test: validate CycloneDX with the JSON schema (#4956)

* test: validate CycloneDX with the JSON schema

* fix(sbom): move licenses to `name` field in Cyclonedx format (#4941)

* use license.Name instead of Expression

* update tests

* test: add uuid package

* test: compare UUID

---------

Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
This commit is contained in:
Teppei Fukuda
2023-08-08 15:51:10 +03:00
committed by GitHub
parent 798ef1b64a
commit d3a34e409c
16 changed files with 6970 additions and 173 deletions

View File

@@ -11,18 +11,20 @@ import (
"os"
"path/filepath"
"sort"
"strings"
"testing"
"time"
cdx "github.com/CycloneDX/cyclonedx-go"
"github.com/samber/lo"
spdxjson "github.com/spdx/tools-golang/json"
"github.com/spdx/tools-golang/spdx"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/xeipuuv/gojsonschema"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy-db/pkg/metadata"
"github.com/aquasecurity/trivy/pkg/commands"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/types"
@@ -138,10 +140,7 @@ func readCycloneDX(t *testing.T, filePath string) *cdx.BOM {
err = decoder.Decode(bom)
require.NoError(t, err)
// We don't compare values which change each time an SBOM is generated
bom.Metadata.Timestamp = ""
bom.Metadata.Component.BOMRef = ""
bom.SerialNumber = ""
// Sort components
if bom.Components != nil {
sort.Slice(*bom.Components, func(i, j int) bool {
return (*bom.Components)[i].Name < (*bom.Components)[j].Name
@@ -153,12 +152,6 @@ func readCycloneDX(t *testing.T, filePath string) *cdx.BOM {
})
}
}
if bom.Dependencies != nil {
for j := range *bom.Dependencies {
(*bom.Dependencies)[j].Ref = ""
(*bom.Dependencies)[j].Dependencies = nil
}
}
return bom
}
@@ -212,6 +205,20 @@ func compareCycloneDX(t *testing.T, wantFile, gotFile string) {
want := readCycloneDX(t, wantFile)
got := readCycloneDX(t, gotFile)
assert.Equal(t, want, got)
// Validate CycloneDX output against the JSON schema
schemaLoader := gojsonschema.NewReferenceLoader(got.JSONSchema)
documentLoader := gojsonschema.NewGoLoader(got)
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
require.NoError(t, err)
if valid := result.Valid(); !valid {
errs := lo.Map(result.Errors(), func(err gojsonschema.ResultError, _ int) string {
return err.String()
})
assert.True(t, valid, strings.Join(errs, "\n"))
}
}
func compareSpdxJson(t *testing.T, wantFile, gotFile string) {