blob: 4013e09650147f5d2068e1180108ba4b7298a8c9 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package result
import (
"encoding/json"
"flag"
"fmt"
"os"
"path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
spdx_common "github.com/spdx/tools-golang/spdx/common"
spdx "github.com/spdx/tools-golang/spdx/v2_2"
"go.fuchsia.dev/fuchsia/tools/check-licenses/project"
)
var (
testDataDir = flag.String("test_data_dir", "", "Path to test data directory")
)
// If the root project is null, SPDX doc generation should fail.
func TestDocCreationEmpty(t *testing.T) {
dir := t.TempDir()
Config = &ResultConfig{
FuchsiaDir: dir,
OutDir: dir,
}
_, err := generateSPDXDoc(t.Name(), []*project.Project{}, nil)
if err == nil {
t.Fatalf("%s: expected error, got none.", t.Name())
}
}
// Simple case: Ensure we can generate a simple doc with one SPDX package.
func TestDocCreationOnePackage(t *testing.T) { runTest("one_package", t) }
// Ensure we can create an SPDX document with multiple packages.
// The root package must have a "CONTAINS" relationship on all other packages.
func TestDocCreationMultiPackage(t *testing.T) { runTest("multi_package", t) }
// Ensure license information is presented properly in the SPDX document.
func TestDocCreationMultiPackageOneLicense(t *testing.T) { runTest("multi_package_one_license", t) }
// If a given package has multiple license files, ensure they are all included in
// the SPDX document successfully.
func TestDocCreationMultiPackageMultiLicense(t *testing.T) { runTest("multi_package_multi_license", t) }
// Similar to the above, NOTICE files have multiple license texts. Ensure we
// handle that situation properly.
func TestDocCreationMultiPackageNotice(t *testing.T) { runTest("multi_package_one_notice", t) }
func runTest(folder string, t *testing.T) {
dir := t.TempDir()
Config = &ResultConfig{
FuchsiaDir: dir,
OutDir: dir,
}
projectsJSONPath := filepath.Join(*testDataDir, "spdx", folder, "filtered_projects.json")
projects := loadProjectsJSON(projectsJSONPath, t)
root := projects[0]
_, err := generateSPDXDoc(t.Name(), projects, root)
if err != nil {
t.Fatalf("%s: expected no error, got %v", t.Name(), err)
}
wantPath := filepath.Join(*testDataDir, "spdx", folder, "want.json")
gotPath := filepath.Join(dir, spdxFilename)
want, got := loadWantGot(wantPath, gotPath, t)
if d := cmp.Diff(want, got); d != "" {
t.Errorf("%v: compare docs mismatch: (-want +got):\n%s", t.Name(), d)
}
}
func loadProjectsJSON(path string, t *testing.T) []*project.Project {
t.Helper()
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("%s: failed to read in json file [%s]: %v", t.Name(), path, err)
}
var projects []*project.Project
err = json.Unmarshal(content, &projects)
if err != nil {
t.Fatalf("%s: failed to unmarshal projects data [%s]: %v", t.Name(), path, err)
}
return projects
}
func loadWantGot(wantPath, gotPath string, t *testing.T) (*spdx.Document, *spdx.Document) {
t.Helper()
content, err := os.ReadFile(wantPath)
if err != nil {
t.Fatalf("%s: failed to read in json file [%s]: %v", t.Name(), wantPath, err)
}
var want *spdx.Document
err = json.Unmarshal(content, &want)
if err != nil {
t.Fatalf("%s: failed to unmarshal data [%s]: %v", t.Name(), wantPath, err)
}
content, err = os.ReadFile(gotPath)
if err != nil {
t.Fatalf("%s: failed to read in json file [%s]: %v", t.Name(), gotPath, err)
}
var got *spdx.Document
err = json.Unmarshal(content, &got)
if err != nil {
t.Fatalf("%s: failed to unmarshal data [%s]: %v", t.Name(), gotPath, err)
}
// Unable to accurately set the creation timestamp, so skip this field.
got.CreationInfo.Created = "SKIP ME"
// JSON unmarshalling of the SPDX DocElementID is broken.
// I will file a bug against the open source project.
// https://github.com/spdx/tools-golang/blob/main/spdx/common/identifier.go#L100
for _, r := range got.Relationships {
r.RefA.ElementRefID = spdx_common.ElementID(fmt.Sprintf("%s\"\n }", r.RefA.ElementRefID))
r.RefB.ElementRefID = spdx_common.ElementID(fmt.Sprintf("%s\"\n }", r.RefB.ElementRefID))
}
return want, got
}