Skip to content

Commit

Permalink
test: replace usage of cyclonedx-cli with internal schema validation
Browse files Browse the repository at this point in the history
The functionality is only available in tests and not exposed as part of the public API. This is mostly due to the fact that XML validation is based on `libxml2`, thus requiring CGO.

Signed-off-by: nscuro <nscuro@protonmail.com>
  • Loading branch information
nscuro committed Jun 18, 2023
1 parent 6c4af62 commit ff2e673
Show file tree
Hide file tree
Showing 25 changed files with 15,927 additions and 67 deletions.
7 changes: 0 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,6 @@ jobs:
with:
go-version: ${{ matrix.go }}
check-latest: true
- name: Setup CycloneDX CLI
run: |
mkdir -p "$HOME/.local/bin"
echo "$HOME/.local/bin" >> $GITHUB_PATH
wget -O "$HOME/.local/bin/cyclonedx" https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.24.2/cyclonedx-linux-x64
echo "ef0d3b31d176e02bc594f83e19cfcea053c6bc5b197351f71696e189390f851d $HOME/.local/bin/cyclonedx" | sha256sum -c
chmod +x "$HOME/.local/bin/cyclonedx"
- name: Checkout Repository
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # tag=v3.5.3
- name: Test
Expand Down
3 changes: 2 additions & 1 deletion .licenserc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ header:
- "LICENSE"
- "Makefile"
- "NOTICE"
- "cyclonedx_string.go"
- "cyclonedx_string.go"
- "schema/**"
9 changes: 0 additions & 9 deletions Dockerfile.gitpod
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,3 @@
# Copyright (c) OWASP Foundation. All Rights Reserved.

FROM gitpod/workspace-go:latest@sha256:d7a41f5f2a24f093cee1791f154e173a51359db19204a67c64ace06be65c0a2f

USER root

RUN \
wget -O "/usr/local/bin/cyclonedx" https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.24.2/cyclonedx-linux-x64 && \
echo "ef0d3b31d176e02bc594f83e19cfcea053c6bc5b197351f71696e189390f851d /usr/local/bin/cyclonedx" | sha256sum -c && \
chmod +x "/usr/local/bin/cyclonedx"

USER gitpod
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,3 @@ Pull requests are welcome. But please read the

