github.com/anchore/syft@v1.38.2/syft/format/internal/testutil/image_input.go (about) 1 package testutil 2 3 import ( 4 "context" 5 "os" 6 "path/filepath" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/anchore/stereoscope/pkg/filetree" 12 "github.com/anchore/stereoscope/pkg/image" 13 "github.com/anchore/stereoscope/pkg/imagetest" 14 "github.com/anchore/syft/syft/cpe" 15 "github.com/anchore/syft/syft/file" 16 "github.com/anchore/syft/syft/linux" 17 "github.com/anchore/syft/syft/pkg" 18 "github.com/anchore/syft/syft/sbom" 19 "github.com/anchore/syft/syft/source/stereoscopesource" 20 ) 21 22 func ImageInput(t testing.TB, testImage string, options ...ImageOption) sbom.SBOM { 23 t.Helper() 24 catalog := pkg.NewCollection() 25 var cfg imageCfg 26 var img *image.Image 27 for _, opt := range options { 28 opt(&cfg) 29 } 30 31 defer changeToDirectoryWithGoldenFixture(t, testImage)() 32 33 switch cfg.fromSnapshot { 34 case true: 35 img = imagetest.GetGoldenFixtureImage(t, testImage) 36 default: 37 img = imagetest.GetFixtureImage(t, "docker-archive", testImage) 38 } 39 40 populateImageCatalog(catalog, img) 41 42 // this is a hard coded value that is not given by the fixture helper and must be provided manually 43 img.Metadata.ManifestDigest = "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368" 44 45 src := stereoscopesource.New(img, stereoscopesource.ImageConfig{ 46 Reference: "user-image-input", 47 }) 48 49 return sbom.SBOM{ 50 Artifacts: sbom.Artifacts{ 51 Packages: catalog, 52 LinuxDistribution: &linux.Release{ 53 PrettyName: "debian", 54 Name: "debian", 55 ID: "debian", 56 IDLike: []string{"like!"}, 57 Version: "1.2.3", 58 VersionID: "1.2.3", 59 }, 60 }, 61 Source: src.Describe(), 62 Descriptor: sbom.Descriptor{ 63 Name: "syft", 64 Version: "v0.42.0-bogus", 65 // the application configuration should be persisted here, however, we do not want to import 66 // the application configuration in this package (it's reserved only for ingestion by the cmd package) 67 Configuration: map[string]string{ 68 "config-key": "config-value", 69 }, 70 }, 71 } 72 } 73 74 func changeToDirectoryWithGoldenFixture(t testing.TB, testImage string) func() { 75 // check if test fixture exists... if not, check if there is a shared fixture relative to this dir 76 fn := func() {} 77 78 path := filepath.Join("test-fixtures", testImage) 79 if _, err := os.Stat(path); err != nil { 80 // change dir, restore as defer 81 wd, err := os.Getwd() 82 require.NoError(t, err) 83 fn = func() { 84 require.NoError(t, os.Chdir(wd)) 85 } 86 87 // change dir to the testutil dir 88 require.NoError(t, os.Chdir(filepath.Join(wd, "..", "internal", "testutil"))) 89 t.Cleanup(fn) 90 91 if _, err := os.Stat(path); err != nil { 92 t.Fatalf("unable to find test fixture: %s", path) 93 } 94 } 95 return fn 96 } 97 98 func populateImageCatalog(catalog *pkg.Collection, img *image.Image) { 99 // TODO: this helper function is coupled to the image-simple fixture, which seems like a bad idea 100 _, ref1, _ := img.SquashedTree().File("/somefile-1.txt", filetree.FollowBasenameLinks) 101 _, ref2, _ := img.SquashedTree().File("/somefile-2.txt", filetree.FollowBasenameLinks) 102 ctx := context.TODO() 103 // populate catalog with test data 104 if ref1 != nil { 105 catalog.Add(pkg.Package{ 106 Name: "package-1", 107 Version: "1.0.1", 108 Locations: file.NewLocationSet( 109 file.NewLocationFromImage(string(ref1.RealPath), *ref1.Reference, img), 110 ), 111 Type: pkg.PythonPkg, 112 FoundBy: "the-cataloger-1", 113 Language: pkg.Python, 114 Licenses: pkg.NewLicenseSet( 115 pkg.NewLicenseWithContext(ctx, "MIT"), 116 ), 117 Metadata: pkg.PythonPackage{ 118 Name: "package-1", 119 Version: "1.0.1", 120 }, 121 PURL: "a-purl-1", // intentionally a bad pURL for test fixtures 122 CPEs: []cpe.CPE{ 123 cpe.Must("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*", cpe.GeneratedSource), 124 }, 125 }) 126 } 127 128 if ref2 != nil { 129 catalog.Add(pkg.Package{ 130 Name: "package-2", 131 Version: "2.0.1", 132 Locations: file.NewLocationSet( 133 file.NewLocationFromImage(string(ref2.RealPath), *ref2.Reference, img), 134 ), 135 Type: pkg.DebPkg, 136 FoundBy: "the-cataloger-2", 137 Metadata: pkg.DpkgDBEntry{ 138 Package: "package-2", 139 Version: "2.0.1", 140 }, 141 PURL: "pkg:deb/debian/package-2@2.0.1", 142 CPEs: []cpe.CPE{ 143 cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), 144 }, 145 }) 146 } 147 }