blob: 2e16df40732e8cbb0425607d4c17149b173f28da [file] [log] [blame]
Julie Qiu60403662021-12-17 18:11:51 -05001// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build go1.17 && !windows
6// +build go1.17,!windows
7
8package main
9
10import (
Damien Neil74a8e012022-08-10 14:26:13 -070011 "errors"
Julie Qiu60403662021-12-17 18:11:51 -050012 "os"
13 "os/exec"
Julie Qiu733040a2021-12-20 17:14:01 -050014 "path/filepath"
15 "runtime"
Damien Neil74a8e012022-08-10 14:26:13 -070016 "sort"
Julie Qiu733040a2021-12-20 17:14:01 -050017 "strings"
Julie Qiu60403662021-12-17 18:11:51 -050018 "testing"
Damien Neil2c15bf72022-09-13 16:09:01 -070019 "time"
Julie Qiu733040a2021-12-20 17:14:01 -050020
Damien Neil2c15bf72022-09-13 16:09:01 -070021 "github.com/google/go-cmp/cmp"
22 "github.com/google/go-cmp/cmp/cmpopts"
Maceo Thompsonb8b87b12022-10-20 15:14:42 -040023 "golang.org/x/vulndb/internal/cveschema5"
Tatiana Bradley0cbf4ff2023-05-12 16:14:27 -040024 "golang.org/x/vulndb/internal/osvutils"
Julie Qiu733040a2021-12-20 17:14:01 -050025 "golang.org/x/vulndb/internal/report"
Julie Qiu60403662021-12-17 18:11:51 -050026)
27
Julie Qiu733040a2021-12-20 17:14:01 -050028func TestChecksBash(t *testing.T) {
Julie Qiu60403662021-12-17 18:11:51 -050029 bash, err := exec.LookPath("bash")
30 if err != nil {
31 t.Skipf("skipping: %v", err)
32 }
33
34 cmd := exec.Command(bash, "./checks.bash")
35 cmd.Stdout = os.Stdout
36 cmd.Stderr = os.Stderr
37 if err := cmd.Run(); err != nil {
38 t.Fatal(err)
39 }
40}
Julie Qiu733040a2021-12-20 17:14:01 -050041
Julie Qiu733040a2021-12-20 17:14:01 -050042func TestLintReports(t *testing.T) {
43 if runtime.GOOS == "js" {
44 t.Skipf("wasm builder does not have network access")
45 }
46 if runtime.GOOS == "android" {
47 t.Skipf("android builder does not have access to reports/")
48 }
Damien Neil74a8e012022-08-10 14:26:13 -070049 allFiles := make(map[string]string)
50 var reports []string
Tatiana Bradleydefb5802022-11-18 16:26:39 -050051 for _, dir := range []string{report.YAMLDir, report.ExcludedDir} {
cui fliterc957d8f2022-09-14 06:13:32 +000052 files, err := os.ReadDir(dir)
Damien Neil74a8e012022-08-10 14:26:13 -070053 if err != nil && !errors.Is(err, os.ErrNotExist) {
54 t.Fatalf("unable to read %v/: %s", dir, err)
Julie Qiu733040a2021-12-20 17:14:01 -050055 }
Tatiana Bradley2551a342022-09-26 12:18:29 -040056 for _, file := range files {
57 if file.IsDir() {
Damien Neil74a8e012022-08-10 14:26:13 -070058 continue
59 }
Tatiana Bradley2551a342022-09-26 12:18:29 -040060 if filepath.Ext(file.Name()) != ".yaml" {
Jonathan Amsterdam90283d92022-08-22 15:01:49 -040061 continue
62 }
Tatiana Bradley2551a342022-09-26 12:18:29 -040063 filename := filepath.Join(dir, file.Name())
64 if allFiles[file.Name()] != "" {
65 t.Errorf("report appears in multiple locations: %v, %v", allFiles[file.Name()], filename)
Damien Neil74a8e012022-08-10 14:26:13 -070066 }
Tatiana Bradley2551a342022-09-26 12:18:29 -040067 allFiles[file.Name()] = filename
68 reports = append(reports, filename)
Damien Neil74a8e012022-08-10 14:26:13 -070069 }
70 }
Maceo Thompsone2eba222022-11-18 13:35:03 -050071 // Map from aliases (CVEs/GHSAS) to report paths, used to check for duplicate aliases.
72 aliases := make(map[string]string)
Damien Neil74a8e012022-08-10 14:26:13 -070073 sort.Strings(reports)
Tatiana Bradley2551a342022-09-26 12:18:29 -040074 for _, filename := range reports {
75 t.Run(filename, func(t *testing.T) {
76 r, err := report.Read(filename)
Julie Qiu733040a2021-12-20 17:14:01 -050077 if err != nil {
Julie Qiue508e322022-01-04 15:12:43 -050078 t.Fatal(err)
Julie Qiu733040a2021-12-20 17:14:01 -050079 }
Tatiana Bradley2551a342022-09-26 12:18:29 -040080 lints := r.Lint(filename)
Julie Qiu733040a2021-12-20 17:14:01 -050081 if len(lints) > 0 {
82 t.Errorf(strings.Join(lints, "\n"))
83 }
Tatiana Bradleydefb5802022-11-18 16:26:39 -050084 goID := report.GetGoIDFromFilename(filename)
Maceo Thompsone2eba222022-11-18 13:35:03 -050085 for _, alias := range r.GetAliases() {
86 if report, ok := aliases[alias]; ok {
87 t.Errorf("report %s shares duplicate alias %s with report %s", filename, alias, report)
88 } else {
89 aliases[alias] = filename
90 }
91 }
Tatiana Bradley2551a342022-09-26 12:18:29 -040092 // Check that a correct OSV file was generated for each YAML report.
Damien Neil2c15bf72022-09-13 16:09:01 -070093 if r.Excluded == "" {
Tatiana Bradleydefb5802022-11-18 16:26:39 -050094 generated := r.GenerateOSVEntry(goID, time.Time{})
95 osvFilename := report.GetOSVFilename(goID)
96 current, err := report.ReadOSV(osvFilename)
Damien Neil2c15bf72022-09-13 16:09:01 -070097 if err != nil {
98 t.Fatal(err)
99 }
Tatiana Bradley2551a342022-09-26 12:18:29 -0400100 if diff := cmp.Diff(generated, current, cmpopts.EquateEmpty()); diff != "" {
Tatiana Bradleydefb5802022-11-18 16:26:39 -0500101 t.Errorf("%s does not match report:\n%v", osvFilename, diff)
Damien Neil2c15bf72022-09-13 16:09:01 -0700102 }
Tatiana Bradley0cbf4ff2023-05-12 16:14:27 -0400103 if err := osvutils.ValidateExceptTimestamps(&current); err != nil {
104 t.Error(err)
105 }
Damien Neil2c15bf72022-09-13 16:09:01 -0700106 }
Maceo Thompsonb8b87b12022-10-20 15:14:42 -0400107 if r.CVEMetadata != nil {
Tatiana Bradleydefb5802022-11-18 16:26:39 -0500108 generated, err := r.ToCVE5(goID)
Maceo Thompsonb8b87b12022-10-20 15:14:42 -0400109 if err != nil {
110 t.Fatal(err)
111 }
Tatiana Bradleydefb5802022-11-18 16:26:39 -0500112 cvePath := report.GetCVEFilename(goID)
Maceo Thompsonb8b87b12022-10-20 15:14:42 -0400113 current, err := cveschema5.Read(cvePath)
114 if err != nil {
115 t.Fatal(err)
116 }
117 if diff := cmp.Diff(generated, current, cmpopts.EquateEmpty()); diff != "" {
118 t.Errorf("%s does not match report:\n%v", cvePath, diff)
119 }
120
121 }
Julie Qiu733040a2021-12-20 17:14:01 -0500122 })
123 }
124}