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