diff --git a/services/report/languages/cobertura.py b/services/report/languages/cobertura.py index 501fa9107..0b3df1c78 100644 --- a/services/report/languages/cobertura.py +++ b/services/report/languages/cobertura.py @@ -64,6 +64,8 @@ def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> None for _class in xml.iter("class"): filename = _class.attrib["filename"] + if not filename: + continue _file = report_builder_session.create_coverage_file(filename, do_fix_path=False) assert ( _file is not None @@ -194,14 +196,17 @@ def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> None # path rename path_fixer = report_builder_session.path_fixer - path_name_fixing = [] source_path_list = get_sources_to_attempt(xml) + path_name_fixing = [] + for _class in xml.iter("class"): filename = _class.attrib["filename"] fixed_name = path_fixer(filename, bases_to_try=source_path_list) path_name_fixing.append((filename, fixed_name)) - _set = set(("dist-packages", "site-packages")) - report_builder_session.resolve_paths( - sorted(path_name_fixing, key=lambda a: _set & set(a[0].split("/"))) + # paths with `X-packages` should be sorted to the end + path_name_fixing.sort( + key=lambda a: "/dist-packages/" in a[0] or "/site-packages/" in a[0] ) + + report_builder_session.resolve_paths(path_name_fixing) diff --git a/services/report/languages/gap.py b/services/report/languages/gap.py index 1438b0b50..4844bfb0f 100644 --- a/services/report/languages/gap.py +++ b/services/report/languages/gap.py @@ -53,5 +53,5 @@ def from_string(string: bytes, report_builder_session: ReportBuilderSession) -> ) # append last file - if _file: + if _file is not None: report_builder_session.append(_file) diff --git a/services/report/languages/jetbrainsxml.py b/services/report/languages/jetbrainsxml.py index 62a869ae0..b6a11e2b8 100644 --- a/services/report/languages/jetbrainsxml.py +++ b/services/report/languages/jetbrainsxml.py @@ -21,10 +21,9 @@ def process( def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> None: file_by_id: dict[str, ReportFile] = {} for f in xml.iter("File"): - _file = report_builder_session.create_coverage_file( - f.attrib["Name"].replace("\\", "/") - ) - if _file: + filename = f.attrib["Name"].replace("\\", "/") + _file = report_builder_session.create_coverage_file(filename) + if _file is not None: file_by_id[str(f.attrib["Index"])] = _file for statement in xml.iter("Statement"): diff --git a/services/report/languages/lcov.py b/services/report/languages/lcov.py index 99ea108e6..319e7e7cb 100644 --- a/services/report/languages/lcov.py +++ b/services/report/languages/lcov.py @@ -27,7 +27,7 @@ def from_txt(reports: bytes, report_builder_session: ReportBuilderSession) -> No # http://ltp.sourceforge.net/coverage/lcov/geninfo.1.php # merge same files for string in reports.split(b"\nend_of_record"): - if _file := _process_file(string, report_builder_session): + if (_file := _process_file(string, report_builder_session)) is not None: report_builder_session.append(_file) diff --git a/services/report/languages/mono.py b/services/report/languages/mono.py index 63c56a668..ee3913435 100644 --- a/services/report/languages/mono.py +++ b/services/report/languages/mono.py @@ -45,5 +45,5 @@ def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> None ) for _file in files.values(): - if _file: + if _file is not None: report_builder_session.append(_file) diff --git a/services/report/languages/tests/unit/test_cobertura.py b/services/report/languages/tests/unit/test_cobertura.py index 99e9eb54d..ab2d70406 100644 --- a/services/report/languages/tests/unit/test_cobertura.py +++ b/services/report/languages/tests/unit/test_cobertura.py @@ -531,3 +531,24 @@ def test_use_source_for_filename_if_multiple_sources_first_and_second_works(self # doesnt use the source as we dont know which one assert "/here/source" in processed_report["report"]["files"] assert "/here/file" in processed_report["report"]["files"] + + +def test_empty_filename(): + xml = """ + + + + + + + + +""" + report_builder_session = create_report_builder_session() + cobertura.from_xml( + etree.fromstring(xml), + report_builder_session, + ) + report = report_builder_session.output_report() + + assert not report.is_empty() diff --git a/services/report/languages/tests/unit/test_jetbrainsxml.py b/services/report/languages/tests/unit/test_jetbrainsxml.py new file mode 100644 index 000000000..f55d67164 --- /dev/null +++ b/services/report/languages/tests/unit/test_jetbrainsxml.py @@ -0,0 +1,22 @@ +import xml.etree.cElementTree as etree + +from services.report.languages import jetbrainsxml + +from . import create_report_builder_session + + +def test_simple_jetbrainsxml(): + xml = """ + + + + +""" + report_builder_session = create_report_builder_session() + jetbrainsxml.from_xml( + etree.fromstring(xml), + report_builder_session, + ) + report = report_builder_session.output_report() + + assert not report.is_empty() diff --git a/services/report/tests/unit/test_process.py b/services/report/tests/unit/test_process.py index 184171f23..6c803a64f 100644 --- a/services/report/tests/unit/test_process.py +++ b/services/report/tests/unit/test_process.py @@ -25,6 +25,29 @@ folder = here.parent +@pytest.mark.skip(reason="this is supposed to be invoked manually") +def test_manual(): + # The intention of this test is to easily reproduce production problems with real reports. + # So download the relevant report, fill in its filename below, comment out the `skip` annotation, + # and run this test directly. + filename = "..." + with open(filename, "rb") as d: + contents = d.read() + + parsed_report = LegacyReportParser().parse_raw_report_from_bytes(contents) + master = Report() + result = process.process_raw_upload( + commit_yaml=None, + report=master, + raw_reports=parsed_report, + flags=[], + session=Session(), + ) + master = result.report + + assert not master.is_empty() + + class TestProcessRawUpload(BaseTestCase): def readjson(self, filename): with open(folder / filename, "r") as d: