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  }