diff --git a/internal/formats/common/testutils/utils.go b/internal/formats/common/testutils/utils.go new file mode 100644 index 000000000..db5f2d78c --- /dev/null +++ b/internal/formats/common/testutils/utils.go @@ -0,0 +1,207 @@ +package testutils + +import ( + "bytes" + "testing" + + "github.com/anchore/syft/syft/presenter" + + "github.com/anchore/go-testutils" + "github.com/anchore/stereoscope/pkg/filetree" + "github.com/anchore/stereoscope/pkg/imagetest" + "github.com/anchore/syft/syft/distro" + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/source" + "github.com/sergi/go-diff/diffmatchpatch" + "github.com/stretchr/testify/assert" +) + +type redactor func(s []byte) []byte + +func MustCPE(c pkg.CPE, e error) pkg.CPE { + if e != nil { + panic(e) + } + return c +} + +func AssertPresenterAgainstGoldenImageSnapshot(t *testing.T, pres presenter.Presenter, testImage string, updateSnapshot bool, redactors ...redactor) { + var buffer bytes.Buffer + + // grab the latest image contents and persist + if updateSnapshot { + imagetest.UpdateGoldenFixtureImage(t, testImage) + } + + err := pres.Present(&buffer) + assert.NoError(t, err) + actual := buffer.Bytes() + + // replace the expected snapshot contents with the current presenter contents + if updateSnapshot { + testutils.UpdateGoldenFileContents(t, actual) + } + + var expected = testutils.GetGoldenFileContents(t) + + // remove dynamic values, which should be tested independently + for _, r := range redactors { + actual = r(actual) + expected = r(expected) + } + + // assert that the golden file snapshot matches the actual contents + if !bytes.Equal(expected, actual) { + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(string(expected), string(actual), true) + t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs)) + } +} + +func AssertPresenterAgainstGoldenSnapshot(t *testing.T, pres presenter.Presenter, updateSnapshot bool, redactors ...redactor) { + var buffer bytes.Buffer + + err := pres.Present(&buffer) + assert.NoError(t, err) + actual := buffer.Bytes() + + // replace the expected snapshot contents with the current presenter contents + if updateSnapshot { + testutils.UpdateGoldenFileContents(t, actual) + } + + var expected = testutils.GetGoldenFileContents(t) + + // remove dynamic values, which should be tested independently + for _, r := range redactors { + actual = r(actual) + expected = r(expected) + } + + if !bytes.Equal(expected, actual) { + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(string(expected), string(actual), true) + t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs)) + } +} + +func ImageInput(t testing.TB, testImage string) (*pkg.Catalog, source.Metadata, *distro.Distro) { + t.Helper() + catalog := pkg.NewCatalog() + img := imagetest.GetGoldenFixtureImage(t, testImage) + + _, ref1, _ := img.SquashedTree().File("/somefile-1.txt", filetree.FollowBasenameLinks) + _, ref2, _ := img.SquashedTree().File("/somefile-2.txt", filetree.FollowBasenameLinks) + + // populate catalog with test data + catalog.Add(pkg.Package{ + ID: "package-1-id", + Name: "package-1", + Version: "1.0.1", + Locations: []source.Location{ + source.NewLocationFromImage(string(ref1.RealPath), *ref1, img), + }, + Type: pkg.PythonPkg, + FoundBy: "the-cataloger-1", + Language: pkg.Python, + MetadataType: pkg.PythonPackageMetadataType, + Licenses: []string{"MIT"}, + Metadata: pkg.PythonPackageMetadata{ + Name: "package-1", + Version: "1.0.1", + }, + PURL: "a-purl-1", + CPEs: []pkg.CPE{ + MustCPE(pkg.NewCPE("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*")), + }, + }) + catalog.Add(pkg.Package{ + ID: "package-2-id", + Name: "package-2", + Version: "2.0.1", + Locations: []source.Location{ + source.NewLocationFromImage(string(ref2.RealPath), *ref2, img), + }, + Type: pkg.DebPkg, + FoundBy: "the-cataloger-2", + MetadataType: pkg.DpkgMetadataType, + Metadata: pkg.DpkgMetadata{ + Package: "package-2", + Version: "2.0.1", + }, + PURL: "a-purl-2", + CPEs: []pkg.CPE{ + MustCPE(pkg.NewCPE("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*")), + }, + }) + + // this is a hard coded value that is not given by the fixture helper and must be provided manually + img.Metadata.ManifestDigest = "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368" + + src, err := source.NewFromImage(img, "user-image-input") + assert.NoError(t, err) + + dist, err := distro.NewDistro(distro.Debian, "1.2.3", "like!") + assert.NoError(t, err) + + return catalog, src.Metadata, &dist +} + +func DirectoryInput(t testing.TB) (*pkg.Catalog, source.Metadata, *distro.Distro) { + catalog := pkg.NewCatalog() + + // populate catalog with test data + catalog.Add(pkg.Package{ + ID: "package-1-id", + Name: "package-1", + Version: "1.0.1", + Type: pkg.PythonPkg, + FoundBy: "the-cataloger-1", + Locations: []source.Location{ + {RealPath: "/some/path/pkg1"}, + }, + Language: pkg.Python, + MetadataType: pkg.PythonPackageMetadataType, + Licenses: []string{"MIT"}, + Metadata: pkg.PythonPackageMetadata{ + Name: "package-1", + Version: "1.0.1", + Files: []pkg.PythonFileRecord{ + { + Path: "/some/path/pkg1/depedencies/foo", + }, + }, + }, + PURL: "a-purl-2", + CPEs: []pkg.CPE{ + MustCPE(pkg.NewCPE("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*")), + }, + }) + catalog.Add(pkg.Package{ + ID: "package-2-id", + Name: "package-2", + Version: "2.0.1", + Type: pkg.DebPkg, + FoundBy: "the-cataloger-2", + Locations: []source.Location{ + {RealPath: "/some/path/pkg1"}, + }, + MetadataType: pkg.DpkgMetadataType, + Metadata: pkg.DpkgMetadata{ + Package: "package-2", + Version: "2.0.1", + }, + PURL: "a-purl-2", + CPEs: []pkg.CPE{ + MustCPE(pkg.NewCPE("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*")), + }, + }) + + dist, err := distro.NewDistro(distro.Debian, "1.2.3", "like!") + assert.NoError(t, err) + + src, err := source.NewFromDirectory("/some/path") + assert.NoError(t, err) + + return catalog, src.Metadata, &dist +} diff --git a/internal/formats/spdx22json/encoder_test.go b/internal/formats/spdx22json/encoder_test.go new file mode 100644 index 000000000..53b10c912 --- /dev/null +++ b/internal/formats/spdx22json/encoder_test.go @@ -0,0 +1,43 @@ +package spdx22json + +import ( + "flag" + "regexp" + "testing" + + "github.com/anchore/syft/internal/formats/common/testutils" + "github.com/anchore/syft/syft/format" +) + +var updateSpdxJson = flag.Bool("update-spdx-json", false, "update the *.golden files for spdx-json presenters") + +func TestSPDXJSONDirectoryPresenter(t *testing.T) { + catalog, metadata, distro := testutils.DirectoryInput(t) + testutils.AssertPresenterAgainstGoldenSnapshot(t, + format.NewPresenter(encoder, catalog, &metadata, distro), + *updateSpdxJson, + spdxJsonRedactor, + ) +} + +func TestSPDXJSONImagePresenter(t *testing.T) { + testImage := "image-simple" + catalog, metadata, distro := testutils.ImageInput(t, testImage) + testutils.AssertPresenterAgainstGoldenImageSnapshot(t, + format.NewPresenter(encoder, catalog, &metadata, distro), + testImage, + *updateSpdxJson, + spdxJsonRedactor, + ) +} + +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")) + + // each SBOM reports a unique documentNamespace when generated, this is not useful for snapshot testing + s = regexp.MustCompile(`"documentNamespace": .*`).ReplaceAll(s, []byte("redacted")) + + // the license list will be updated periodically, the value here should not be directly tested in snapshot tests + return regexp.MustCompile(`"licenseListVersion": .*`).ReplaceAll(s, []byte("redacted")) +} diff --git a/internal/formats/spdx22json/model/syft_package_data.go b/internal/formats/spdx22json/model/syft_package_data.go index 58efd69b1..1b33db575 100644 --- a/internal/formats/spdx22json/model/syft_package_data.go +++ b/internal/formats/spdx22json/model/syft_package_data.go @@ -15,16 +15,16 @@ type SyftPackageData struct { } type SyftPackageCustomData struct { - MetadataType pkg.MetadataType `json:"metadataType"` - Metadata interface{} `json:"metadata"` + MetadataType pkg.MetadataType `json:"metadataType,omitempty"` + Metadata interface{} `json:"metadata,omitempty"` } type SyftPackageBasicData struct { - PackageType pkg.Type `json:"type"` - FoundBy string `json:"foundBy"` - Locations []source.Location `json:"locations"` - Licenses []string `json:"licenses"` - Language pkg.Language `json:"language"` + PackageType pkg.Type `json:"type,omitempty"` + FoundBy string `json:"foundBy,omitempty"` + Locations []source.Location `json:"locations,omitempty"` + Licenses []string `json:"licenses,omitempty"` + Language pkg.Language `json:"language,omitempty"` } // syftPackageMetadataUnpacker is all values needed from Package to disambiguate ambiguous fields during json unmarshaling. diff --git a/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden b/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden index 249517449..8b7ed5756 100644 --- a/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden +++ b/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden @@ -3,15 +3,36 @@ "name": "/some/path", "spdxVersion": "SPDX-2.2", "creationInfo": { - "created": "2021-09-16T20:44:35.198887Z", + "created": "2021-10-11T01:54:40.609143Z", "creators": [ "Organization: Anchore, Inc", "Tool: syft-[not provided]" ], "licenseListVersion": "3.14" }, + "syftSourceData": { + "Scheme": "DirectoryScheme", + "ImageMetadata": { + "userInput": "", + "imageID": "", + "manifestDigest": "", + "mediaType": "", + "tags": null, + "imageSize": 0, + "layers": null, + "manifest": null, + "config": null, + "repoDigests": null + }, + "Path": "/some/path" + }, + "syftDistroData": { + "name": "debian", + "version": "1.2.3", + "idLike": "like!" + }, "dataLicense": "CC0-1.0", - "documentNamespace": "https://anchore.com/syft/image/", + "documentNamespace": "https:/anchore.com/syft/dir/some/path-e94d6e43-5de5-4849-8e21-983ada9103c5", "packages": [ { "SPDXID": "SPDXRef-Package-python-package-1-1.0.1", @@ -36,7 +57,35 @@ ], "licenseDeclared": "MIT", "sourceInfo": "acquired package info from installed python package manifest file: /some/path/pkg1", - "versionInfo": "1.0.1" + "versionInfo": "1.0.1", + "syftPackageData": { + "type": "python", + "foundBy": "the-cataloger-1", + "locations": [ + { + "path": "/some/path/pkg1" + } + ], + "licenses": [ + "MIT" + ], + "language": "python", + "metadataType": "PythonPackageMetadata", + "metadata": { + "name": "package-1", + "version": "1.0.1", + "license": "", + "author": "", + "authorEmail": "", + "platform": "", + "files": [ + { + "path": "/some/path/pkg1/depedencies/foo" + } + ], + "sitePackagesRootPath": "" + } + } }, { "SPDXID": "SPDXRef-Package-deb-package-2-2.0.1", @@ -58,7 +107,27 @@ "filesAnalyzed": false, "licenseDeclared": "NONE", "sourceInfo": "acquired package info from DPKG DB: /some/path/pkg1", - "versionInfo": "2.0.1" + "versionInfo": "2.0.1", + "syftPackageData": { + "type": "deb", + "foundBy": "the-cataloger-2", + "locations": [ + { + "path": "/some/path/pkg1" + } + ], + "metadataType": "DpkgMetadata", + "metadata": { + "package": "package-2", + "source": "", + "version": "2.0.1", + "sourceVersion": "", + "architecture": "", + "maintainer": "", + "installedSize": 0, + "files": null + } + } } ], "files": [ diff --git a/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden b/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden index 8906ef161..cba9d5d06 100644 --- a/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden +++ b/internal/formats/spdx22json/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden @@ -3,15 +3,49 @@ "name": "user-image-input", "spdxVersion": "SPDX-2.2", "creationInfo": { - "created": "2021-09-16T20:44:35.203911Z", + "created": "2021-10-11T01:54:40.61361Z", "creators": [ "Organization: Anchore, Inc", "Tool: syft-[not provided]" ], "licenseListVersion": "3.14" }, + "syftSourceData": { + "Scheme": "ImageScheme", + "ImageMetadata": { + "userInput": "user-image-input", + "imageID": "sha256:2480160b55bec40c44d3b145c7b2c1c47160db8575c3dcae086d76b9370ae7ca", + "manifestDigest": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368", + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "tags": [ + "stereoscope-fixture-image-simple:85066c51088bdd274f7a89e99e00490f666c49e72ffc955707cd6e18f0e22c5b" + ], + "imageSize": 38, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:fb6beecb75b39f4bb813dbf177e501edd5ddb3e69bb45cedeb78c676ee1b7a59", + "size": 22 + }, + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:319b588ce64253a87b533c8ed01cf0025e0eac98e7b516e12532957e1244fdec", + "size": 16 + } + ], + "manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjo2NjcsImRpZ2VzdCI6InNoYTI1NjoyNDgwMTYwYjU1YmVjNDBjNDRkM2IxNDVjN2IyYzFjNDcxNjBkYjg1NzVjM2RjYWUwODZkNzZiOTM3MGFlN2NhIn0sImxheWVycyI6W3sibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjIwNDgsImRpZ2VzdCI6InNoYTI1NjpmYjZiZWVjYjc1YjM5ZjRiYjgxM2RiZjE3N2U1MDFlZGQ1ZGRiM2U2OWJiNDVjZWRlYjc4YzY3NmVlMWI3YTU5In0seyJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmltYWdlLnJvb3Rmcy5kaWZmLnRhci5nemlwIiwic2l6ZSI6MjA0OCwiZGlnZXN0Ijoic2hhMjU2OjMxOWI1ODhjZTY0MjUzYTg3YjUzM2M4ZWQwMWNmMDAyNWUwZWFjOThlN2I1MTZlMTI1MzI5NTdlMTI0NGZkZWMifV19", + "config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiV29ya2luZ0RpciI6Ii8iLCJPbkJ1aWxkIjpudWxsfSwiY3JlYXRlZCI6IjIwMjEtMTAtMDRUMTE6NDA6MDAuNjM4Mzk0NVoiLCJoaXN0b3J5IjpbeyJjcmVhdGVkIjoiMjAyMS0xMC0wNFQxMTo0MDowMC41OTA3MzE2WiIsImNyZWF0ZWRfYnkiOiJBREQgZmlsZS0xLnR4dCAvc29tZWZpbGUtMS50eHQgIyBidWlsZGtpdCIsImNvbW1lbnQiOiJidWlsZGtpdC5kb2NrZXJmaWxlLnYwIn0seyJjcmVhdGVkIjoiMjAyMS0xMC0wNFQxMTo0MDowMC42MzgzOTQ1WiIsImNyZWF0ZWRfYnkiOiJBREQgZmlsZS0yLnR4dCAvc29tZWZpbGUtMi50eHQgIyBidWlsZGtpdCIsImNvbW1lbnQiOiJidWlsZGtpdC5kb2NrZXJmaWxlLnYwIn1dLCJvcyI6ImxpbnV4Iiwicm9vdGZzIjp7InR5cGUiOiJsYXllcnMiLCJkaWZmX2lkcyI6WyJzaGEyNTY6ZmI2YmVlY2I3NWIzOWY0YmI4MTNkYmYxNzdlNTAxZWRkNWRkYjNlNjliYjQ1Y2VkZWI3OGM2NzZlZTFiN2E1OSIsInNoYTI1NjozMTliNTg4Y2U2NDI1M2E4N2I1MzNjOGVkMDFjZjAwMjVlMGVhYzk4ZTdiNTE2ZTEyNTMyOTU3ZTEyNDRmZGVjIl19fQ==", + "repoDigests": [] + }, + "Path": "" + }, + "syftDistroData": { + "name": "debian", + "version": "1.2.3", + "idLike": "like!" + }, "dataLicense": "CC0-1.0", - "documentNamespace": "https://anchore.com/syft/image/user-image-input", + "documentNamespace": "https:/anchore.com/syft/image/user-image-input-9badd1fb-a067-4207-addf-243c5b7705fe", "packages": [ { "SPDXID": "SPDXRef-Package-python-package-1-1.0.1", @@ -33,7 +67,31 @@ "filesAnalyzed": false, "licenseDeclared": "MIT", "sourceInfo": "acquired package info from installed python package manifest file: /somefile-1.txt", - "versionInfo": "1.0.1" + "versionInfo": "1.0.1", + "syftPackageData": { + "type": "python", + "foundBy": "the-cataloger-1", + "locations": [ + { + "path": "/somefile-1.txt", + "layerID": "sha256:fb6beecb75b39f4bb813dbf177e501edd5ddb3e69bb45cedeb78c676ee1b7a59" + } + ], + "licenses": [ + "MIT" + ], + "language": "python", + "metadataType": "PythonPackageMetadata", + "metadata": { + "name": "package-1", + "version": "1.0.1", + "license": "", + "author": "", + "authorEmail": "", + "platform": "", + "sitePackagesRootPath": "" + } + } }, { "SPDXID": "SPDXRef-Package-deb-package-2-2.0.1", @@ -55,7 +113,28 @@ "filesAnalyzed": false, "licenseDeclared": "NONE", "sourceInfo": "acquired package info from DPKG DB: /somefile-2.txt", - "versionInfo": "2.0.1" + "versionInfo": "2.0.1", + "syftPackageData": { + "type": "deb", + "foundBy": "the-cataloger-2", + "locations": [ + { + "path": "/somefile-2.txt", + "layerID": "sha256:319b588ce64253a87b533c8ed01cf0025e0eac98e7b516e12532957e1244fdec" + } + ], + "metadataType": "DpkgMetadata", + "metadata": { + "package": "package-2", + "source": "", + "version": "2.0.1", + "sourceVersion": "", + "architecture": "", + "maintainer": "", + "installedSize": 0, + "files": null + } + } } ] } diff --git a/internal/formats/syftjson/encoder_test.go b/internal/formats/syftjson/encoder_test.go new file mode 100644 index 000000000..69fda8a66 --- /dev/null +++ b/internal/formats/syftjson/encoder_test.go @@ -0,0 +1,29 @@ +package syftjson + +import ( + "flag" + "testing" + + "github.com/anchore/syft/internal/formats/common/testutils" + "github.com/anchore/syft/syft/format" +) + +var updateJson = flag.Bool("update-json", false, "update the *.golden files for json presenters") + +func TestJSONDirectoryPresenter(t *testing.T) { + catalog, metadata, distro := testutils.DirectoryInput(t) + testutils.AssertPresenterAgainstGoldenSnapshot(t, + format.NewPresenter(encoder, catalog, &metadata, distro), + *updateJson, + ) +} + +func TestJSONImagePresenter(t *testing.T) { + testImage := "image-simple" + catalog, metadata, distro := testutils.ImageInput(t, testImage) + testutils.AssertPresenterAgainstGoldenImageSnapshot(t, + format.NewPresenter(encoder, catalog, &metadata, distro), + testImage, + *updateJson, + ) +} diff --git a/internal/formats/syftjson/test-fixtures/snapshot/TestJSONDirectoryPresenter.golden b/internal/formats/syftjson/test-fixtures/snapshot/TestJSONDirectoryPresenter.golden new file mode 100644 index 000000000..2abdef222 --- /dev/null +++ b/internal/formats/syftjson/test-fixtures/snapshot/TestJSONDirectoryPresenter.golden @@ -0,0 +1,86 @@ +{ + "artifacts": [ + { + "id": "package-1-id", + "name": "package-1", + "version": "1.0.1", + "type": "python", + "foundBy": "the-cataloger-1", + "locations": [ + { + "path": "/some/path/pkg1" + } + ], + "licenses": [ + "MIT" + ], + "language": "python", + "cpes": [ + "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*" + ], + "purl": "a-purl-2", + "metadataType": "PythonPackageMetadata", + "metadata": { + "name": "package-1", + "version": "1.0.1", + "license": "", + "author": "", + "authorEmail": "", + "platform": "", + "files": [ + { + "path": "/some/path/pkg1/depedencies/foo" + } + ], + "sitePackagesRootPath": "" + } + }, + { + "id": "package-2-id", + "name": "package-2", + "version": "2.0.1", + "type": "deb", + "foundBy": "the-cataloger-2", + "locations": [ + { + "path": "/some/path/pkg1" + } + ], + "licenses": [], + "language": "", + "cpes": [ + "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*" + ], + "purl": "a-purl-2", + "metadataType": "DpkgMetadata", + "metadata": { + "package": "package-2", + "source": "", + "version": "2.0.1", + "sourceVersion": "", + "architecture": "", + "maintainer": "", + "installedSize": 0, + "files": null + } + } + ], + "artifactRelationships": [], + "source": { + "type": "directory", + "target": "/some/path" + }, + "distro": { + "name": "debian", + "version": "1.2.3", + "idLike": "like!" + }, + "descriptor": { + "name": "syft", + "version": "[not provided]" + }, + "schema": { + "version": "1.1.0", + "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-1.1.0.json" + } +} diff --git a/internal/formats/syftjson/test-fixtures/snapshot/TestJSONImagePresenter.golden b/internal/formats/syftjson/test-fixtures/snapshot/TestJSONImagePresenter.golden new file mode 100644 index 000000000..abcda45b5 --- /dev/null +++ b/internal/formats/syftjson/test-fixtures/snapshot/TestJSONImagePresenter.golden @@ -0,0 +1,108 @@ +{ + "artifacts": [ + { + "id": "package-1-id", + "name": "package-1", + "version": "1.0.1", + "type": "python", + "foundBy": "the-cataloger-1", + "locations": [ + { + "path": "/somefile-1.txt", + "layerID": "sha256:ffb5e9eaa453a002110719d12c294960117ca2903953d1faa40f01dc3f77045c" + } + ], + "licenses": [ + "MIT" + ], + "language": "python", + "cpes": [ + "cpe:2.3:*:some:package:1:*:*:*:*:*:*:*" + ], + "purl": "a-purl-1", + "metadataType": "PythonPackageMetadata", + "metadata": { + "name": "package-1", + "version": "1.0.1", + "license": "", + "author": "", + "authorEmail": "", + "platform": "", + "sitePackagesRootPath": "" + } + }, + { + "id": "package-2-id", + "name": "package-2", + "version": "2.0.1", + "type": "deb", + "foundBy": "the-cataloger-2", + "locations": [ + { + "path": "/somefile-2.txt", + "layerID": "sha256:8463854829fc53d47b9dcdf7ee79fe7eb4ca7933c910f67f8521412f7a2f5c21" + } + ], + "licenses": [], + "language": "", + "cpes": [ + "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*" + ], + "purl": "a-purl-2", + "metadataType": "DpkgMetadata", + "metadata": { + "package": "package-2", + "source": "", + "version": "2.0.1", + "sourceVersion": "", + "architecture": "", + "maintainer": "", + "installedSize": 0, + "files": null + } + } + ], + "artifactRelationships": [], + "source": { + "type": "image", + "target": { + "userInput": "user-image-input", + "imageID": "sha256:112851310e48e604f7379e2a3acddab50e91ce926edacb598a532e60ff6b776a", + "manifestDigest": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368", + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "tags": [ + "stereoscope-fixture-image-simple:85066c51088bdd274f7a89e99e00490f666c49e72ffc955707cd6e18f0e22c5b" + ], + "imageSize": 38, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:ffb5e9eaa453a002110719d12c294960117ca2903953d1faa40f01dc3f77045c", + "size": 22 + }, + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "digest": "sha256:8463854829fc53d47b9dcdf7ee79fe7eb4ca7933c910f67f8521412f7a2f5c21", + "size": 16 + } + ], + "manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjo2NzMsImRpZ2VzdCI6InNoYTI1NjoxMTI4NTEzMTBlNDhlNjA0ZjczNzllMmEzYWNkZGFiNTBlOTFjZTkyNmVkYWNiNTk4YTUzMmU2MGZmNmI3NzZhIn0sImxheWVycyI6W3sibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjIwNDgsImRpZ2VzdCI6InNoYTI1NjpmZmI1ZTllYWE0NTNhMDAyMTEwNzE5ZDEyYzI5NDk2MDExN2NhMjkwMzk1M2QxZmFhNDBmMDFkYzNmNzcwNDVjIn0seyJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmltYWdlLnJvb3Rmcy5kaWZmLnRhci5nemlwIiwic2l6ZSI6MjA0OCwiZGlnZXN0Ijoic2hhMjU2Ojg0NjM4NTQ4MjlmYzUzZDQ3YjlkY2RmN2VlNzlmZTdlYjRjYTc5MzNjOTEwZjY3Zjg1MjE0MTJmN2EyZjVjMjEifV19", + "config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiV29ya2luZ0RpciI6Ii8iLCJPbkJ1aWxkIjpudWxsfSwiY3JlYXRlZCI6IjIwMjEtMDktMDhUMTc6MjE6NTguODk2NTI5MTkyWiIsImhpc3RvcnkiOlt7ImNyZWF0ZWQiOiIyMDIxLTA5LTA4VDE3OjIxOjU4Ljg3OTY5MDgyNFoiLCJjcmVhdGVkX2J5IjoiQUREIGZpbGUtMS50eHQgL3NvbWVmaWxlLTEudHh0ICMgYnVpbGRraXQiLCJjb21tZW50IjoiYnVpbGRraXQuZG9ja2VyZmlsZS52MCJ9LHsiY3JlYXRlZCI6IjIwMjEtMDktMDhUMTc6MjE6NTguODk2NTI5MTkyWiIsImNyZWF0ZWRfYnkiOiJBREQgZmlsZS0yLnR4dCAvc29tZWZpbGUtMi50eHQgIyBidWlsZGtpdCIsImNvbW1lbnQiOiJidWlsZGtpdC5kb2NrZXJmaWxlLnYwIn1dLCJvcyI6ImxpbnV4Iiwicm9vdGZzIjp7InR5cGUiOiJsYXllcnMiLCJkaWZmX2lkcyI6WyJzaGEyNTY6ZmZiNWU5ZWFhNDUzYTAwMjExMDcxOWQxMmMyOTQ5NjAxMTdjYTI5MDM5NTNkMWZhYTQwZjAxZGMzZjc3MDQ1YyIsInNoYTI1Njo4NDYzODU0ODI5ZmM1M2Q0N2I5ZGNkZjdlZTc5ZmU3ZWI0Y2E3OTMzYzkxMGY2N2Y4NTIxNDEyZjdhMmY1YzIxIl19fQ==", + "repoDigests": [], + "scope": "Squashed" + } + }, + "distro": { + "name": "debian", + "version": "1.2.3", + "idLike": "like!" + }, + "descriptor": { + "name": "syft", + "version": "[not provided]" + }, + "schema": { + "version": "1.1.0", + "url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-1.1.0.json" + } +} diff --git a/internal/formats/syftjson/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden b/internal/formats/syftjson/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden deleted file mode 100644 index 249517449..000000000 --- a/internal/formats/syftjson/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden +++ /dev/null @@ -1,79 +0,0 @@ -{ - "SPDXID": "SPDXRef-DOCUMENT", - "name": "/some/path", - "spdxVersion": "SPDX-2.2", - "creationInfo": { - "created": "2021-09-16T20:44:35.198887Z", - "creators": [ - "Organization: Anchore, Inc", - "Tool: syft-[not provided]" - ], - "licenseListVersion": "3.14" - }, - "dataLicense": "CC0-1.0", - "documentNamespace": "https://anchore.com/syft/image/", - "packages": [ - { - "SPDXID": "SPDXRef-Package-python-package-1-1.0.1", - "name": "package-1", - "licenseConcluded": "MIT", - "downloadLocation": "NOASSERTION", - "externalRefs": [ - { - "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", - "referenceType": "cpe23Type" - }, - { - "referenceCategory": "PACKAGE_MANAGER", - "referenceLocator": "a-purl-2", - "referenceType": "purl" - } - ], - "filesAnalyzed": false, - "hasFiles": [ - "SPDXRef-File-package-1-04cd22424378dcd6c77fce08beb52493b5494a60ea5e1f9bdf9b16dc0cacffe9" - ], - "licenseDeclared": "MIT", - "sourceInfo": "acquired package info from installed python package manifest file: /some/path/pkg1", - "versionInfo": "1.0.1" - }, - { - "SPDXID": "SPDXRef-Package-deb-package-2-2.0.1", - "name": "package-2", - "licenseConcluded": "NONE", - "downloadLocation": "NOASSERTION", - "externalRefs": [ - { - "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", - "referenceType": "cpe23Type" - }, - { - "referenceCategory": "PACKAGE_MANAGER", - "referenceLocator": "a-purl-2", - "referenceType": "purl" - } - ], - "filesAnalyzed": false, - "licenseDeclared": "NONE", - "sourceInfo": "acquired package info from DPKG DB: /some/path/pkg1", - "versionInfo": "2.0.1" - } - ], - "files": [ - { - "SPDXID": "SPDXRef-File-package-1-04cd22424378dcd6c77fce08beb52493b5494a60ea5e1f9bdf9b16dc0cacffe9", - "name": "foo", - "licenseConcluded": "", - "fileName": "/some/path/pkg1/depedencies/foo" - } - ], - "relationships": [ - { - "spdxElementId": "SPDXRef-Package-python-package-1-1.0.1", - "relationshipType": "CONTAINS", - "relatedSpdxElement": "SPDXRef-File-package-1-04cd22424378dcd6c77fce08beb52493b5494a60ea5e1f9bdf9b16dc0cacffe9" - } - ] -} diff --git a/internal/formats/syftjson/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden b/internal/formats/syftjson/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden deleted file mode 100644 index 8906ef161..000000000 --- a/internal/formats/syftjson/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden +++ /dev/null @@ -1,61 +0,0 @@ -{ - "SPDXID": "SPDXRef-DOCUMENT", - "name": "user-image-input", - "spdxVersion": "SPDX-2.2", - "creationInfo": { - "created": "2021-09-16T20:44:35.203911Z", - "creators": [ - "Organization: Anchore, Inc", - "Tool: syft-[not provided]" - ], - "licenseListVersion": "3.14" - }, - "dataLicense": "CC0-1.0", - "documentNamespace": "https://anchore.com/syft/image/user-image-input", - "packages": [ - { - "SPDXID": "SPDXRef-Package-python-package-1-1.0.1", - "name": "package-1", - "licenseConcluded": "MIT", - "downloadLocation": "NOASSERTION", - "externalRefs": [ - { - "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:*:some:package:1:*:*:*:*:*:*:*", - "referenceType": "cpe23Type" - }, - { - "referenceCategory": "PACKAGE_MANAGER", - "referenceLocator": "a-purl-1", - "referenceType": "purl" - } - ], - "filesAnalyzed": false, - "licenseDeclared": "MIT", - "sourceInfo": "acquired package info from installed python package manifest file: /somefile-1.txt", - "versionInfo": "1.0.1" - }, - { - "SPDXID": "SPDXRef-Package-deb-package-2-2.0.1", - "name": "package-2", - "licenseConcluded": "NONE", - "downloadLocation": "NOASSERTION", - "externalRefs": [ - { - "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", - "referenceType": "cpe23Type" - }, - { - "referenceCategory": "PACKAGE_MANAGER", - "referenceLocator": "a-purl-2", - "referenceType": "purl" - } - ], - "filesAnalyzed": false, - "licenseDeclared": "NONE", - "sourceInfo": "acquired package info from DPKG DB: /somefile-2.txt", - "versionInfo": "2.0.1" - } - ] -}