Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unittest and fuzzing test for SBOM Conversion #13

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Unit Tests and Fuzzing Tests

on:
pull_request:
branches:
- main

push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.21.0

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 16.x

- name: Build bootstrap
run: make bootstrap

- name: Build upstream-protobom
run: make upstream-protobom

- name: Copy goreleaser.yaml
run: cp .goreleaser.yaml ./.tmp/goreleaser.yaml

- name: Build binary
run: make binary

- name: Run unit tests
run: make unittest

# - name: Run fuzzing tests
# run: make fuzztest
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@ upstream-protobom: ## Upstream protobom library

.PHONY: unittest
unittest: ## Run unittests
go test -count=1 -v ./...

go test -count=1 -v ./... -run='^(Test[^F])' -args -max_test_count=100 -test_spdx_keyvalue=false -test_spdx_json=true -test_cdx_json=true

.PHONY: fuzztest
fuzztest: ## Run fuzzing tests
go test --fuzz=Fuzz pkg/convert/convert_fuzzing_test.go -args -seed_input=fuzz_seed_spdx.json
38 changes: 38 additions & 0 deletions pkg/convert/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Unit and Fuzz Testing for SBOM Conversion

This repository contains a Go unit test file aimed at evaluating the accuracy and integrity of the Software Bill of Materials (SBOM) conversion process. It ensures that the SBOM conversion maintains specific properties and is error-free.

## How it Functions

This unit test file operates through the following steps to validate SBOM conversion:

1. **Unit Test**:
- Automatically Download our shared [SBOM dataset](https://drive.google.com/file/d/1LgGlq3g_H02mhzkc94cUd0zzxy0JhFim/view?usp=sharing), comprising 10,494 SBOM files in both SPDX and CycloneDX formats.
- Utilize the sbom-convert tool for converting SBOMs from one format to another.
- Verify that the sbom-convert tool does not encounter any errors.
- Compare the counts of PURLs in the original and converted SBOMs.
- Compare the counts of licenses in the original and converted SBOMs.

2. **Fuzzing Test**:
- The fuzzer takes seed inputs and generates new inputs through mutations.
- It then checks if the binary fails when exposed to certain corner cases.

## Getting Started

### Running the Unit Test

1. **Run the Unit Test**: Execute the following command in your project's root directory:

```bash
make unittest
```

2. **Run the Fuzzing Test**: Execute the following command in your project's root directory:

```bash
make fuzztest
```

## Contribution

The current unit tests primarily focus on conversion, PURL counts, and license counts. Additional unit tests will be added in the future. If you have suggestions, improvements, or bug fixes, please don't hesitate to reach out and contribute to the project. Your input is highly valued.
80 changes: 80 additions & 0 deletions pkg/convert/convert_fuzzing_test.go
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that, Looking neat. but what are we testing here? can you explain more how it works?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just the first step to do the fuzzing tests for our tool. It generates new inputs for the ParseStream() function in protobom and verifies whether it can cause a crash. It helped to find errors in unserializing. we can add more functions for testing.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package convert

import (
"flag"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"testing"

"github.com/bom-squad/protobom/pkg/reader"
)

var (
seed_input string
)

func init() {
flag.StringVar(&seed_input, "seed_input", "fuzz_seed_spdx.json", "Seed input file path")
}

type ReadWriteSeeker struct {
*os.File
}

func (rws *ReadWriteSeeker) Close() error {
return rws.File.Close()
}

func WriteStringToTempFile(content string) (io.ReadSeekCloser, error) {
// Create a temporary file
tempFile, err := os.CreateTemp("", "tempfile")
if err != nil {
return nil, err
}

// Write the content to the temporary file
_, err = tempFile.WriteString(content)
if err != nil {
return nil, err
}

// Close the file to make sure all data is flushed to disk
err = tempFile.Close()
if err != nil {
return nil, err
}

// Reopen the temporary file for reading and seeking
file, err := os.OpenFile(tempFile.Name(), os.O_RDWR, 0644)
if err != nil {
return nil, err
}

return &ReadWriteSeeker{file}, nil
}

func ParseStreamWrapper(content string) {
t := io.NopCloser(strings.NewReader(content))
r := reader.New()
t, _ = WriteStringToTempFile(content)
t2 := t.(io.ReadSeekCloser)
r.ParseStream(t2)
}

func FuzzParseStream(f *testing.F) {
absPath, _ := filepath.Abs(seed_input)
fmt.Println(absPath)
content, err := os.ReadFile(absPath)
if err != nil {
log.Fatal(err)
}
f.Add(string(content))

f.Fuzz(func(t *testing.T, orig string) {
ParseStreamWrapper(orig)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is basically the test?

})
}
Loading
Loading