From f65682982819a3462f85063c3ae44a3929865112 Mon Sep 17 00:00:00 2001 From: tdruez Date: Wed, 31 Jul 2024 18:44:13 +0400 Subject: [PATCH] Add unit tests #1145 Signed-off-by: tdruez --- .../tests/data/spdx/dependencies.spdx.json | 112 ++++++++++++++++++ scanpipe/tests/pipes/test_output.py | 41 +++++++ scanpipe/tests/test_models.py | 24 +++- 3 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 scanpipe/tests/data/spdx/dependencies.spdx.json diff --git a/scanpipe/tests/data/spdx/dependencies.spdx.json b/scanpipe/tests/data/spdx/dependencies.spdx.json new file mode 100644 index 000000000..bd20db1a2 --- /dev/null +++ b/scanpipe/tests/data/spdx/dependencies.spdx.json @@ -0,0 +1,112 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT-b74fe5df-e965-415e-ba65-f38421a0695d", + "name": "scancodeio_analysis", + "documentNamespace": "https://scancode.io/spdxdocs/b74fe5df-e965-415e-ba65-f38421a0695d", + "creationInfo": { + "created": "2000-01-01T01:02:03Z", + "creators": [ + "Tool: ScanCode.io" + ], + "licenseListVersion": "3.20" + }, + "packages": [ + { + "name": "a", + "SPDXID": "SPDXRef-scancodeio-discoveredpackage-a83a60de-81bc-4bf4-b48c-dc78e0e658a9", + "downloadLocation": "NOASSERTION", + "licenseConcluded": "NOASSERTION", + "copyrightText": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:type/a" + } + ] + }, + { + "name": "b", + "SPDXID": "SPDXRef-scancodeio-discoveredpackage-81147701-285f-485c-ba36-9cd3742790b1", + "downloadLocation": "NOASSERTION", + "licenseConcluded": "NOASSERTION", + "copyrightText": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:type/b" + } + ] + }, + { + "name": "z", + "SPDXID": "SPDXRef-scancodeio-discoveredpackage-e391c33e-d7d0-4a97-a3c3-e947375c53d5", + "downloadLocation": "NOASSERTION", + "licenseConcluded": "NOASSERTION", + "copyrightText": "NOASSERTION", + "filesAnalyzed": false, + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:type/z" + } + ] + }, + { + "name": "", + "SPDXID": "SPDXRef-scancodeio-discovereddependency-for_package_b", + "downloadLocation": "NOASSERTION", + "licenseConcluded": "NOASSERTION", + "copyrightText": "NOASSERTION", + "filesAnalyzed": false, + "licenseDeclared": "NOASSERTION" + }, + { + "name": "unresolved", + "SPDXID": "SPDXRef-scancodeio-discovereddependency-unresolved", + "downloadLocation": "NOASSERTION", + "licenseConcluded": "NOASSERTION", + "copyrightText": "NOASSERTION", + "filesAnalyzed": false, + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:type/unresolved" + } + ] + } + ], + "documentDescribes": [ + "SPDXRef-scancodeio-discoveredpackage-a83a60de-81bc-4bf4-b48c-dc78e0e658a9", + "SPDXRef-scancodeio-discoveredpackage-81147701-285f-485c-ba36-9cd3742790b1", + "SPDXRef-scancodeio-discoveredpackage-e391c33e-d7d0-4a97-a3c3-e947375c53d5", + "SPDXRef-scancodeio-discovereddependency-for_package_b", + "SPDXRef-scancodeio-discovereddependency-unresolved" + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-scancodeio-discoveredpackage-81147701-285f-485c-ba36-9cd3742790b1", + "relatedSpdxElement": "SPDXRef-scancodeio-discoveredpackage-a83a60de-81bc-4bf4-b48c-dc78e0e658a9", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-scancodeio-discovereddependency-for_package_b", + "relatedSpdxElement": "SPDXRef-scancodeio-discoveredpackage-81147701-285f-485c-ba36-9cd3742790b1", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-scancodeio-discovereddependency-unresolved", + "relatedSpdxElement": "SPDXRef-DOCUMENT-b74fe5df-e965-415e-ba65-f38421a0695d", + "relationshipType": "DEPENDENCY_OF" + } + ], + "comment": "Generated with ScanCode.io and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied.\nNo content created from ScanCode.io should be considered or used as legal advice.\nConsult an Attorney for any legal advice.\nScanCode.io is a free software code scanning tool from nexB Inc. and others\nlicensed under the Apache License version 2.0.\nScanCode is a trademark of nexB Inc.\nVisit https://github.com/nexB/scancode.io for support and download.\n", + "files": [] +} \ No newline at end of file diff --git a/scanpipe/tests/pipes/test_output.py b/scanpipe/tests/pipes/test_output.py index 388a5585e..5a8fb8570 100644 --- a/scanpipe/tests/pipes/test_output.py +++ b/scanpipe/tests/pipes/test_output.py @@ -370,6 +370,47 @@ def test_scanpipe_pipes_outputs_to_spdx_extracted_licenses(self): self.assertEqual(expected, license_infos["seeAlsos"]) self.assertTrue(license_infos["extractedText"].startswith("License:")) + @mock.patch("uuid.uuid4") + def test_scanpipe_pipes_outputs_to_spdx_dependencies(self, mock_uuid4): + forced_uuid = "b74fe5df-e965-415e-ba65-f38421a0695d" + mock_uuid4.return_value = forced_uuid + project = Project.objects.create(name="Analysis", uuid=forced_uuid) + + a = make_package( + project, "pkg:type/a", uuid="a83a60de-81bc-4bf4-b48c-dc78e0e658a9" + ) + b = make_package( + project, "pkg:type/b", uuid="81147701-285f-485c-ba36-9cd3742790b1" + ) + # 1. Package resolved dependency + make_dependency(project, for_package=a, resolved_to_package=b) + # 2. Package unresolved dependency + make_dependency(project, for_package=b, dependency_uid="for_package_b") + # 3. Project unresolved dependency + unresolved_dependency = make_dependency(project, dependency_uid="unresolved") + unresolved_dependency.set_package_url("pkg:type/unresolved") + unresolved_dependency.save() + # 4. Project package + make_package(project, "pkg:type/z", uuid="e391c33e-d7d0-4a97-a3c3-e947375c53d5") + + self.assertEqual(3, project.discoveredpackages.count()) + self.assertEqual(3, project.discovereddependencies.count()) + + output_file = output.to_spdx(project=project) + results_json = json.loads(output_file.read_text()) + self.assertEqual(5, len(results_json["packages"])) + self.assertEqual(3, len(results_json["relationships"])) + + # Patch the `created` date and tool version + results_json["creationInfo"]["created"] = "2000-01-01T01:02:03Z" + results_json["creationInfo"]["creators"] = ["Tool: ScanCode.io"] + # Files ordering is system dependent, excluded for now + results_json["files"] = [] + results = json.dumps(results_json, indent=2) + + expected_file = self.data / "spdx" / "dependencies.spdx.json" + self.assertResultsEqual(expected_file, results) + def test_scanpipe_pipes_outputs_make_unknown_license_object(self): licensing = get_licensing() parsed_expression = licensing.parse("some-unknown-license") diff --git a/scanpipe/tests/test_models.py b/scanpipe/tests/test_models.py index 168ba04a8..9c32db542 100644 --- a/scanpipe/tests/test_models.py +++ b/scanpipe/tests/test_models.py @@ -1849,8 +1849,20 @@ def test_scanpipe_discovered_package_queryset_dependency_methods(self): z = make_package(project, "pkg:type/z") # Project -> A -> B -> C # Project -> Z - make_dependency(project, for_package=a, resolved_to_package=b) - make_dependency(project, for_package=b, resolved_to_package=c) + a_to_b = make_dependency( + project, for_package=a, resolved_to_package=b, dependency_uid="a_to_b" + ) + b_to_c = make_dependency( + project, for_package=b, resolved_to_package=c, dependency_uid="b_to_c" + ) + unresolved_dependency = make_dependency(project, dependency_uid="unresolved") + + self.assertFalse(a_to_b.is_project_dependency) + self.assertTrue(a_to_b.is_for_package) + self.assertTrue(a_to_b.is_resolved_to_package) + self.assertTrue(unresolved_dependency.is_project_dependency) + self.assertFalse(unresolved_dependency.is_for_package) + self.assertFalse(unresolved_dependency.is_resolved_to_package) project_packages_qs = project.discoveredpackages.order_by("name") root_packages = project_packages_qs.root_packages() @@ -1858,6 +1870,14 @@ def test_scanpipe_discovered_package_queryset_dependency_methods(self): non_root_packages = project_packages_qs.non_root_packages() self.assertEqual([b, c], list(non_root_packages)) + dependency_qs = project.discovereddependencies + self.assertEqual( + [unresolved_dependency], list(dependency_qs.project_dependencies()) + ) + self.assertEqual([a_to_b, b_to_c], list(dependency_qs.package_dependencies())) + self.assertEqual([a_to_b, b_to_c], list(dependency_qs.resolved())) + self.assertEqual([unresolved_dependency], list(dependency_qs.unresolved())) + @skipIf(sys.platform != "linux", "Ordering differs on macOS.") def test_scanpipe_codebase_resource_model_walk_method(self): fixtures = self.data / "asgiref" / "asgiref-3.3.0_walk_test_fixtures.json"