It is generally expected that pull requests will include relevant tests. Tests are automatically run against all
supported Go versions (see [Compatibility](#compatibility)) for every pull request.

### Running Tests

Some tests make use of the [CycloneDX CLI](https://github.com/CycloneDX/cyclonedx-cli), e.g. to validate BOMs.
Make sure to download the CLI binary and make it available as `cyclonedx` in your `$PATH`.
This is done automatically for [Gitpod](https://gitpod.io/#https://github.com/CycloneDX/cyclonedx-go).
22 changes: 8 additions & 14 deletions cyclonedx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
package cyclonedx

import (
"fmt"
"os/exec"
"strings"
"testing"

"github.com/bradleyjkemp/cupaloy/v2"
Expand Down Expand Up @@ -60,16 +57,13 @@ func TestVulnerability_Properties(t *testing.T) {
assert.Equal(t, 0, len(*vuln.Properties))
}

func assertValidBOM(t *testing.T, bomFilePath string, version SpecVersion) {
inputFormat := "xml"
if strings.HasSuffix(bomFilePath, ".json") {
inputFormat = "json"
}
inputVersion := fmt.Sprintf("v%s", strings.ReplaceAll(version.String(), ".", "_"))
valCmd := exec.Command("cyclonedx", "validate", "--input-file", bomFilePath, "--input-format", inputFormat, "--input-version", inputVersion, "--fail-on-errors")
valOut, err := valCmd.CombinedOutput()
if !assert.NoError(t, err) {
// Provide some context when test is failing
fmt.Printf("validation error: %s\n", string(valOut))
func assertValidBOM(t *testing.T, bomBytes []byte, format BOMFileFormat, version SpecVersion) {
var v validator
if format == BOMFileFormatJSON {
v = newJSONValidator()
} else {
v = newXMLValidator()
}
err := v.Validate(bomBytes, version)
require.NoError(t, err)
}
21 changes: 6 additions & 15 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -198,21 +197,17 @@ func TestJsonBOMEncoder_EncodeVersion(t *testing.T) {
require.NoError(t, NewBOMDecoder(inputFile, BOMFileFormatJSON).Decode(&bom))
inputFile.Close()

// Prepare encoding destinations
// Prepare encoding destination
buf := bytes.Buffer{}
outputFilePath := filepath.Join(t.TempDir(), "bom.json")
outputFile, err := os.Create(outputFilePath)
require.NoError(t, err)

// Encode BOM again, for a specific version
err = NewBOMEncoder(io.MultiWriter(&buf, outputFile), BOMFileFormatJSON).
err = NewBOMEncoder(&buf, BOMFileFormatJSON).
SetPretty(true).
EncodeVersion(&bom, version)
require.NoError(t, err)
outputFile.Close() // Required for CLI to be able to access the file

// Sanity checks: BOM has to be valid
assertValidBOM(t, outputFilePath, version)
assertValidBOM(t, buf.Bytes(), BOMFileFormatJSON, version)

// Compare with snapshot
require.NoError(t, snapShooter.SnapshotMulti(fmt.Sprintf("%s.bom.json", version), buf.String()))
Expand All @@ -232,24 +227,20 @@ func TestXmlBOMEncoder_EncodeVersion(t *testing.T) {
require.NoError(t, NewBOMDecoder(inputFile, BOMFileFormatXML).Decode(&bom))
inputFile.Close()

// Prepare encoding destinations
// Prepare encoding destination
buf := bytes.Buffer{}
outputFilePath := filepath.Join(t.TempDir(), "bom.xml")
outputFile, err := os.Create(outputFilePath)
require.NoError(t, err)

// Encode BOM again
err = NewBOMEncoder(io.MultiWriter(&buf, outputFile), BOMFileFormatXML).
err = NewBOMEncoder(&buf, BOMFileFormatXML).
SetPretty(true).
EncodeVersion(&bom, version)
require.NoError(t, err)
outputFile.Close() // Required for CLI to be able to access the file

// Sanity checks: BOM has to be valid
require.NoError(t, snapShooter.SnapshotMulti(fmt.Sprintf("%s.bom.xml", version), buf.String()))

// Compare with snapshot
assertValidBOM(t, outputFilePath, version)
assertValidBOM(t, buf.Bytes(), BOMFileFormatXML, version)
})
}
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ go 1.17
require (
github.com/bradleyjkemp/cupaloy/v2 v2.8.0
github.com/stretchr/testify v1.8.4
github.com/terminalstatic/go-xsd-validate v0.1.5
github.com/xeipuuv/gojsonschema v1.2.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo=
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
21 changes: 6 additions & 15 deletions roundtrip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package cyclonedx

import (
"bytes"
"io"
"os"
"path/filepath"
"testing"
Expand All @@ -43,21 +42,17 @@ func TestRoundTripJSON(t *testing.T) {
require.NoError(t, NewBOMDecoder(inputFile, BOMFileFormatJSON).Decode(&bom))
inputFile.Close()

// Prepare encoding destinations
// Prepare encoding destination
buf := bytes.Buffer{}
outputFilePath := filepath.Join(t.TempDir(), "bom.json")
outputFile, err := os.Create(outputFilePath)
require.NoError(t, err)

// Encode BOM again
err = NewBOMEncoder(io.MultiWriter(&buf, outputFile), BOMFileFormatJSON).
err = NewBOMEncoder(&buf, BOMFileFormatJSON).
SetPretty(true).
Encode(&bom)
require.NoError(t, err)
outputFile.Close() // Required for CLI to be able to access the file

// Sanity checks: BOM has to be valid
assertValidBOM(t, outputFilePath, SpecVersion1_4)
assertValidBOM(t, buf.Bytes(), BOMFileFormatJSON, SpecVersion1_4)

// Compare with snapshot
assert.NoError(t, snapShooter.SnapshotMulti(filepath.Base(bomFilePath), buf.String()))
Expand All @@ -80,21 +75,17 @@ func TestRoundTripXML(t *testing.T) {
require.NoError(t, NewBOMDecoder(inputFile, BOMFileFormatXML).Decode(&bom))
inputFile.Close()

// Prepare encoding destinations
// Prepare encoding destination
buf := bytes.Buffer{}
outputFilePath := filepath.Join(t.TempDir(), "bom.xml")
outputFile, err := os.Create(outputFilePath)
require.NoError(t, err)

// Encode BOM again
err = NewBOMEncoder(io.MultiWriter(&buf, outputFile), BOMFileFormatXML).
err = NewBOMEncoder(&buf, BOMFileFormatXML).
SetPretty(true).
Encode(&bom)
require.NoError(t, err)
outputFile.Close() // Required for CLI to be able to access the file

// Sanity check: BOM has to be valid
assertValidBOM(t, outputFilePath, SpecVersion1_4)
assertValidBOM(t, buf.Bytes(), BOMFileFormatXML, SpecVersion1_4)

// Compare with snapshot
assert.NoError(t, snapShooter.SnapshotMulti(filepath.Base(bomFilePath), buf.String()))
Expand Down
Loading

0 comments on commit ff2e673

Please sign in to comment.