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  }