Files
syft/syft/format/common/cyclonedxhelpers/licenses_test.go
T
Alex Goodman 7392d607b6 Split the sbom.Format interface by encode and decode use cases (#2186)
* split up sbom.Format into encode and decode ops

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update cmd pkg to inject format configs

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* bump cyclonedx schema to 1.5

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* redact image metadata from github encoder tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add more testing around format decoder identify

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add test case for format version options

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix cli tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix CLI test

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* [wip] - review comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* keep encoder creation out of post load function

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* keep decider and identify functions

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add a few more doc comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove format encoder default function helpers

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address PR feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* move back to streaming based decode functions

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* with common convention for encoder constructors

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix tests and allow for encoders to be created from cli options

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix cli tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix linting

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* buffer reads from stdin to support seeking

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2023-10-25 13:43:06 +00:00

278 lines
6.1 KiB
Go

package cyclonedxhelpers
import (
"testing"
"github.com/CycloneDX/cyclonedx-go"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/license"
"github.com/anchore/syft/syft/pkg"
)
func Test_encodeLicense(t *testing.T) {
tests := []struct {
name string
input pkg.Package
expected *cyclonedx.Licenses
}{
{
name: "no licenses",
input: pkg.Package{},
},
{
name: "no SPDX licenses",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicense("RandomLicense"),
),
},
expected: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
Name: "RandomLicense",
},
},
},
},
{
name: "single SPDX ID and Non SPDX ID",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicense("mit"),
pkg.NewLicense("FOOBAR"),
),
},
expected: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
ID: "MIT",
},
},
{
License: &cyclonedx.License{
Name: "FOOBAR",
},
},
},
},
{
name: "with complex SPDX license expression",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicense("MIT AND GPL-3.0-only"),
),
},
expected: &cyclonedx.Licenses{
{
Expression: "MIT AND GPL-3.0-only",
},
},
},
{
name: "with multiple complex SPDX license expression",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicense("MIT AND GPL-3.0-only"),
pkg.NewLicense("MIT AND GPL-3.0-only WITH Classpath-exception-2.0"),
),
},
expected: &cyclonedx.Licenses{
{
Expression: "(MIT AND GPL-3.0-only) AND (MIT AND GPL-3.0-only WITH Classpath-exception-2.0)",
},
},
},
{
name: "with multiple URLs and expressions",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromURLs("MIT", "https://opensource.org/licenses/MIT", "https://spdx.org/licenses/MIT.html"),
pkg.NewLicense("MIT AND GPL-3.0-only"),
pkg.NewLicenseFromURLs("FakeLicense", "htts://someurl.com"),
),
},
expected: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
ID: "MIT",
URL: "https://opensource.org/licenses/MIT",
},
},
{
License: &cyclonedx.License{
ID: "MIT",
URL: "https://spdx.org/licenses/MIT.html",
},
},
{
License: &cyclonedx.License{
Name: "FakeLicense",
URL: "htts://someurl.com",
},
},
{
License: &cyclonedx.License{
Name: "MIT AND GPL-3.0-only",
},
},
},
},
{
name: "with multiple values licenses are deduplicated",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicense("Apache-2"),
pkg.NewLicense("Apache-2.0"),
),
},
expected: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
ID: "Apache-2.0",
},
},
},
},
{
name: "with multiple URLs and single with no URLs",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicense("MIT"),
pkg.NewLicenseFromURLs("MIT", "https://opensource.org/licenses/MIT", "https://spdx.org/licenses/MIT.html"),
pkg.NewLicense("MIT AND GPL-3.0-only"),
),
},
expected: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
ID: "MIT",
URL: "https://opensource.org/licenses/MIT",
},
},
{
License: &cyclonedx.License{
ID: "MIT",
URL: "https://spdx.org/licenses/MIT.html",
},
},
{
License: &cyclonedx.License{
Name: "MIT AND GPL-3.0-only",
},
},
},
},
// TODO: do we drop the non SPDX ID license and do a single expression
// OR do we keep the non SPDX ID license and do multiple licenses where the complex
// expressions are set as the NAME field?
//{
// name: "with multiple complex SPDX license expression and a non spdx id",
// input: pkg.Package{
// Licenses: []pkg.License{
// {
// SPDXExpression: "MIT AND GPL-3.0-only",
// },
// {
// SPDXExpression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
// },
// {
// Value: "FOOBAR",
// },
// },
// },
// expected: &cyclonedx.Licenses{
// {
// Expression: "(MIT AND GPL-3.0-only) AND (MIT AND GPL-3.0-only WITH Classpath-exception-2.0)",
// },
// },
//},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if d := cmp.Diff(test.expected, encodeLicenses(test.input)); d != "" {
t.Errorf("unexpected license (-want +got):\n%s", d)
}
})
}
}
func TestDecodeLicenses(t *testing.T) {
tests := []struct {
name string
input *cyclonedx.Component
expected []pkg.License
}{
{
name: "no licenses",
input: &cyclonedx.Component{},
expected: []pkg.License{},
},
{
name: "no SPDX license ID or expression",
input: &cyclonedx.Component{
Licenses: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
Name: "RandomLicense",
},
},
},
},
expected: []pkg.License{
{
Value: "RandomLicense",
// CycloneDX specification doesn't give a field for determining the license type
Type: license.Declared,
URLs: []string{},
},
},
},
{
name: "with SPDX license ID",
input: &cyclonedx.Component{
Licenses: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
ID: "MIT",
},
},
},
},
expected: []pkg.License{
{
Value: "MIT",
SPDXExpression: "MIT",
Type: license.Declared,
URLs: []string{},
},
},
},
{
name: "with complex SPDX license expression",
input: &cyclonedx.Component{
Licenses: &cyclonedx.Licenses{
{
License: &cyclonedx.License{},
Expression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
},
},
},
expected: []pkg.License{
{
Value: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
SPDXExpression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
Type: license.Declared,
URLs: []string{},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, test.expected, decodeLicenses(test.input))
})
}
}