diff --git a/test/linters_test.go b/test/linters_test.go index 3d8ca694c58f..6794efa10045 100644 --- a/test/linters_test.go +++ b/test/linters_test.go @@ -1,13 +1,17 @@ package test import ( + "os" "os/exec" "path/filepath" + "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/golangci/golangci-lint/pkg/logutils" "github.com/golangci/golangci-lint/test/testshared" ) @@ -28,18 +32,32 @@ func testSourcesFromDir(t *testing.T, dir string) { sources := findSources(t, dir, "*.go") - testshared.InstallGolangciLint(t) + binPath := testshared.InstallGolangciLint(t) - for _, s := range sources { - s := s - t.Run(filepath.Base(s), func(subTest *testing.T) { + cwd, err := os.Getwd() + require.NoError(t, err) + t.Cleanup(func() { _ = os.Chdir(cwd) }) + + err = os.Chdir(dir) + require.NoError(t, err) + + log := logutils.NewStderrLog("test") + log.SetLevel(logutils.LogLevelInfo) + + for _, source := range sources { + source := source + t.Run(filepath.Base(source), func(subTest *testing.T) { subTest.Parallel() - testOneSource(subTest, s) + + rel, err := filepath.Rel(dir, sources[0]) + require.NoError(t, err) + + testOneSource(subTest, log, binPath, rel) }) } } -func testOneSource(t *testing.T, sourcePath string) { +func testOneSource(t *testing.T, log *logutils.StderrLog, binPath, sourcePath string) { t.Helper() rc := testshared.ParseTestDirectives(t, sourcePath) @@ -62,6 +80,7 @@ func testOneSource(t *testing.T, sourcePath string) { } cmd := testshared.NewRunnerBuilder(t). + WithBinPath(binPath). WithNoParallelRunners(). WithArgs(caseArgs...). WithRunContext(rc). @@ -69,8 +88,12 @@ func testOneSource(t *testing.T, sourcePath string) { Runner(). Command() + startedAt := time.Now() + output, err := cmd.CombinedOutput() + log.Infof("ran [%s] in %s", strings.Join(cmd.Args, " "), time.Since(startedAt)) + // The returned error will be nil if the test file does not have any issues // and thus the linter exits with exit code 0. // So perform the additional assertions only if the error is non-nil. diff --git a/test/testshared/analysis.go b/test/testshared/analysis.go index 77e7d858a860..be1ed731275a 100644 --- a/test/testshared/analysis.go +++ b/test/testshared/analysis.go @@ -6,7 +6,6 @@ import ( "go/parser" "go/token" "os" - "path/filepath" "regexp" "sort" "strconv" @@ -21,8 +20,6 @@ import ( const keyword = "want" -const testdataDir = "testdata" - type jsonResult struct { Issues []*result.Issue } @@ -52,9 +49,6 @@ func Analyze(t *testing.T, sourcePath string, rawData []byte) { require.NoError(t, err) for _, issue := range reportData.Issues { - if !strings.HasPrefix(issue.Pos.Filename, testdataDir) { - issue.Pos.Filename = filepath.Join(testdataDir, issue.Pos.Filename) - } checkMessage(t, want, issue.Pos, "diagnostic", issue.FromLinter, issue.Text) } diff --git a/test/testshared/runner.go b/test/testshared/runner.go index 06c9e7303a51..1c3e3fba51ae 100644 --- a/test/testshared/runner.go +++ b/test/testshared/runner.go @@ -17,12 +17,13 @@ import ( "github.com/golangci/golangci-lint/pkg/logutils" ) -const binName = "../golangci-lint" +const defaultBinPath = "../golangci-lint" type RunnerBuilder struct { tb testing.TB log logutils.Log + binPath string command string env []string @@ -42,11 +43,18 @@ func NewRunnerBuilder(tb testing.TB) *RunnerBuilder { return &RunnerBuilder{ tb: tb, log: log, + binPath: defaultBinPath, command: "run", allowParallelRunners: true, } } +func (b *RunnerBuilder) WithBinPath(binPath string) *RunnerBuilder { + b.binPath = binPath + + return b +} + func (b *RunnerBuilder) WithCommand(command string) *RunnerBuilder { b.command = command @@ -162,6 +170,7 @@ func (b *RunnerBuilder) Runner() *Runner { } return &Runner{ + binPath: b.binPath, log: b.log, tb: b.tb, env: b.env, @@ -174,6 +183,7 @@ type Runner struct { log logutils.Log tb testing.TB + binPath string env []string command string args []string @@ -197,11 +207,10 @@ func (r *Runner) Run() *RunnerResult { runArgs := append([]string{r.command}, r.args...) defer func(startedAt time.Time) { - r.log.Infof("ran [%s %s] in %s", binName, strings.Join(runArgs, " "), time.Since(startedAt)) + r.log.Infof("ran [%s %s] in %s", r.binPath, strings.Join(runArgs, " "), time.Since(startedAt)) }(time.Now()) - cmd := exec.Command(binName, runArgs...) - cmd.Env = append(os.Environ(), r.env...) + cmd := r.Command() out, err := cmd.CombinedOutput() if err != nil { @@ -239,11 +248,8 @@ func (r *Runner) Command() *exec.Cmd { runArgs := append([]string{r.command}, r.args...) - defer func(startedAt time.Time) { - r.log.Infof("ran [../golangci-lint %s] in %s", strings.Join(runArgs, " "), time.Since(startedAt)) - }(time.Now()) - - cmd := exec.Command("../golangci-lint", runArgs...) + //nolint:gosec + cmd := exec.Command(r.binPath, runArgs...) cmd.Env = append(os.Environ(), r.env...) return cmd @@ -311,19 +317,22 @@ func (r *RunnerResult) ExpectHasIssue(issueText string) *RunnerResult { return r.ExpectExitCode(exitcodes.IssuesFound).ExpectOutputContains(issueText) } -func InstallGolangciLint(tb testing.TB) { +func InstallGolangciLint(tb testing.TB) string { tb.Helper() - if os.Getenv("GOLANGCI_LINT_INSTALLED") == "true" { - return - } + if os.Getenv("GOLANGCI_LINT_INSTALLED") != "true" { + cmd := exec.Command("make", "-C", "..", "build") - cmd := exec.Command("make", "-C", "..", "build") + output, err := cmd.CombinedOutput() + if err != nil { + tb.Log(string(output)) + } - output, err := cmd.CombinedOutput() - if err != nil { - tb.Log(string(output)) + require.NoError(tb, err, "Can't go install golangci-lint") } - require.NoError(tb, err, "Can't go install golangci-lint") + abs, err := filepath.Abs(defaultBinPath) + require.NoError(tb, err) + + return abs }