Skip to content

Commit

Permalink
feat: send file_not_found
Browse files Browse the repository at this point in the history
if the report_type is "test_results" and we don't find any files to
upload we want to send a request to the regular test results endpoint
with "file_not_found" set to True and not expect a raw_upload_location
in the response
  • Loading branch information
joseph-sentry committed Jan 10, 2025
1 parent ba3cede commit 052ac3c
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 9 deletions.
18 changes: 12 additions & 6 deletions codecov_cli/services/upload/upload_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,22 +162,28 @@ def generate_upload_data(
if not report_files:
if report_type == ReportType.TEST_RESULTS:
error_message = "No JUnit XML reports found. Please review our documentation (https://docs.codecov.com/docs/test-result-ingestion-beta) to generate and upload the file."
logger.error(error_message)
return UploadCollectionResult(
network=network,
files=[],
file_fixes=[],
)
else:
error_message = "No coverage reports found. Please make sure you're generating reports successfully."
raise click.ClickException(
click.style(
error_message,
fg="red",
raise click.ClickException(
click.style(
error_message,
fg="red",
)
)
)
for file in report_files:
logger.info(f"> {file}")
return UploadCollectionResult(
network=network,
files=report_files,
file_fixes=(
self._produce_file_fixes(self.network_finder.find_files(True))
if report_type == "coverage"
if report_type == ReportType.COVERAGE
else []
),
)
15 changes: 15 additions & 0 deletions codecov_cli/services/upload/upload_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ def send_upload_data(
upload_coverage: bool = False,
args: dict = None,
) -> RequestResult:
file_not_found = False
if report_type == ReportType.TEST_RESULTS and not upload_data.files:
file_not_found = True

data = {
"ci_service": ci_service,
"ci_url": build_url,
Expand All @@ -56,7 +60,9 @@ def send_upload_data(
"job_code": job_code,
"name": name,
"version": codecov_cli_version,
"file_not_found": file_not_found,
}

if upload_coverage:
data["branch"] = branch
data["code"] = report_code
Expand Down Expand Up @@ -86,6 +92,13 @@ def send_upload_data(
data=data,
headers=headers,
)

if file_not_found:
logger.info(
"No test results reports found. Triggering notifications without uploading."
)
return resp_from_codecov

if resp_from_codecov.status_code >= 400:
return resp_from_codecov
resp_json_obj = json.loads(resp_from_codecov.text)
Expand Down Expand Up @@ -185,6 +198,7 @@ def get_url_and_possibly_update_data(
commit_sha,
report_code,
upload_coverage=False,
file_not_found=False,
):
if report_type == ReportType.COVERAGE:
base_url = f"{upload_url}/upload/{git_service}/{encoded_slug}"
Expand All @@ -197,6 +211,7 @@ def get_url_and_possibly_update_data(
data["branch"] = branch
data["commit"] = commit_sha
data["service"] = git_service
data["file_not_found"] = file_not_found
url = f"{upload_url}/upload/test_results/v1"

return url, data
70 changes: 67 additions & 3 deletions tests/helpers/test_upload_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
import re
from pathlib import Path

from copy import deepcopy
import pytest
import responses
from responses import matchers

from codecov_cli import __version__ as codecov_cli_version
from codecov_cli.helpers.encoder import encode_slug
from codecov_cli.services.upload.upload_sender import UploadSender
from codecov_cli.types import UploadCollectionResult, UploadCollectionResultFileFixer
from codecov_cli.types import (
UploadCollectionResult,
UploadCollectionResultFileFixer,
UploadCollectionResultFile,
)
from tests.data import reports_examples
from codecov_cli.helpers.upload_type import ReportType

Expand Down Expand Up @@ -56,6 +61,7 @@
"job_code": "job_code",
"name": "name",
"version": codecov_cli_version,
"file_not_found": False,
}


Expand Down Expand Up @@ -111,6 +117,18 @@ def mocked_test_results_endpoint(mocked_responses):
yield resp


@pytest.fixture
def mocked_test_results_endpoint_file_not_found(mocked_responses):
resp = responses.Response(
responses.POST,
"https://ingest.codecov.io/upload/test_results/v1",
status=200,
json={},
)
mocked_responses.add(resp)
yield resp


@pytest.fixture
def mocked_storage_server(mocked_responses):
resp = responses.Response(responses.PUT, "https://puturl.com", status=200)
Expand Down Expand Up @@ -240,7 +258,11 @@ def test_upload_sender_post_called_with_right_parameters_and_upload_coverage(
) # test dict is a subset of the other

def test_upload_sender_post_called_with_right_parameters_test_results(
self, mocked_responses, mocked_test_results_endpoint, mocked_storage_server
self,
mocked_responses,
mocked_test_results_endpoint,
mocked_storage_server,
tmp_path,
):
headers = {"Authorization": f"token {random_token}"}

Expand All @@ -249,8 +271,15 @@ def test_upload_sender_post_called_with_right_parameters_test_results(
matchers.header_matcher(headers),
]

ta_upload_collection = deepcopy(upload_collection)

test_path = tmp_path / "test_results.xml"
test_path.write_bytes(b"test_data")

ta_upload_collection.files = [UploadCollectionResultFile(test_path)]

sending_result = UploadSender().send_upload_data(
upload_collection,
ta_upload_collection,
random_sha,
random_token,
**test_results_named_upload_data,
Expand All @@ -272,6 +301,41 @@ def test_upload_sender_post_called_with_right_parameters_test_results(
assert put_req_made.url == "https://puturl.com/"
assert "test_results_files" in put_req_made.body.decode("utf-8")

def test_upload_sender_post_called_with_right_parameters_test_results_file_not_found(
self,
mocked_responses,
mocked_test_results_endpoint_file_not_found,
tmp_path,
):
headers = {"Authorization": f"token {random_token}"}

req_data = deepcopy(request_data)
req_data["file_not_found"] = True

mocked_legacy_upload_endpoint.match = [
matchers.json_params_matcher(req_data),
matchers.header_matcher(headers),
]

sending_result = UploadSender().send_upload_data(
upload_collection,
random_sha,
random_token,
**test_results_named_upload_data,
)
assert sending_result.error is None
assert sending_result.warnings == []

assert len(mocked_responses.calls) == 1

post_req_made = mocked_responses.calls[0].request
response = json.loads(mocked_responses.calls[0].response.text)
assert response.get("raw_upload_location") is None
assert post_req_made.url == "https://ingest.codecov.io/upload/test_results/v1"
assert (
post_req_made.headers.items() >= headers.items()
) # test dict is a subset of the other

def test_upload_sender_post_called_with_right_parameters_tokenless(
self,
mocked_responses,
Expand Down

0 comments on commit 052ac3c

Please sign in to comment.