//go:build integration package integration import ( "path/filepath" "testing" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" ) func TestSBOM(t *testing.T) { type args struct { input string format string artifactType string } tests := []struct { name string args args golden string override types.Report }{ { name: "centos7 cyclonedx", args: args{ input: "testdata/fixtures/sbom/centos-7-cyclonedx.json", format: "json", artifactType: "cyclonedx", }, golden: "testdata/centos-7.json.golden", override: types.Report{ ArtifactName: "testdata/fixtures/sbom/centos-7-cyclonedx.json", ArtifactType: ftypes.ArtifactType("cyclonedx"), Results: types.Results{ { Target: "testdata/fixtures/sbom/centos-7-cyclonedx.json (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ { PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", }, }, { PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", }, }, { PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", }, }, }, }, }, }, }, { name: "fluentd-multiple-lockfiles cyclonedx", args: args{ input: "testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json", format: "json", artifactType: "cyclonedx", }, golden: "testdata/fluentd-multiple-lockfiles.json.golden", }, { name: "minikube KBOM", args: args{ input: "testdata/fixtures/sbom/minikube-kbom.json", format: "json", artifactType: "cyclonedx", }, golden: "testdata/minikube-kbom.json.golden", }, { name: "centos7 in in-toto attestation", args: args{ input: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl", format: "json", artifactType: "cyclonedx", }, golden: "testdata/centos-7.json.golden", override: types.Report{ ArtifactName: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl", ArtifactType: ftypes.ArtifactType("cyclonedx"), Results: types.Results{ { Target: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl (centos 7.6.1810)", Vulnerabilities: []types.DetectedVulnerability{ { PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810", }, }, { PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", }, }, { PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810", }, }, }, }, }, }, }, { name: "centos7 spdx tag-value", args: args{ input: "testdata/fixtures/sbom/centos-7-spdx.txt", format: "json", artifactType: "spdx", }, golden: "testdata/centos-7.json.golden", override: types.Report{ ArtifactName: "testdata/fixtures/sbom/centos-7-spdx.txt", ArtifactType: ftypes.ArtifactType("spdx"), Results: types.Results{ { Target: "testdata/fixtures/sbom/centos-7-spdx.txt (centos 7.6.1810)", }, }, }, }, { name: "centos7 spdx json", args: args{ input: "testdata/fixtures/sbom/centos-7-spdx.json", format: "json", artifactType: "spdx", }, golden: "testdata/centos-7.json.golden", override: types.Report{ ArtifactName: "testdata/fixtures/sbom/centos-7-spdx.json", ArtifactType: ftypes.ArtifactType("spdx"), Results: types.Results{ { Target: "testdata/fixtures/sbom/centos-7-spdx.json (centos 7.6.1810)", }, }, }, }, } // Set up testing DB cacheDir := initDB(t) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { osArgs := []string{ "--cache-dir", cacheDir, "sbom", "-q", "--skip-db-update", "--format", tt.args.format, } // Set up the output file outputFile := filepath.Join(t.TempDir(), "output.json") if *update { outputFile = tt.golden } osArgs = append(osArgs, "--output", outputFile) osArgs = append(osArgs, tt.args.input) // Run "trivy sbom" err := execute(osArgs) assert.NoError(t, err) // Compare want and got switch tt.args.format { case "json": compareSBOMReports(t, tt.golden, outputFile, tt.override) default: require.Fail(t, "invalid format", "format: %s", tt.args.format) } }) } } // TODO(teppei): merge into compareReports func compareSBOMReports(t *testing.T, wantFile, gotFile string, overrideWant types.Report) { want := readReport(t, wantFile) if overrideWant.ArtifactName != "" { want.ArtifactName = overrideWant.ArtifactName } if overrideWant.ArtifactType != "" { want.ArtifactType = overrideWant.ArtifactType } want.Metadata.ImageID = "" want.Metadata.ImageConfig = v1.ConfigFile{} want.Metadata.DiffIDs = nil for i, result := range want.Results { for j := range result.Vulnerabilities { want.Results[i].Vulnerabilities[j].Layer.DiffID = "" } } for i, result := range overrideWant.Results { want.Results[i].Target = result.Target for j, vuln := range result.Vulnerabilities { if vuln.PkgIdentifier.PURL != nil { want.Results[i].Vulnerabilities[j].PkgIdentifier.PURL = vuln.PkgIdentifier.PURL } if vuln.PkgIdentifier.BOMRef != "" { want.Results[i].Vulnerabilities[j].PkgIdentifier.BOMRef = vuln.PkgIdentifier.BOMRef } } } got := readReport(t, gotFile) assert.Equal(t, want, got) }