def test_analyze_vulnerability_release_not_found(db_request, metrics): project = ProjectFactory.create() ReleaseFactory.create(project=project, version="1.0") metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) with pytest.raises(HTTPBadRequest): utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": ["1", "2"], "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, ( "warehouse.vulnerabilities.error.release_not_found", ("origin:test_report_source",), ): 2, }
def test_analyze_vulnerability_no_versions(db_request, metrics): project = ProjectFactory.create() metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": [], "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1, }
def test_analyze_vulnerability_project_not_found(db_request, metrics): metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) with pytest.raises(NoResultFound): utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": faker.Faker().text(max_nb_chars=8), "versions": ["1", "2"], "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, ( "warehouse.vulnerabilities.error.project_not_found", ("origin:test_report_source",), ): 1, }
def test_analyze_vulnerability_invalid_request(db_request, metrics): project = ProjectFactory.create() metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) with pytest.raises(vulnerabilities.InvalidVulnerabilityReportError) as exc: utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": ["1", "2"], # "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert str(exc.value) == "Record is missing attribute(s): id" assert exc.value.reason == "format" assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.error.format", ("origin:test_report_source",)): 1, }
def analyze_vulnerability_task(request, vulnerability_report, origin): metrics = request.find_service(IMetricsService, context=None) utils.analyze_vulnerability( request=request, vulnerability_report=vulnerability_report, origin=origin, metrics=metrics, )
def test_analyze_vulnerability_add_release(db_request, metrics): project = ProjectFactory.create() release1 = ReleaseFactory.create(project=project, version="1.0") release2 = ReleaseFactory.create(project=project, version="2.0") metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": ["1.0"], "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert len(release1.vulnerabilities) == 1 assert len(release2.vulnerabilities) == 0 assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, } metrics_counter.clear() utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": ["1.0", "2.0"], # Add 2.0 "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert len(release1.vulnerabilities) == 1 assert len(release2.vulnerabilities) == 1 assert release1.vulnerabilities[0] == release2.vulnerabilities[0] assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, }
def test_analyze_vulnerability_unknown_error(db_request, monkeypatch, metrics): metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) class UnknownError(Exception): pass def raise_unknown_err(): raise UnknownError() vuln_report_from_api_request = pretend.call_recorder( lambda **k: raise_unknown_err()) vuln_report_cls = pretend.stub( from_api_request=vuln_report_from_api_request) monkeypatch.setattr(vulnerabilities, "VulnerabilityReportRequest", vuln_report_cls) with pytest.raises(UnknownError): utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": "whatever", "versions": [], "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source", )): 1, ("warehouse.vulnerabilities.error.unknown", ("origin:test_report_source", )): 1, }
def test_analyze_vulnerability_delete_releases(db_request, metrics): project = ProjectFactory.create() release1 = ReleaseFactory.create(project=project, version="1.0") release2 = ReleaseFactory.create(project=project, version="2.0") metrics_counter = collections.Counter() def metrics_increment(key, tags): metrics_counter.update([(key, tuple(tags))]) metrics = pretend.stub(increment=metrics_increment, timed=metrics.timed) utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": ["1.0", "2.0"], "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert len(release1.vulnerabilities) == 1 assert len(release2.vulnerabilities) == 1 assert release1.vulnerabilities[0] == release2.vulnerabilities[0] assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, } metrics_counter.clear() utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": ["1.0"], # Remove v2 as vulnerable "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) assert len(release1.vulnerabilities) == 1 assert len(release2.vulnerabilities) == 0 assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, } metrics_counter.clear() utils.analyze_vulnerability( request=db_request, vulnerability_report={ "project": project.name, "versions": [], # Remove all releases "id": "vuln_id", "link": "vulns.com/vuln_id", "aliases": ["vuln_alias"], }, origin="test_report_source", metrics=metrics, ) # Weird behavior, see: # https://docs.sqlalchemy.org/en/14/orm/cascades.html#notes-on-delete-deleting-objects-referenced-from-collections-and-scalar-relationships # assert len(release1.vulnerabilities) == 0 assert len(release2.vulnerabilities) == 0 assert metrics_counter == { ("warehouse.vulnerabilities.received", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.processed", ("origin:test_report_source",)): 1, ("warehouse.vulnerabilities.valid", ("origin:test_report_source",)): 1, }