diff --git a/syft/formats/common/spdxhelpers/to_format_model.go b/syft/formats/common/spdxhelpers/to_format_model.go index b62c1be0d..be2c1018d 100644 --- a/syft/formats/common/spdxhelpers/to_format_model.go +++ b/syft/formats/common/spdxhelpers/to_format_model.go @@ -105,7 +105,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document { }, Packages: toPackages(s.Artifacts.PackageCatalog), Files: toFiles(s), - Relationships: toRelationships(s.Relationships), + Relationships: toRelationships(s.RelationshipsSorted()), } } diff --git a/syft/formats/common/testutils/utils.go b/syft/formats/common/testutils/utils.go index 5276c46e5..f672a139e 100644 --- a/syft/formats/common/testutils/utils.go +++ b/syft/formats/common/testutils/utils.go @@ -2,8 +2,10 @@ package testutils import ( "bytes" + "math/rand" "strings" "testing" + "time" "github.com/sergi/go-diff/diffmatchpatch" "github.com/stretchr/testify/assert" @@ -12,6 +14,7 @@ import ( "github.com/anchore/stereoscope/pkg/filetree" "github.com/anchore/stereoscope/pkg/image" "github.com/anchore/stereoscope/pkg/imagetest" + "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/linux" "github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/sbom" @@ -276,3 +279,25 @@ func newDirectoryCatalog() *pkg.Catalog { return catalog } + +//nolint:gosec +func AddSampleFileRelationships(s *sbom.SBOM) { + catalog := s.Artifacts.PackageCatalog.Sorted() + s.Artifacts.FileMetadata = map[source.Coordinates]source.FileMetadata{} + + files := []string{"/f1", "/f2", "/d1/f3", "/d2/f4", "/z1/f5", "/a1/f6"} + rnd := rand.New(rand.NewSource(time.Now().UnixNano())) + rnd.Shuffle(len(files), func(i, j int) { files[i], files[j] = files[j], files[i] }) + + for _, f := range files { + meta := source.FileMetadata{} + coords := source.Coordinates{RealPath: f} + s.Artifacts.FileMetadata[coords] = meta + + s.Relationships = append(s.Relationships, artifact.Relationship{ + From: catalog[0], + To: coords, + Type: artifact.ContainsRelationship, + }) + } +} diff --git a/syft/formats/spdxjson/encoder_test.go b/syft/formats/spdxjson/encoder_test.go index 545013613..39fa6e3f9 100644 --- a/syft/formats/spdxjson/encoder_test.go +++ b/syft/formats/spdxjson/encoder_test.go @@ -5,10 +5,7 @@ import ( "regexp" "testing" - "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/formats/common/testutils" - "github.com/anchore/syft/syft/sbom" - "github.com/anchore/syft/syft/source" ) var updateSpdxJson = flag.Bool("update-spdx-json", false, "update the *.golden files for spdx-json encoders") @@ -36,7 +33,7 @@ func TestSPDXJSONImageEncoder(t *testing.T) { func TestSPDXRelationshipOrder(t *testing.T) { testImage := "image-simple" s := testutils.ImageInput(t, testImage, testutils.FromSnapshot()) - addRelationships(&s) + testutils.AddSampleFileRelationships(&s) testutils.AssertEncoderAgainstGoldenImageSnapshot(t, Format(), s, @@ -46,23 +43,6 @@ func TestSPDXRelationshipOrder(t *testing.T) { ) } -func addRelationships(s *sbom.SBOM) { - catalog := s.Artifacts.PackageCatalog.Sorted() - s.Artifacts.FileMetadata = map[source.Coordinates]source.FileMetadata{} - - for _, f := range []string{"/f1", "/f2", "/d1/f3", "/d2/f4", "/z1/f5", "/a1/f6"} { - meta := source.FileMetadata{} - coords := source.Coordinates{RealPath: f} - s.Artifacts.FileMetadata[coords] = meta - - s.Relationships = append(s.Relationships, artifact.Relationship{ - From: catalog[0], - To: coords, - Type: artifact.ContainsRelationship, - }) - } -} - func spdxJsonRedactor(s []byte) []byte { // each SBOM reports the time it was generated, which is not useful during snapshot testing s = regexp.MustCompile(`"created": .*`).ReplaceAll(s, []byte("redacted")) diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden index c444dee2a..bbe863815 100644 --- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden +++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden @@ -3,14 +3,14 @@ "dataLicense": "CC0-1.0", "SPDXID": "SPDXRef-DOCUMENT", "name": "/some/path", - "documentNamespace": "https://anchore.com/syft/dir/some/path-0f9b165e-1819-43cb-bd58-f61c1c23d6cf", + "documentNamespace": "https://anchore.com/syft/dir/some/path-4bf54cdd-0a0f-4560-bf4f-39cac2ef7a5b", "creationInfo": { "licenseListVersion": "3.18", "creators": [ "Organization: Anchore, Inc", "Tool: syft-v0.42.0-bogus" ], - "created": "2022-11-11T19:24:55Z", + "created": "2022-11-19T13:46:57Z", "comment": "" }, "packages": [ diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden index 9d052f8ec..5462bcdf1 100644 --- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden +++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden @@ -3,14 +3,14 @@ "dataLicense": "CC0-1.0", "SPDXID": "SPDXRef-DOCUMENT", "name": "user-image-input", - "documentNamespace": "https://anchore.com/syft/image/user-image-input-5841d063-c3ef-406b-91b4-8a702ef45ce9", + "documentNamespace": "https://anchore.com/syft/image/user-image-input-102ca7dc-3d1e-46d2-b130-28968831ebcc", "creationInfo": { "licenseListVersion": "3.18", "creators": [ "Organization: Anchore, Inc", "Tool: syft-v0.42.0-bogus" ], - "created": "2022-11-11T19:24:55Z", + "created": "2022-11-19T13:46:57Z", "comment": "" }, "packages": [ diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden index 93c474cad..c66e4989e 100644 --- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden +++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden @@ -3,14 +3,14 @@ "dataLicense": "CC0-1.0", "SPDXID": "SPDXRef-DOCUMENT", "name": "user-image-input", - "documentNamespace": "https://anchore.com/syft/image/user-image-input-8755f340-f205-4bf2-a909-94c623670734", + "documentNamespace": "https://anchore.com/syft/image/user-image-input-55ad4afc-ecdc-46a4-8bc3-36b3e72da5d1", "creationInfo": { "licenseListVersion": "3.18", "creators": [ "Organization: Anchore, Inc", "Tool: syft-v0.42.0-bogus" ], - "created": "2022-11-11T19:24:55Z", + "created": "2022-11-19T13:46:57Z", "comment": "" }, "packages": [ @@ -133,12 +133,12 @@ }, { "spdxElementId": "SPDXRef-Package-python-package-1-66ba429119b8bec6", - "relatedSpdxElement": "SPDXRef-f9e49132a4b96ccd", + "relatedSpdxElement": "SPDXRef-839d99ee67d9d174", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Package-python-package-1-66ba429119b8bec6", - "relatedSpdxElement": "SPDXRef-c6f5b29dca12661f", + "relatedSpdxElement": "SPDXRef-9c2f7510199b17f6", "relationshipType": "CONTAINS" }, { @@ -148,12 +148,12 @@ }, { "spdxElementId": "SPDXRef-Package-python-package-1-66ba429119b8bec6", - "relatedSpdxElement": "SPDXRef-839d99ee67d9d174", + "relatedSpdxElement": "SPDXRef-c6f5b29dca12661f", "relationshipType": "CONTAINS" }, { "spdxElementId": "SPDXRef-Package-python-package-1-66ba429119b8bec6", - "relatedSpdxElement": "SPDXRef-9c2f7510199b17f6", + "relatedSpdxElement": "SPDXRef-f9e49132a4b96ccd", "relationshipType": "CONTAINS" } ] diff --git a/syft/formats/spdxtagvalue/encoder_test.go b/syft/formats/spdxtagvalue/encoder_test.go index 55f001207..b5ca75f12 100644 --- a/syft/formats/spdxtagvalue/encoder_test.go +++ b/syft/formats/spdxtagvalue/encoder_test.go @@ -67,6 +67,19 @@ func TestSPDXJSONSPDXIDs(t *testing.T) { ) } +func TestSPDXRelationshipOrder(t *testing.T) { + testImage := "image-simple" + s := testutils.ImageInput(t, testImage, testutils.FromSnapshot()) + testutils.AddSampleFileRelationships(&s) + testutils.AssertEncoderAgainstGoldenImageSnapshot(t, + Format(), + s, + testImage, + *updateSpdxTagValue, + spdxTagValueRedactor, + ) +} + func spdxTagValueRedactor(s []byte) []byte { // each SBOM reports the time it was generated, which is not useful during snapshot testing s = regexp.MustCompile(`Created: .*`).ReplaceAll(s, []byte("redacted")) diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXJSONSPDXIDs.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXJSONSPDXIDs.golden index 8acb135b9..988de2374 100644 --- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXJSONSPDXIDs.golden +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXJSONSPDXIDs.golden @@ -2,11 +2,11 @@ SPDXVersion: SPDX-2.3 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: foobar/baz -DocumentNamespace: https://anchore.com/syft/dir/foobar/baz-3d730196-4510-4ee4-9743-9322dd27cee7 +DocumentNamespace: https://anchore.com/syft/dir/foobar/baz-62bc0aae-2b37-4c86-ab79-63c6fc4198ed LicenseListVersion: 3.18 Creator: Organization: Anchore, Inc Creator: Tool: syft-v0.42.0-bogus -Created: 2022-11-18T14:21:45Z +Created: 2022-11-19T13:48:30Z ##### Package: @at-sign diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden new file mode 100644 index 000000000..d87fee378 --- /dev/null +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden @@ -0,0 +1,79 @@ +SPDXVersion: SPDX-2.3 +DataLicense: CC0-1.0 +SPDXID: SPDXRef-DOCUMENT +DocumentName: user-image-input +DocumentNamespace: https://anchore.com/syft/image/user-image-input-cc20e416-9c74-401c-b4aa-245556bada5e +LicenseListVersion: 3.18 +Creator: Organization: Anchore, Inc +Creator: Tool: syft-v0.42.0-bogus +Created: 2022-11-19T13:48:30Z + +##### Unpackaged files + +FileName: /f1 +SPDXID: SPDXRef-5265a4dde3edbf7c +FileType: OTHER +LicenseConcluded: NOASSERTION + +FileName: /z1/f5 +SPDXID: SPDXRef-839d99ee67d9d174 +FileType: OTHER +LicenseConcluded: NOASSERTION + +FileName: /a1/f6 +SPDXID: SPDXRef-9c2f7510199b17f6 +FileType: OTHER +LicenseConcluded: NOASSERTION + +FileName: /d2/f4 +SPDXID: SPDXRef-c641caa71518099f +FileType: OTHER +LicenseConcluded: NOASSERTION + +FileName: /d1/f3 +SPDXID: SPDXRef-c6f5b29dca12661f +FileType: OTHER +LicenseConcluded: NOASSERTION + +FileName: /f2 +SPDXID: SPDXRef-f9e49132a4b96ccd +FileType: OTHER +LicenseConcluded: NOASSERTION + +##### Package: package-2 + +PackageName: package-2 +SPDXID: SPDXRef-Package-deb-package-2-958443e2d9304af4 +PackageVersion: 2.0.1 +PackageDownloadLocation: NOASSERTION +FilesAnalyzed: false +PackageSourceInfo: acquired package info from DPKG DB: /somefile-2.txt +PackageLicenseConcluded: NONE +PackageLicenseDeclared: NONE +PackageCopyrightText: NOASSERTION +ExternalRef: SECURITY cpe23Type cpe:2.3:*:some:package:2:*:*:*:*:*:*:* +ExternalRef: PACKAGE-MANAGER purl pkg:deb/debian/package-2@2.0.1 + +##### Package: package-1 + +PackageName: package-1 +SPDXID: SPDXRef-Package-python-package-1-66ba429119b8bec6 +PackageVersion: 1.0.1 +PackageDownloadLocation: NOASSERTION +FilesAnalyzed: false +PackageSourceInfo: acquired package info from installed python package manifest file: /somefile-1.txt +PackageLicenseConcluded: MIT +PackageLicenseDeclared: MIT +PackageCopyrightText: NOASSERTION +ExternalRef: SECURITY cpe23Type cpe:2.3:*:some:package:1:*:*:*:*:*:*:* +ExternalRef: PACKAGE-MANAGER purl a-purl-1 + +##### Relationships + +Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-5265a4dde3edbf7c +Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-839d99ee67d9d174 +Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-9c2f7510199b17f6 +Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-c641caa71518099f +Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-c6f5b29dca12661f +Relationship: SPDXRef-Package-python-package-1-66ba429119b8bec6 CONTAINS SPDXRef-f9e49132a4b96ccd + diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden index a450e0191..119e225ef 100644 --- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden @@ -2,11 +2,11 @@ SPDXVersion: SPDX-2.3 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: /some/path -DocumentNamespace: https://anchore.com/syft/dir/some/path-b6078c95-5b97-462d-acb3-9e74bc9ddb43 +DocumentNamespace: https://anchore.com/syft/dir/some/path-7a4b2140-6669-4a28-80dd-5c8e795c5da0 LicenseListVersion: 3.18 Creator: Organization: Anchore, Inc Creator: Tool: syft-v0.42.0-bogus -Created: 2022-11-18T14:21:44Z +Created: 2022-11-19T13:48:30Z ##### Package: package-2 diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden index 4d6a523d5..3d62f6ccc 100644 --- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden @@ -2,11 +2,11 @@ SPDXVersion: SPDX-2.3 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: user-image-input -DocumentNamespace: https://anchore.com/syft/image/user-image-input-aa272d1e-8bb4-411f-a554-4c9a16ea66fb +DocumentNamespace: https://anchore.com/syft/image/user-image-input-baff7ada-85cb-403e-90d7-05b0c6d79490 LicenseListVersion: 3.18 Creator: Organization: Anchore, Inc Creator: Tool: syft-v0.42.0-bogus -Created: 2022-11-18T14:21:45Z +Created: 2022-11-19T13:48:30Z ##### Package: package-2 diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/stereoscope-fixture-image-simple.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/stereoscope-fixture-image-simple.golden index f902fc6aa..0a4b4d256 100644 Binary files a/syft/formats/spdxtagvalue/test-fixtures/snapshot/stereoscope-fixture-image-simple.golden and b/syft/formats/spdxtagvalue/test-fixtures/snapshot/stereoscope-fixture-image-simple.golden differ