diff --git a/requirements.in b/requirements.in index 6d144275c..7cd99be24 100644 --- a/requirements.in +++ b/requirements.in @@ -1,4 +1,4 @@ -https://github.com/codecov/shared/archive/b48aec853deed52c19b0c3a44549787009861691.tar.gz#egg=shared +https://github.com/codecov/shared/archive/a0b5d256b6d580a99dd3a1e900f5c9bdaf2d5c9e.tar.gz#egg=shared https://github.com/codecov/opentelem-python/archive/refs/tags/v0.0.4a1.tar.gz#egg=codecovopentelem https://github.com/codecov/test-results-parser/archive/5515e960d5d38881036e9127f86320efca649f13.tar.gz#egg=test-results-parser boto3 diff --git a/requirements.txt b/requirements.txt index 618336700..06a55a729 100644 --- a/requirements.txt +++ b/requirements.txt @@ -366,7 +366,7 @@ sentry-sdk==1.40.0 # via # -r requirements.in # shared -shared @ https://github.com/codecov/shared/archive/b48aec853deed52c19b0c3a44549787009861691.tar.gz +shared @ https://github.com/codecov/shared/archive/a0b5d256b6d580a99dd3a1e900f5c9bdaf2d5c9e.tar.gz # via -r requirements.in six==1.15.0 # via diff --git a/services/bundle_analysis.py b/services/bundle_analysis.py index cdff178b4..a939c067b 100644 --- a/services/bundle_analysis.py +++ b/services/bundle_analysis.py @@ -16,7 +16,7 @@ from shared.bundle_analysis.storage import get_bucket_name from shared.reports.enums import UploadState from shared.storage import get_appropriate_storage_service -from shared.storage.exceptions import FileNotInStorageError +from shared.storage.exceptions import FileNotInStorageError, PutRequestRateLimitError from shared.torngit.base import TorngitBaseAdapter from shared.torngit.exceptions import TorngitClientError from shared.yaml import UserYaml @@ -161,6 +161,24 @@ def process_upload(self, commit: Commit, upload: Upload) -> ProcessingResult: is_retryable=True, ), ) + except PutRequestRateLimitError as e: + plugin_name = getattr(e, "bundle_analysis_plugin_name", "unknown") + sentry_metrics.incr( + "bundle_analysis_upload", + tags={ + "result": "rate_limit_error", + "plugin_name": plugin_name, + }, + ) + return ProcessingResult( + upload=upload, + commit=commit, + error=ProcessingError( + code="rate_limit_error", + params={"location": upload.storage_path}, + is_retryable=True, + ), + ) except Exception as e: # Metrics to count number of parsing errors of bundle files by plugins plugin_name = getattr(e, "bundle_analysis_plugin_name", "unknown") diff --git a/tasks/tests/unit/test_bundle_analysis_processor_task.py b/tasks/tests/unit/test_bundle_analysis_processor_task.py index f9cb43531..08b82c10b 100644 --- a/tasks/tests/unit/test_bundle_analysis_processor_task.py +++ b/tasks/tests/unit/test_bundle_analysis_processor_task.py @@ -3,6 +3,7 @@ import pytest from redis.exceptions import LockError from shared.bundle_analysis.storage import get_bucket_name +from shared.storage.exceptions import PutRequestRateLimitError from database.models import CommitReport from database.tests.factories import CommitFactory, UploadFactory @@ -299,3 +300,68 @@ def test_bundle_analysis_processor_task_locked( assert upload.state == "started" retry.assert_called_once_with(countdown=ANY, max_retries=5) + + +def test_bundle_analysis_process_upload_rate_limit_error( + mocker, + mock_configuration, + dbsession, + mock_storage, + mock_redis, + celery_app, +): + storage_path = ( + f"v1/repos/testing/ed1bdd67-8fd2-4cdb-ac9e-39b99e4a3892/bundle_report.sqlite" + ) + mock_storage.write_file(get_bucket_name(), storage_path, "test-content") + + mocker.patch.object(BundleAnalysisProcessorTask, "app", celery_app) + + commit = CommitFactory.create(state="pending") + dbsession.add(commit) + dbsession.flush() + + commit_report = CommitReport(commit_id=commit.id_) + dbsession.add(commit_report) + dbsession.flush() + + upload = UploadFactory.create(storage_path=storage_path, report=commit_report) + dbsession.add(upload) + dbsession.flush() + + task = BundleAnalysisProcessorTask() + retry = mocker.patch.object(task, "retry") + + ingest = mocker.patch("shared.bundle_analysis.BundleAnalysisReport.ingest") + ingest.side_effect = PutRequestRateLimitError() + + result = task.run_impl( + dbsession, + {"results": [{"previous": "result"}]}, + repoid=commit.repoid, + commitid=commit.commitid, + commit_yaml={}, + params={ + "upload_pk": upload.id_, + "commit": commit.commitid, + }, + ) + assert result == { + "results": [ + {"previous": "result"}, + { + "error": { + "code": "rate_limit_error", + "params": { + "location": "v1/repos/testing/ed1bdd67-8fd2-4cdb-ac9e-39b99e4a3892/bundle_report.sqlite" + }, + }, + "session_id": None, + "upload_id": upload.id_, + }, + ], + } + + assert commit.state == "error" + assert upload.state == "error" + retry.assert_called_once_with(countdown=20, max_retries=5)