diff --git a/codecov_cli/services/staticanalysis/__init__.py b/codecov_cli/services/staticanalysis/__init__.py index 95175ae8..7a9914a5 100644 --- a/codecov_cli/services/staticanalysis/__init__.py +++ b/codecov_cli/services/staticanalysis/__init__.py @@ -109,7 +109,14 @@ async def run_analysis_entrypoint( for el in files_that_need_upload: all_tasks.append(send_single_upload_put(client, all_data, el)) bar.update(1, all_data[el["filepath"]]) - resps = await asyncio.gather(*all_tasks) + try: + resps = await asyncio.gather(*all_tasks) + except asyncio.CancelledError: + message = ( + "Unknown error cancelled the upload tasks.\n" + + f"Uploaded {len(uploaded_files)}/{len(files_that_need_upload)} files successfully." + ) + raise click.ClickException(message) for resp in resps: if resp["succeeded"]: uploaded_files.append(resp["filepath"]) diff --git a/tests/services/static_analysis/test_static_analysis_service.py b/tests/services/static_analysis/test_static_analysis_service.py index fae25226..08876634 100644 --- a/tests/services/static_analysis/test_static_analysis_service.py +++ b/tests/services/static_analysis/test_static_analysis_service.py @@ -1,3 +1,4 @@ +from asyncio import CancelledError from pathlib import Path from unittest.mock import MagicMock @@ -148,6 +149,76 @@ async def side_effect(*args, **kwargs): "raw_upload_location": "http://storage-url", } + @pytest.mark.asyncio + async def test_static_analysis_service_CancelledError(self, mocker): + mock_file_finder = mocker.patch( + "codecov_cli.services.staticanalysis.select_file_finder" + ) + mock_send_upload_put = mocker.patch( + "codecov_cli.services.staticanalysis.send_single_upload_put" + ) + + async def side_effect(client, all_data, el): + if el["filepath"] == "samples/inputs/sample_001.py": + return { + "status_code": 204, + "filepath": el["filepath"], + "succeeded": True, + } + raise CancelledError("Pretending something cancelled this task") + + mock_send_upload_put.side_effect = side_effect + + files_found = map( + lambda filename: FileAnalysisRequest(str(filename), Path(filename)), + [ + "samples/inputs/sample_001.py", + "samples/inputs/sample_002.py", + ], + ) + mock_file_finder.return_value.find_files = MagicMock(return_value=files_found) + with responses.RequestsMock() as rsps: + rsps.add( + responses.POST, + "https://api.codecov.io/staticanalysis/analyses", + json={ + "external_id": "externalid", + "filepaths": [ + { + "state": "created", + "filepath": "samples/inputs/sample_001.py", + "raw_upload_location": "http://storage-url-001", + }, + { + "state": "created", + "filepath": "samples/inputs/sample_002.py", + "raw_upload_location": "http://storage-url-002", + }, + ], + }, + status=200, + match=[ + matchers.header_matcher({"Authorization": "Repotoken STATIC_TOKEN"}) + ], + ) + + with pytest.raises(click.ClickException) as exp: + await run_analysis_entrypoint( + config={}, + folder=".", + numberprocesses=1, + pattern="*.py", + token="STATIC_TOKEN", + commit="COMMIT", + should_force=False, + folders_to_exclude=[], + enterprise_url=None, + ) + assert "Unknown error cancelled the upload tasks." in str(exp.value) + mock_file_finder.assert_called_with({}) + mock_file_finder.return_value.find_files.assert_called() + assert mock_send_upload_put.call_count == 2 + @pytest.mark.asyncio async def test_send_single_upload_put_success(self, mocker): mock_client = MagicMock()