github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/sbom/cataloger_test.go (about) 1 package sbom 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 8 "github.com/anchore/syft/syft/artifact" 9 "github.com/anchore/syft/syft/cpe" 10 "github.com/anchore/syft/syft/file" 11 "github.com/anchore/syft/syft/formats/syftjson" 12 "github.com/anchore/syft/syft/pkg" 13 "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" 14 "github.com/anchore/syft/syft/sbom" 15 ) 16 17 func mustCPEs(s ...string) (c []cpe.CPE) { 18 for _, i := range s { 19 c = append(c, mustCPE(i)) 20 } 21 return 22 } 23 24 func mustCPE(c string) cpe.CPE { 25 return must(cpe.New(c)) 26 } 27 func must(c cpe.CPE, e error) cpe.CPE { 28 if e != nil { 29 panic(e) 30 } 31 return c 32 } 33 34 func Test_parseSBOM(t *testing.T) { 35 expectedPkgs := []pkg.Package{ 36 { 37 Name: "alpine-baselayout", 38 Version: "3.2.0-r23", 39 Type: "apk", 40 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 41 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 42 FoundBy: "sbom-cataloger", 43 PURL: "pkg:apk/alpine/alpine-baselayout@3.2.0-r23?arch=x86_64&upstream=alpine-baselayout&distro=alpine-3.16.3", 44 CPEs: mustCPEs( 45 "cpe:2.3:a:alpine-baselayout:alpine-baselayout:3.2.0-r23:*:*:*:*:*:*:*", 46 "cpe:2.3:a:alpine-baselayout:alpine_baselayout:3.2.0-r23:*:*:*:*:*:*:*", 47 "cpe:2.3:a:alpine_baselayout:alpine-baselayout:3.2.0-r23:*:*:*:*:*:*:*", 48 "cpe:2.3:a:alpine_baselayout:alpine_baselayout:3.2.0-r23:*:*:*:*:*:*:*", 49 "cpe:2.3:a:alpine:alpine-baselayout:3.2.0-r23:*:*:*:*:*:*:*", 50 "cpe:2.3:a:alpine:alpine_baselayout:3.2.0-r23:*:*:*:*:*:*:*", 51 ), 52 }, 53 { 54 Name: "alpine-baselayout-data", 55 Version: "3.2.0-r23", 56 Type: "apk", 57 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 58 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 59 FoundBy: "sbom-cataloger", 60 PURL: "pkg:apk/alpine/alpine-baselayout-data@3.2.0-r23?arch=x86_64&upstream=alpine-baselayout&distro=alpine-3.16.3", 61 CPEs: mustCPEs( 62 "cpe:2.3:a:alpine-baselayout-data:alpine-baselayout-data:3.2.0-r23:*:*:*:*:*:*:*", 63 "cpe:2.3:a:alpine-baselayout-data:alpine_baselayout_data:3.2.0-r23:*:*:*:*:*:*:*", 64 "cpe:2.3:a:alpine_baselayout_data:alpine-baselayout-data:3.2.0-r23:*:*:*:*:*:*:*", 65 "cpe:2.3:a:alpine_baselayout_data:alpine_baselayout_data:3.2.0-r23:*:*:*:*:*:*:*", 66 "cpe:2.3:a:alpine-baselayout:alpine-baselayout-data:3.2.0-r23:*:*:*:*:*:*:*", 67 "cpe:2.3:a:alpine-baselayout:alpine_baselayout_data:3.2.0-r23:*:*:*:*:*:*:*", 68 "cpe:2.3:a:alpine_baselayout:alpine-baselayout-data:3.2.0-r23:*:*:*:*:*:*:*", 69 "cpe:2.3:a:alpine_baselayout:alpine_baselayout_data:3.2.0-r23:*:*:*:*:*:*:*", 70 "cpe:2.3:a:alpine:alpine-baselayout-data:3.2.0-r23:*:*:*:*:*:*:*", 71 "cpe:2.3:a:alpine:alpine_baselayout_data:3.2.0-r23:*:*:*:*:*:*:*", 72 ), 73 }, 74 { 75 Name: "alpine-keys", 76 Version: "2.4-r1", 77 Type: "apk", 78 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 79 Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")), 80 FoundBy: "sbom-cataloger", 81 PURL: "pkg:apk/alpine/alpine-keys@2.4-r1?arch=x86_64&upstream=alpine-keys&distro=alpine-3.16.3", 82 CPEs: mustCPEs( 83 "cpe:2.3:a:alpine-keys:alpine-keys:2.4-r1:*:*:*:*:*:*:*", 84 "cpe:2.3:a:alpine-keys:alpine_keys:2.4-r1:*:*:*:*:*:*:*", 85 "cpe:2.3:a:alpine_keys:alpine-keys:2.4-r1:*:*:*:*:*:*:*", 86 "cpe:2.3:a:alpine_keys:alpine_keys:2.4-r1:*:*:*:*:*:*:*", 87 "cpe:2.3:a:alpine:alpine-keys:2.4-r1:*:*:*:*:*:*:*", 88 "cpe:2.3:a:alpine:alpine_keys:2.4-r1:*:*:*:*:*:*:*", 89 ), 90 }, 91 { 92 Name: "apk-tools", 93 Version: "2.12.9-r3", 94 Type: "apk", 95 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 96 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 97 FoundBy: "sbom-cataloger", 98 PURL: "pkg:apk/alpine/apk-tools@2.12.9-r3?arch=x86_64&upstream=apk-tools&distro=alpine-3.16.3", 99 CPEs: mustCPEs( 100 "cpe:2.3:a:apk-tools:apk-tools:2.12.9-r3:*:*:*:*:*:*:*", 101 "cpe:2.3:a:apk-tools:apk_tools:2.12.9-r3:*:*:*:*:*:*:*", 102 "cpe:2.3:a:apk_tools:apk-tools:2.12.9-r3:*:*:*:*:*:*:*", 103 "cpe:2.3:a:apk_tools:apk_tools:2.12.9-r3:*:*:*:*:*:*:*", 104 "cpe:2.3:a:apk:apk-tools:2.12.9-r3:*:*:*:*:*:*:*", 105 "cpe:2.3:a:apk:apk_tools:2.12.9-r3:*:*:*:*:*:*:*", 106 ), 107 }, 108 { 109 Name: "busybox", 110 Version: "1.35.0-r17", 111 Type: "apk", 112 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 113 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 114 FoundBy: "sbom-cataloger", 115 PURL: "pkg:apk/alpine/busybox@1.35.0-r17?arch=x86_64&upstream=busybox&distro=alpine-3.16.3", 116 CPEs: mustCPEs( 117 "cpe:2.3:a:busybox:busybox:1.35.0-r17:*:*:*:*:*:*:*", 118 ), 119 }, 120 { 121 Name: "ca-certificates-bundle", 122 Version: "20220614-r0", 123 Type: "apk", 124 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 125 Licenses: pkg.NewLicenseSet( 126 pkg.NewLicense("MPL-2.0"), 127 pkg.NewLicense("MIT"), 128 ), 129 FoundBy: "sbom-cataloger", 130 PURL: "pkg:apk/alpine/ca-certificates-bundle@20220614-r0?arch=x86_64&upstream=ca-certificates&distro=alpine-3.16.3", 131 CPEs: mustCPEs( 132 "cpe:2.3:a:ca-certificates-bundle:ca-certificates-bundle:20220614-r0:*:*:*:*:*:*:*", 133 "cpe:2.3:a:ca-certificates-bundle:ca_certificates_bundle:20220614-r0:*:*:*:*:*:*:*", 134 "cpe:2.3:a:ca_certificates_bundle:ca-certificates-bundle:20220614-r0:*:*:*:*:*:*:*", 135 "cpe:2.3:a:ca_certificates_bundle:ca_certificates_bundle:20220614-r0:*:*:*:*:*:*:*", 136 "cpe:2.3:a:ca-certificates:ca-certificates-bundle:20220614-r0:*:*:*:*:*:*:*", 137 "cpe:2.3:a:ca-certificates:ca_certificates_bundle:20220614-r0:*:*:*:*:*:*:*", 138 "cpe:2.3:a:ca_certificates:ca-certificates-bundle:20220614-r0:*:*:*:*:*:*:*", 139 "cpe:2.3:a:ca_certificates:ca_certificates_bundle:20220614-r0:*:*:*:*:*:*:*", 140 "cpe:2.3:a:ca:ca-certificates-bundle:20220614-r0:*:*:*:*:*:*:*", 141 "cpe:2.3:a:ca:ca_certificates_bundle:20220614-r0:*:*:*:*:*:*:*", 142 ), 143 }, 144 { 145 Name: "libc-utils", 146 Version: "0.7.2-r3", 147 Type: "apk", 148 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 149 Licenses: pkg.NewLicenseSet( 150 pkg.NewLicense("BSD-2-Clause"), 151 pkg.NewLicense("BSD-3-Clause"), 152 ), 153 FoundBy: "sbom-cataloger", 154 PURL: "pkg:apk/alpine/libc-utils@0.7.2-r3?arch=x86_64&upstream=libc-dev&distro=alpine-3.16.3", 155 CPEs: mustCPEs( 156 "cpe:2.3:a:libc-utils:libc-utils:0.7.2-r3:*:*:*:*:*:*:*", 157 "cpe:2.3:a:libc-utils:libc_utils:0.7.2-r3:*:*:*:*:*:*:*", 158 "cpe:2.3:a:libc_utils:libc-utils:0.7.2-r3:*:*:*:*:*:*:*", 159 "cpe:2.3:a:libc_utils:libc_utils:0.7.2-r3:*:*:*:*:*:*:*", 160 "cpe:2.3:a:libc:libc-utils:0.7.2-r3:*:*:*:*:*:*:*", 161 "cpe:2.3:a:libc:libc_utils:0.7.2-r3:*:*:*:*:*:*:*", 162 ), 163 }, 164 { 165 Name: "libcrypto1.1", 166 Version: "1.1.1s-r0", 167 Type: "apk", 168 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 169 Licenses: pkg.NewLicenseSet(pkg.NewLicense("OpenSSL")), // SPDX expression is not set 170 FoundBy: "sbom-cataloger", 171 PURL: "pkg:apk/alpine/libcrypto1.1@1.1.1s-r0?arch=x86_64&upstream=openssl&distro=alpine-3.16.3", 172 CPEs: mustCPEs( 173 "cpe:2.3:a:libcrypto1.1:libcrypto1.1:1.1.1s-r0:*:*:*:*:*:*:*", 174 ), 175 }, 176 { 177 Name: "libssl1.1", 178 Version: "1.1.1s-r0", 179 Type: "apk", 180 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 181 Licenses: pkg.NewLicenseSet(pkg.NewLicense("OpenSSL")), // SPDX expression is not set 182 FoundBy: "sbom-cataloger", 183 PURL: "pkg:apk/alpine/libssl1.1@1.1.1s-r0?arch=x86_64&upstream=openssl&distro=alpine-3.16.3", 184 CPEs: mustCPEs( 185 "cpe:2.3:a:libssl1.1:libssl1.1:1.1.1s-r0:*:*:*:*:*:*:*", 186 ), 187 }, 188 { 189 Name: "musl", 190 Version: "1.2.3-r1", 191 Type: "apk", 192 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 193 Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")), // SPDX expression is not set 194 FoundBy: "sbom-cataloger", 195 PURL: "pkg:apk/alpine/musl@1.2.3-r1?arch=x86_64&upstream=musl&distro=alpine-3.16.3", 196 CPEs: mustCPEs( 197 "cpe:2.3:a:musl:musl:1.2.3-r1:*:*:*:*:*:*:*", 198 ), 199 }, 200 { 201 Name: "musl-utils", 202 Version: "1.2.3-r1", 203 Type: "apk", 204 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 205 Licenses: pkg.NewLicenseSet( 206 pkg.NewLicense("MIT"), 207 pkg.NewLicense("BSD"), 208 pkg.NewLicense("GPL2+"), // SPDX expression is not set 209 ), 210 FoundBy: "sbom-cataloger", 211 PURL: "pkg:apk/alpine/musl-utils@1.2.3-r1?arch=x86_64&upstream=musl&distro=alpine-3.16.3", 212 CPEs: mustCPEs( 213 "cpe:2.3:a:musl-utils:musl-utils:1.2.3-r1:*:*:*:*:*:*:*", 214 "cpe:2.3:a:musl-utils:musl_utils:1.2.3-r1:*:*:*:*:*:*:*", 215 "cpe:2.3:a:musl_utils:musl-utils:1.2.3-r1:*:*:*:*:*:*:*", 216 "cpe:2.3:a:musl_utils:musl_utils:1.2.3-r1:*:*:*:*:*:*:*", 217 "cpe:2.3:a:musl:musl-utils:1.2.3-r1:*:*:*:*:*:*:*", 218 "cpe:2.3:a:musl:musl_utils:1.2.3-r1:*:*:*:*:*:*:*", 219 ), 220 }, 221 { 222 Name: "scanelf", 223 Version: "1.3.4-r0", 224 Type: "apk", 225 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 226 Licenses: pkg.NewLicenseSet( 227 pkg.NewLicense("GPL-2.0-only"), 228 ), 229 FoundBy: "sbom-cataloger", 230 PURL: "pkg:apk/alpine/scanelf@1.3.4-r0?arch=x86_64&upstream=pax-utils&distro=alpine-3.16.3", 231 CPEs: mustCPEs( 232 "cpe:2.3:a:scanelf:scanelf:1.3.4-r0:*:*:*:*:*:*:*", 233 ), 234 }, 235 { 236 Name: "ssl_client", 237 Version: "1.35.0-r17", 238 Type: "apk", 239 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 240 Licenses: pkg.NewLicenseSet( 241 pkg.NewLicense("GPL-2.0-only"), 242 ), 243 FoundBy: "sbom-cataloger", 244 PURL: "pkg:apk/alpine/ssl_client@1.35.0-r17?arch=x86_64&upstream=busybox&distro=alpine-3.16.3", 245 CPEs: mustCPEs( 246 "cpe:2.3:a:ssl-client:ssl-client:1.35.0-r17:*:*:*:*:*:*:*", 247 "cpe:2.3:a:ssl-client:ssl_client:1.35.0-r17:*:*:*:*:*:*:*", 248 "cpe:2.3:a:ssl_client:ssl-client:1.35.0-r17:*:*:*:*:*:*:*", 249 "cpe:2.3:a:ssl_client:ssl_client:1.35.0-r17:*:*:*:*:*:*:*", 250 "cpe:2.3:a:ssl:ssl-client:1.35.0-r17:*:*:*:*:*:*:*", 251 "cpe:2.3:a:ssl:ssl_client:1.35.0-r17:*:*:*:*:*:*:*", 252 ), 253 }, 254 { 255 Name: "zlib", 256 Version: "1.2.12-r3", 257 Type: "apk", 258 Locations: file.NewLocationSet(file.NewLocation("sbom.syft.json")), 259 Licenses: pkg.NewLicenseSet( 260 pkg.NewLicense("Zlib"), 261 ), 262 FoundBy: "sbom-cataloger", 263 PURL: "pkg:apk/alpine/zlib@1.2.12-r3?arch=x86_64&upstream=zlib&distro=alpine-3.16.3", 264 CPEs: mustCPEs( 265 "cpe:2.3:a:zlib:zlib:1.2.12-r3:*:*:*:*:*:*:*", 266 ), 267 }, 268 } 269 270 apkgdbLocation := file.NewLocationSet(file.Location{ 271 LocationData: file.LocationData{ 272 Coordinates: file.Coordinates{ 273 RealPath: "/lib/apk/db/installed", 274 FileSystemID: "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd", 275 }, 276 }, 277 }) 278 279 libSSL := pkg.Package{ 280 Name: "libssl1.1", 281 Version: "1.1.1s-r0", 282 Type: "apk", 283 Locations: apkgdbLocation, 284 Licenses: pkg.NewLicenseSet(pkg.NewLicense("OpenSSL")), 285 FoundBy: "apkdb-cataloger", 286 PURL: "pkg:apk/alpine/libssl1.1@1.1.1s-r0?arch=x86_64&upstream=openssl&distro=alpine-3.16.3", 287 CPEs: mustCPEs( 288 "cpe:2.3:a:libssl1.1:libssl1.1:1.1.1s-r0:*:*:*:*:*:*:*", 289 ), 290 } 291 292 sslClient := pkg.Package{ 293 Name: "ssl_client", 294 Version: "1.35.0-r17", 295 Type: "apk", 296 Locations: apkgdbLocation, 297 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 298 FoundBy: "apkdb-cataloger", 299 PURL: "pkg:apk/alpine/ssl_client@1.35.0-r17?arch=x86_64&upstream=busybox&distro=alpine-3.16.3", 300 CPEs: mustCPEs( 301 "cpe:2.3:a:ssl-client:ssl-client:1.35.0-r17:*:*:*:*:*:*:*", 302 "cpe:2.3:a:ssl-client:ssl_client:1.35.0-r17:*:*:*:*:*:*:*", 303 "cpe:2.3:a:ssl_client:ssl-client:1.35.0-r17:*:*:*:*:*:*:*", 304 "cpe:2.3:a:ssl_client:ssl_client:1.35.0-r17:*:*:*:*:*:*:*", 305 "cpe:2.3:a:ssl:ssl-client:1.35.0-r17:*:*:*:*:*:*:*", 306 "cpe:2.3:a:ssl:ssl_client:1.35.0-r17:*:*:*:*:*:*:*", 307 ), 308 } 309 310 baseLayout := pkg.Package{ 311 Name: "alpine-baselayout", 312 Version: "3.2.0-r23", 313 Type: "apk", 314 Locations: apkgdbLocation, 315 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 316 FoundBy: "apkdb-cataloger", 317 PURL: "pkg:apk/alpine/alpine-baselayout@3.2.0-r23?arch=x86_64&upstream=alpine-baselayout&distro=alpine-3.16.3", 318 CPEs: mustCPEs( 319 "cpe:2.3:a:alpine-baselayout:alpine-baselayout:3.2.0-r23:*:*:*:*:*:*:*", 320 "cpe:2.3:a:alpine-baselayout:alpine_baselayout:3.2.0-r23:*:*:*:*:*:*:*", 321 "cpe:2.3:a:alpine_baselayout:alpine-baselayout:3.2.0-r23:*:*:*:*:*:*:*", 322 "cpe:2.3:a:alpine_baselayout:alpine_baselayout:3.2.0-r23:*:*:*:*:*:*:*", 323 "cpe:2.3:a:alpine:alpine-baselayout:3.2.0-r23:*:*:*:*:*:*:*", 324 "cpe:2.3:a:alpine:alpine_baselayout:3.2.0-r23:*:*:*:*:*:*:*", 325 ), 326 } 327 328 busybox := pkg.Package{ 329 Name: "busybox", 330 Version: "1.35.0-r17", 331 Type: "apk", 332 Locations: apkgdbLocation, 333 Licenses: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0-only")), 334 FoundBy: "apkdb-cataloger", 335 PURL: "pkg:apk/alpine/busybox@1.35.0-r17?arch=x86_64&upstream=busybox&distro=alpine-3.16.3", 336 CPEs: mustCPEs( 337 "cpe:2.3:a:busybox:busybox:1.35.0-r17:*:*:*:*:*:*:*", 338 ), 339 } 340 341 musl := pkg.Package{ 342 Name: "musl", 343 Version: "1.2.3-r1", 344 Type: "apk", 345 Locations: apkgdbLocation, 346 Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")), 347 FoundBy: "apkdb-cataloger", 348 PURL: "pkg:apk/alpine/musl@1.2.3-r1?arch=x86_64&upstream=musl&distro=alpine-3.16.3", 349 CPEs: mustCPEs( 350 "cpe:2.3:a:musl:musl:1.2.3-r1:*:*:*:*:*:*:*", 351 ), 352 } 353 354 expectedRelationships := []artifact.Relationship{ 355 { 356 From: libSSL, 357 To: sslClient, 358 Type: artifact.DependencyOfRelationship, 359 }, 360 { 361 From: libSSL, 362 To: file.Coordinates{ 363 RealPath: "/lib/libssl.so.1.1", 364 FileSystemID: "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd", 365 }, 366 Type: artifact.ContainsRelationship, 367 }, 368 { 369 From: busybox, 370 To: baseLayout, 371 Type: artifact.DependencyOfRelationship, 372 }, 373 { 374 From: baseLayout, 375 To: file.Coordinates{ 376 RealPath: "/etc/profile.d/color_prompt.sh.disabled", 377 FileSystemID: "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd", 378 }, 379 Type: artifact.ContainsRelationship, 380 }, 381 { 382 From: baseLayout, 383 To: file.Coordinates{ 384 RealPath: "/etc/modprobe.d/kms.conf", 385 FileSystemID: "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd", 386 }, 387 Type: artifact.ContainsRelationship, 388 }, 389 { 390 From: musl, 391 To: libSSL, 392 Type: artifact.DependencyOfRelationship, 393 }, 394 } 395 396 for _, p := range expectedPkgs { 397 expectedRelationships = append(expectedRelationships, artifact.Relationship{ 398 From: p, 399 To: file.Coordinates{ 400 RealPath: "sbom.syft.json", 401 }, 402 Type: artifact.DescribedByRelationship, 403 }) 404 } 405 406 tests := []struct { 407 name string 408 format sbom.Format 409 fixture string 410 wantPkgs []pkg.Package 411 wantRelationships []artifact.Relationship 412 wantErr require.ErrorAssertionFunc 413 }{ 414 { 415 name: "parse syft JSON", 416 format: syftjson.Format(), 417 fixture: "test-fixtures/alpine/syft-json", 418 wantPkgs: expectedPkgs, 419 wantRelationships: expectedRelationships, 420 }, 421 } 422 for _, tt := range tests { 423 t.Run(tt.name, func(t *testing.T) { 424 pkgtest.NewCatalogTester(). 425 FromDirectory(t, tt.fixture). 426 IgnorePackageFields("Metadata", "MetadataType"). 427 Expects(tt.wantPkgs, tt.wantRelationships). 428 TestCataloger(t, NewSBOMCataloger()) 429 }) 430 } 431 } 432 433 func Test_Cataloger_Globs(t *testing.T) { 434 tests := []struct { 435 name string 436 fixture string 437 expected []string 438 }{ 439 { 440 name: "obtain sbom files", 441 fixture: "test-fixtures/glob-paths", 442 expected: []string{ 443 "bom", 444 "sbom", 445 "app.syft.json", 446 "app.bom", 447 "app.sbom", 448 "app.cdx", 449 "app.spdx", 450 "app.bom.json", 451 "app.sbom.json", 452 "app.cdx.json", 453 "app.spdx.json", 454 }, 455 }, 456 } 457 458 for _, test := range tests { 459 t.Run(test.name, func(t *testing.T) { 460 pkgtest.NewCatalogTester(). 461 FromDirectory(t, test.fixture). 462 ExpectsResolverContentQueries(test.expected). 463 TestCataloger(t, NewSBOMCataloger()) 464 }) 465 } 466 }