github.com/glimps-jbo/go-licenses@v0.0.0-20230908151000-e06d3c113277/e2e_test.go (about) 1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main_test 16 17 import ( 18 "bytes" 19 "errors" 20 "flag" 21 "os" 22 "os/exec" 23 "path/filepath" 24 "regexp" 25 "testing" 26 27 "github.com/google/go-cmp/cmp" 28 ) 29 30 var update = flag.Bool("update", false, "update golden files") 31 32 func TestReportCommandE2E(t *testing.T) { 33 tests := []struct { 34 workdir string 35 args []string // additional arguments to pass to report command. 36 goldenFilePath string 37 }{ 38 {"testdata/modules/hello01", nil, "licenses.csv"}, 39 {"testdata/modules/cli02", nil, "licenses.csv"}, 40 {"testdata/modules/vendored03", nil, "licenses.csv"}, 41 {"testdata/modules/replace04", nil, "licenses.csv"}, 42 {"testdata/modules/complex", nil, "licenses.csv"}, 43 44 {"testdata/modules/hello01", []string{"--template", "licenses.tpl"}, "licenses.md"}, 45 {"testdata/modules/template01", []string{"--template", "licenses.tpl"}, "licenses.md"}, 46 } 47 48 originalWorkDir, err := os.Getwd() 49 if err != nil { 50 t.Fatal(err) 51 } 52 t.Cleanup(func() { _ = os.Chdir(originalWorkDir) }) 53 54 // This builds go-licenses CLI to temporary dir. 55 tempDir, err := os.MkdirTemp("", "") 56 if err != nil { 57 t.Fatal(err) 58 } 59 defer os.RemoveAll(tempDir) 60 goLicensesPath := filepath.Join(tempDir, "go-licenses") 61 cmd := exec.Command("go", "build", "-o", goLicensesPath) 62 _, err = cmd.Output() 63 if err != nil { 64 t.Fatal(err) 65 } 66 t.Logf("Built go-licenses binary in %s.", goLicensesPath) 67 68 for _, tt := range tests { 69 t.Run(tt.workdir, func(t *testing.T) { 70 err := os.Chdir(filepath.Join(originalWorkDir, tt.workdir)) 71 if err != nil { 72 t.Fatal(err) 73 } 74 cmd := exec.Command("go", "mod", "download") 75 log, err := cmd.CombinedOutput() 76 if err != nil { 77 t.Fatalf("downloading go modules:\n%s", string(log)) 78 } 79 args := append([]string{"report", "."}, tt.args...) 80 cmd = exec.Command(goLicensesPath, args...) 81 // Capture stderr to buffer. 82 var stderr bytes.Buffer 83 cmd.Stderr = &stderr 84 t.Logf("%s $ go-licenses report .", tt.workdir) 85 output, err := cmd.Output() 86 if err != nil { 87 t.Logf("\n=== start of log ===\n%s=== end of log ===\n\n\n", stderr.String()) 88 t.Fatalf("running go-licenses report: %s. Full log shown above.", err) 89 } 90 got := string(output) 91 if *update { 92 err := os.WriteFile(tt.goldenFilePath, output, 0600) 93 if err != nil { 94 t.Fatalf("writing golden file: %s", err) 95 } 96 } 97 goldenBytes, err := os.ReadFile(tt.goldenFilePath) 98 if err != nil { 99 if errors.Is(err, os.ErrNotExist) { 100 t.Fatalf("reading golden file: %s. Create a golden file by running `go test --update .`", err) 101 } 102 t.Fatalf("reading golden file: %s", err) 103 } 104 golden := string(goldenBytes) 105 if got != golden { 106 t.Logf("\n=== start of log ===\n%s=== end of log ===\n\n\n", stderr.String()) 107 t.Fatalf("result of go-licenses report does not match the golden file.\n"+ 108 "Diff -golden +got:\n%s\n"+ 109 "Update the golden by running `go test --update .`", 110 cmp.Diff(golden, got)) 111 } 112 }) 113 } 114 } 115 116 func TestCheckCommandE2E(t *testing.T) { 117 tests := []struct { 118 workdir string 119 args []string // additional arguments to pass to report command. 120 goldenFilePath string 121 wantExitCode int 122 }{ 123 {"testdata/modules/hello01", nil, "output-check-forbidden.txt", 0}, 124 {"testdata/modules/hello01", []string{"--disallowed_types=forbidden,notice"}, "output-check-notice-forbidden.txt", 1}, 125 {"testdata/modules/cli02", nil, "output-check-forbidden.txt", 0}, 126 {"testdata/modules/cli02", []string{"--disallowed_types=forbidden,notice"}, "output-check-notice-forbidden.txt", 1}, 127 {"testdata/modules/cli02", []string{"--allowed_licenses=Apache-2.0"}, "output-check-license-names-1.txt", 1}, 128 {"testdata/modules/cli02", []string{"--allowed_licenses=Apache-2.0,MIT"}, "output-check-license-names-2.txt", 1}, 129 {"testdata/modules/cli02", []string{"--allowed_licenses= Apache-2.0, MIT"}, "output-check-license-names-2.txt", 1}, 130 {"testdata/modules/nolicense05", nil, "output-check.txt", 1}, 131 {"testdata/modules/complex", nil, "output-check-complex.txt", 0}, 132 } 133 134 originalWorkDir, err := os.Getwd() 135 if err != nil { 136 t.Fatal(err) 137 } 138 t.Cleanup(func() { _ = os.Chdir(originalWorkDir) }) 139 140 // This builds go-licenses CLI to temporary dir. 141 tempDir, err := os.MkdirTemp("", "") 142 if err != nil { 143 t.Fatal(err) 144 } 145 defer os.RemoveAll(tempDir) 146 goLicensesPath := filepath.Join(tempDir, "go-licenses") 147 cmd := exec.Command("go", "build", "-o", goLicensesPath) 148 _, err = cmd.Output() 149 if err != nil { 150 t.Fatal(err) 151 } 152 t.Logf("Built go-licenses binary in %s.", goLicensesPath) 153 154 for _, tt := range tests { 155 t.Run(tt.workdir, func(t *testing.T) { 156 err := os.Chdir(filepath.Join(originalWorkDir, tt.workdir)) 157 if err != nil { 158 t.Fatal(err) 159 } 160 cmd := exec.Command("go", "mod", "download") 161 log, err := cmd.CombinedOutput() 162 if err != nil { 163 t.Fatalf("downloading go modules:\n%s", string(log)) 164 } 165 // Extra flags to disable logging. 166 // Logs are not deterministic for this golden test. 167 args := append([]string{"--logtostderr=false", "--stderrthreshold=10", "check", "."}, tt.args...) 168 cmd = exec.Command(goLicensesPath, args...) 169 // Capture stderr to buffer. 170 var stderr bytes.Buffer 171 cmd.Stderr = &stderr 172 exitCode := 0 173 t.Logf("%s $ go-licenses check .", tt.workdir) 174 output, err := cmd.Output() 175 if err != nil { 176 exitCode = -1 177 178 if exitError, ok := err.(*exec.ExitError); ok { 179 exitCode = exitError.ExitCode() 180 } 181 } 182 183 if len(output) != 0 { 184 t.Fatalf("unexpected output running go-licenses check: %s.", string(output)) 185 } 186 187 if exitCode != tt.wantExitCode { 188 t.Fatalf("unexpected exit code running go-licenses check, expected %d but got %d", tt.wantExitCode, exitCode) 189 } 190 191 got := filterOutput(stderr.String()) 192 if *update { 193 err := os.WriteFile(tt.goldenFilePath, []byte(got), 0600) 194 if err != nil { 195 t.Fatalf("writing golden file: %s", err) 196 } 197 } 198 goldenBytes, err := os.ReadFile(tt.goldenFilePath) 199 if err != nil { 200 if errors.Is(err, os.ErrNotExist) { 201 t.Fatalf("reading golden file: %s. Create a golden file by running `go test --update .`", err) 202 } 203 t.Fatalf("reading golden file: %s", err) 204 } 205 golden := string(goldenBytes) 206 if got != golden { 207 t.Logf("\n=== start of log ===\n%s=== end of log ===\n\n\n", stderr.String()) 208 t.Fatalf("result of go-licenses check does not match the golden file.\n"+ 209 "Diff -golden +got:\n%s\n"+ 210 "Update the golden by running `go test --update .`", 211 cmp.Diff(golden, got)) 212 } 213 }) 214 } 215 } 216 217 func filterOutput(output string) string { 218 output = regexp.MustCompile(`(?m)W\d+.*\n`). 219 ReplaceAllString(output, "") 220 221 output = regexp.MustCompile(`(?m)^/.*\n`). 222 ReplaceAllString(output, "") 223 224 return output 225 }