diff --git a/internal/presenter/packages/cyclonedx_presenter_test.go b/internal/presenter/packages/cyclonedx_presenter_test.go index 4914edbb4..083a72022 100644 --- a/internal/presenter/packages/cyclonedx_presenter_test.go +++ b/internal/presenter/packages/cyclonedx_presenter_test.go @@ -4,13 +4,15 @@ import ( "flag" "regexp" "testing" + + "github.com/anchore/syft/internal/formats/common/testutils" ) var updateCycloneDx = flag.Bool("update-cyclonedx", false, "update the *.golden files for cyclone-dx presenters") func TestCycloneDxDirectoryPresenter(t *testing.T) { - catalog, metadata, _ := presenterDirectoryInput(t) - assertPresenterAgainstGoldenSnapshot(t, + catalog, metadata, _ := testutils.DirectoryInput(t) + testutils.AssertPresenterAgainstGoldenSnapshot(t, NewCycloneDxPresenter(catalog, metadata), *updateCycloneDx, cycloneDxRedactor, @@ -19,8 +21,8 @@ func TestCycloneDxDirectoryPresenter(t *testing.T) { func TestCycloneDxImagePresenter(t *testing.T) { testImage := "image-simple" - catalog, metadata, _ := presenterImageInput(t, testImage) - assertPresenterAgainstGoldenImageSnapshot(t, + catalog, metadata, _ := testutils.ImageInput(t, testImage) + testutils.AssertPresenterAgainstGoldenImageSnapshot(t, NewCycloneDxPresenter(catalog, metadata), testImage, *updateCycloneDx, diff --git a/internal/presenter/packages/spdx_helpers_test.go b/internal/presenter/packages/spdx_helpers_test.go deleted file mode 100644 index 985e26fed..000000000 --- a/internal/presenter/packages/spdx_helpers_test.go +++ /dev/null @@ -1,527 +0,0 @@ -package packages - -import ( - "testing" - - "github.com/anchore/syft/syft/source" - - "github.com/stretchr/testify/assert" - - "github.com/anchore/syft/internal/presenter/packages/model/spdx22" - "github.com/anchore/syft/syft/pkg" -) - -func Test_getSPDXExternalRefs(t *testing.T) { - testCPE := must(pkg.NewCPE("cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*")) - tests := []struct { - name string - input pkg.Package - expected []spdx22.ExternalRef - }{ - { - name: "cpe + purl", - input: pkg.Package{ - CPEs: []pkg.CPE{ - testCPE, - }, - PURL: "a-purl", - }, - expected: []spdx22.ExternalRef{ - { - ReferenceCategory: spdx22.SecurityReferenceCategory, - ReferenceLocator: testCPE.BindToFmtString(), - ReferenceType: spdx22.Cpe23ExternalRefType, - }, - { - ReferenceCategory: spdx22.PackageManagerReferenceCategory, - ReferenceLocator: "a-purl", - ReferenceType: spdx22.PurlExternalRefType, - }, - }, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.ElementsMatch(t, test.expected, getSPDXExternalRefs(&test.input)) - }) - } -} - -func Test_getSPDXLicense(t *testing.T) { - tests := []struct { - name string - input pkg.Package - expected string - }{ - { - name: "no licenses", - input: pkg.Package{}, - expected: "NONE", - }, - { - name: "no SPDX licenses", - input: pkg.Package{ - Licenses: []string{ - "made-up", - }, - }, - expected: "NOASSERTION", - }, - { - name: "with SPDX license", - input: pkg.Package{ - Licenses: []string{ - "MIT", - }, - }, - expected: "MIT", - }, - { - name: "with SPDX license expression", - input: pkg.Package{ - Licenses: []string{ - "MIT", - "GPL-3.0", - }, - }, - expected: "MIT AND GPL-3.0", - }, - { - name: "cap insensitive", - input: pkg.Package{ - Licenses: []string{ - "gpl-3.0", - }, - }, - expected: "GPL-3.0", - }, - { - name: "debian to spdx conversion", - input: pkg.Package{ - Licenses: []string{ - "GPL-2", - }, - }, - expected: "GPL-2.0", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, getSPDXLicense(&test.input)) - }) - } -} - -func Test_noneIfEmpty(t *testing.T) { - tests := []struct { - name string - value string - expected string - }{ - { - name: "non-zero value", - value: "something", - expected: "something", - }, - { - name: "empty", - value: "", - expected: "NONE", - }, - { - name: "space", - value: " ", - expected: "NONE", - }, - { - name: "tab", - value: "\t", - expected: "NONE", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, noneIfEmpty(test.value)) - }) - } -} - -func Test_getSPDXDownloadLocation(t *testing.T) { - tests := []struct { - name string - input pkg.Package - expected string - }{ - { - name: "no metadata", - input: pkg.Package{}, - expected: "NOASSERTION", - }, - { - name: "from apk", - input: pkg.Package{ - Metadata: pkg.ApkMetadata{ - URL: "http://a-place.gov", - }, - }, - expected: "http://a-place.gov", - }, - { - name: "from npm", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - URL: "http://a-place.gov", - }, - }, - expected: "http://a-place.gov", - }, - { - name: "empty", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - URL: "", - }, - }, - expected: "NONE", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, getSPDXDownloadLocation(&test.input)) - }) - } -} - -func Test_getSPDXHomepage(t *testing.T) { - tests := []struct { - name string - input pkg.Package - expected string - }{ - { - // note: since this is an optional field, no value is preferred over NONE or NOASSERTION - name: "no metadata", - input: pkg.Package{}, - expected: "", - }, - { - name: "from gem", - input: pkg.Package{ - Metadata: pkg.GemMetadata{ - Homepage: "http://a-place.gov", - }, - }, - expected: "http://a-place.gov", - }, - { - name: "from npm", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - Homepage: "http://a-place.gov", - }, - }, - expected: "http://a-place.gov", - }, - { - // note: since this is an optional field, no value is preferred over NONE or NOASSERTION - name: "empty", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - Homepage: "", - }, - }, - expected: "", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, getSPDXHomepage(&test.input)) - }) - } -} - -func Test_getSPDXSourceInfo(t *testing.T) { - tests := []struct { - name string - input pkg.Package - expected []string - }{ - { - name: "locations are captured", - input: pkg.Package{ - // note: no type given - Locations: []source.Location{ - { - RealPath: "/a-place", - VirtualPath: "/b-place", - }, - { - RealPath: "/c-place", - VirtualPath: "/d-place", - }, - }, - }, - expected: []string{ - "from the following paths", - "/a-place", - "/c-place", - }, - }, - { - // note: no specific support for this - input: pkg.Package{ - Type: pkg.KbPkg, - }, - expected: []string{ - "from the following paths", - }, - }, - { - input: pkg.Package{ - Type: pkg.RpmPkg, - }, - expected: []string{ - "from RPM DB", - }, - }, - { - input: pkg.Package{ - Type: pkg.ApkPkg, - }, - expected: []string{ - "from APK DB", - }, - }, - { - input: pkg.Package{ - Type: pkg.DebPkg, - }, - expected: []string{ - "from DPKG DB", - }, - }, - { - input: pkg.Package{ - Type: pkg.NpmPkg, - }, - expected: []string{ - "from installed node module manifest file", - }, - }, - { - input: pkg.Package{ - Type: pkg.PythonPkg, - }, - expected: []string{ - "from installed python package manifest file", - }, - }, - { - input: pkg.Package{ - Type: pkg.JavaPkg, - }, - expected: []string{ - "from installed java archive", - }, - }, - { - input: pkg.Package{ - Type: pkg.JenkinsPluginPkg, - }, - expected: []string{ - "from installed java archive", - }, - }, - { - input: pkg.Package{ - Type: pkg.GemPkg, - }, - expected: []string{ - "from installed gem metadata file", - }, - }, - { - input: pkg.Package{ - Type: pkg.GoModulePkg, - }, - expected: []string{ - "from go module information", - }, - }, - { - input: pkg.Package{ - Type: pkg.RustPkg, - }, - expected: []string{ - "from rust cargo manifest", - }, - }, - } - var pkgTypes []pkg.Type - for _, test := range tests { - t.Run(test.name+" "+string(test.input.Type), func(t *testing.T) { - if test.input.Type != "" { - pkgTypes = append(pkgTypes, test.input.Type) - } - actual := getSPDXSourceInfo(&test.input) - for _, expected := range test.expected { - assert.Contains(t, actual, expected) - } - }) - } - assert.ElementsMatch(t, pkg.AllPkgs, pkgTypes, "missing one or more package types to test against (maybe a package type was added?)") -} - -func Test_getSPDXOriginator(t *testing.T) { - tests := []struct { - name string - input pkg.Package - expected string - }{ - { - // note: since this is an optional field, no value is preferred over NONE or NOASSERTION - name: "no metadata", - input: pkg.Package{}, - expected: "", - }, - { - name: "from gem", - input: pkg.Package{ - Metadata: pkg.GemMetadata{ - Authors: []string{ - "auth1", - "auth2", - }, - }, - }, - expected: "auth1", - }, - { - name: "from npm", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - Author: "auth", - }, - }, - expected: "auth", - }, - { - name: "from apk", - input: pkg.Package{ - Metadata: pkg.ApkMetadata{ - Maintainer: "auth", - }, - }, - expected: "auth", - }, - { - name: "from python - just name", - input: pkg.Package{ - Metadata: pkg.PythonPackageMetadata{ - Author: "auth", - }, - }, - expected: "auth", - }, - { - name: "from python - just email", - input: pkg.Package{ - Metadata: pkg.PythonPackageMetadata{ - AuthorEmail: "auth@auth.gov", - }, - }, - expected: "auth@auth.gov", - }, - { - name: "from python - both name and email", - input: pkg.Package{ - Metadata: pkg.PythonPackageMetadata{ - Author: "auth", - AuthorEmail: "auth@auth.gov", - }, - }, - expected: "auth ", - }, - { - name: "from rpm", - input: pkg.Package{ - Metadata: pkg.RpmdbMetadata{ - Vendor: "auth", - }, - }, - expected: "auth", - }, - { - name: "from dpkg", - input: pkg.Package{ - Metadata: pkg.DpkgMetadata{ - Maintainer: "auth", - }, - }, - expected: "auth", - }, - { - // note: since this is an optional field, no value is preferred over NONE or NOASSERTION - name: "empty", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - Author: "", - }, - }, - expected: "", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, getSPDXOriginator(&test.input)) - }) - } -} - -func Test_getSPDXDescription(t *testing.T) { - tests := []struct { - name string - input pkg.Package - expected string - }{ - { - // note: since this is an optional field, no value is preferred over NONE or NOASSERTION - name: "no metadata", - input: pkg.Package{}, - expected: "", - }, - { - name: "from apk", - input: pkg.Package{ - Metadata: pkg.ApkMetadata{ - Description: "a description!", - }, - }, - expected: "a description!", - }, - { - name: "from npm", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - Description: "a description!", - }, - }, - expected: "a description!", - }, - { - // note: since this is an optional field, no value is preferred over NONE or NOASSERTION - name: "empty", - input: pkg.Package{ - Metadata: pkg.NpmPackageJSONMetadata{ - Homepage: "", - }, - }, - expected: "", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, getSPDXDescription(&test.input)) - }) - } -} diff --git a/internal/presenter/packages/spdx_tag_value_presenter.go b/internal/presenter/packages/spdx_tag_value_presenter.go index 5f66fdf4a..19974ecb8 100644 --- a/internal/presenter/packages/spdx_tag_value_presenter.go +++ b/internal/presenter/packages/spdx_tag_value_presenter.go @@ -5,6 +5,8 @@ import ( "io" "time" + "github.com/anchore/syft/internal/formats/common/spdxhelpers" + "github.com/anchore/syft/internal/spdxlicense" "github.com/anchore/syft/internal" @@ -114,7 +116,7 @@ func (pres *SPDXTagValuePresenter) packages() map[spdx.ElementID]*spdx.Package2_ // If the Concluded License is not the same as the Declared License, a written explanation should be provided // in the Comments on License field (section 3.16). With respect to NOASSERTION, a written explanation in // the Comments on License field (section 3.16) is preferred. - license := getSPDXLicense(p) + license := spdxhelpers.License(p) results[spdx.ElementID(id)] = &spdx.Package2_2{ @@ -274,7 +276,7 @@ func (pres *SPDXTagValuePresenter) packages() map[spdx.ElementID]*spdx.Package2_ } func formatSPDXExternalRefs(p *pkg.Package) (refs []*spdx.PackageExternalReference2_2) { - for _, ref := range getSPDXExternalRefs(p) { + for _, ref := range spdxhelpers.ExternalRefs(p) { refs = append(refs, &spdx.PackageExternalReference2_2{ Category: string(ref.ReferenceCategory), RefType: string(ref.ReferenceType), diff --git a/internal/presenter/packages/spdx_tag_value_presenter_test.go b/internal/presenter/packages/spdx_tag_value_presenter_test.go index 8ffff1d62..95dd4a793 100644 --- a/internal/presenter/packages/spdx_tag_value_presenter_test.go +++ b/internal/presenter/packages/spdx_tag_value_presenter_test.go @@ -4,13 +4,15 @@ import ( "flag" "regexp" "testing" + + "github.com/anchore/syft/internal/formats/common/testutils" ) var updateSpdxTagValue = flag.Bool("update-spdx-tv", false, "update the *.golden files for spdx-tv presenters") func TestSPDXTagValueDirectoryPresenter(t *testing.T) { - catalog, metadata, _ := presenterDirectoryInput(t) - assertPresenterAgainstGoldenSnapshot(t, + catalog, metadata, _ := testutils.DirectoryInput(t) + testutils.AssertPresenterAgainstGoldenSnapshot(t, NewSPDXTagValuePresenter(catalog, metadata), *updateSpdxTagValue, spdxTagValueRedactor, @@ -19,8 +21,8 @@ func TestSPDXTagValueDirectoryPresenter(t *testing.T) { func TestSPDXTagValueImagePresenter(t *testing.T) { testImage := "image-simple" - catalog, metadata, _ := presenterImageInput(t, testImage) - assertPresenterAgainstGoldenImageSnapshot(t, + catalog, metadata, _ := testutils.ImageInput(t, testImage) + testutils.AssertPresenterAgainstGoldenImageSnapshot(t, NewSPDXTagValuePresenter(catalog, metadata), testImage, *updateSpdxTagValue, diff --git a/internal/presenter/packages/table_presenter_test.go b/internal/presenter/packages/table_presenter_test.go index 7d59fb1ba..01ebdaca8 100644 --- a/internal/presenter/packages/table_presenter_test.go +++ b/internal/presenter/packages/table_presenter_test.go @@ -4,6 +4,8 @@ import ( "flag" "testing" + "github.com/anchore/syft/internal/formats/common/testutils" + "github.com/go-test/deep" ) @@ -11,8 +13,8 @@ var updateTablePresenterGoldenFiles = flag.Bool("update-table", false, "update t func TestTablePresenter(t *testing.T) { testImage := "image-simple" - catalog, _, _ := presenterImageInput(t, testImage) - assertPresenterAgainstGoldenImageSnapshot(t, + catalog, _, _ := testutils.ImageInput(t, testImage) + testutils.AssertPresenterAgainstGoldenImageSnapshot(t, NewTablePresenter(catalog), testImage, *updateTablePresenterGoldenFiles, diff --git a/internal/presenter/packages/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden b/internal/presenter/packages/test-fixtures/snapshot/TestSPDXJSONDirectoryPresenter.golden deleted file mode 100644 index 249517449..000000000 --- a/internal/presenter/packages/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/presenter/packages/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden b/internal/presenter/packages/test-fixtures/snapshot/TestSPDXJSONImagePresenter.golden deleted file mode 100644 index 8906ef161..000000000 --- a/internal/presenter/packages/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" - } - ] -} diff --git a/internal/presenter/packages/text_presenter_test.go b/internal/presenter/packages/text_presenter_test.go index 2a2164285..a6533d356 100644 --- a/internal/presenter/packages/text_presenter_test.go +++ b/internal/presenter/packages/text_presenter_test.go @@ -3,13 +3,15 @@ package packages import ( "flag" "testing" + + "github.com/anchore/syft/internal/formats/common/testutils" ) var updateTextPresenterGoldenFiles = flag.Bool("update-text", false, "update the *.golden files for text presenters") func TestTextDirectoryPresenter(t *testing.T) { - catalog, metadata, _ := presenterDirectoryInput(t) - assertPresenterAgainstGoldenSnapshot(t, + catalog, metadata, _ := testutils.DirectoryInput(t) + testutils.AssertPresenterAgainstGoldenSnapshot(t, NewTextPresenter(catalog, metadata), *updateTextPresenterGoldenFiles, ) @@ -17,8 +19,8 @@ func TestTextDirectoryPresenter(t *testing.T) { func TestTextImagePresenter(t *testing.T) { testImage := "image-simple" - catalog, metadata, _ := presenterImageInput(t, testImage) - assertPresenterAgainstGoldenImageSnapshot(t, + catalog, metadata, _ := testutils.ImageInput(t, testImage) + testutils.AssertPresenterAgainstGoldenImageSnapshot(t, NewTextPresenter(catalog, metadata), testImage, *updateTextPresenterGoldenFiles, diff --git a/internal/presenter/packages/utils_test.go b/internal/presenter/packages/utils_test.go deleted file mode 100644 index 9c6a88242..000000000 --- a/internal/presenter/packages/utils_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package packages - -import ( - "bytes" - "testing" - - "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/presenter" - "github.com/anchore/syft/syft/source" - "github.com/sergi/go-diff/diffmatchpatch" - "github.com/stretchr/testify/assert" -) - -type redactor func(s []byte) []byte - -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 presenterImageInput(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{ - must(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{ - must(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 presenterDirectoryInput(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{ - must(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{ - must(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 -}