github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/pkg/cataloger/sbom/cataloger_test.go (about)

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