
Fixes flaky cgo test failures caused by duplicate printf format checks in staticcheck and go vet that use slightly different reporting formats.
224 lines
7.7 KiB
Go
224 lines
7.7 KiB
Go
package test
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/golangci/golangci-lint/test/testshared"
|
|
|
|
"github.com/golangci/golangci-lint/pkg/exitcodes"
|
|
|
|
_ "github.com/valyala/quicktemplate"
|
|
)
|
|
|
|
func getCommonRunArgs() []string {
|
|
return []string{"--skip-dirs", "testdata_etc/,pkg/golinters/goanalysis/(checker|passes)"}
|
|
}
|
|
|
|
func withCommonRunArgs(args ...string) []string {
|
|
return append(getCommonRunArgs(), args...)
|
|
}
|
|
|
|
func TestAutogeneratedNoIssues(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run(getTestDataDir("autogenerated")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestEmptyDirRun(t *testing.T) {
|
|
testshared.NewLintRunner(t, "GO111MODULE=off").Run(getTestDataDir("nogofiles")).
|
|
ExpectExitCode(exitcodes.NoGoFiles).
|
|
ExpectOutputContains(": no go files to analyze")
|
|
}
|
|
|
|
func TestNotExistingDirRun(t *testing.T) {
|
|
testshared.NewLintRunner(t, "GO111MODULE=off").Run(getTestDataDir("no_such_dir")).
|
|
ExpectExitCode(exitcodes.Failure).
|
|
ExpectOutputContains("cannot find package").
|
|
ExpectOutputContains("/testdata/no_such_dir")
|
|
}
|
|
|
|
func TestSymlinkLoop(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run(getTestDataDir("symlink_loop", "...")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestDeadline(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--deadline=1ms", getProjectRoot()).
|
|
ExpectExitCode(exitcodes.Timeout).
|
|
ExpectOutputContains(`Deadline exceeded: try increase it by passing --deadline option`)
|
|
}
|
|
|
|
func TestTestsAreLintedByDefault(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run(getTestDataDir("withtests")).
|
|
ExpectHasIssue("`if` block ends with a `return`")
|
|
}
|
|
|
|
func TestCgoOk(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--no-config", "--enable-all", getTestDataDir("cgo")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestCgoWithIssues(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--no-config", "--disable-all", "-Egovet", getTestDataDir("cgo_with_issues")).
|
|
ExpectHasIssue("Printf format %t has arg cs of wrong type")
|
|
testshared.NewLintRunner(t).Run("--no-config", "--disable-all", "-Estaticcheck", getTestDataDir("cgo_with_issues")).
|
|
ExpectHasIssue("SA5009: Printf format %t has arg #1 of wrong type")
|
|
}
|
|
|
|
func TestUnsafeOk(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--no-config", "--enable-all", getTestDataDir("unsafe")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestGovetCustomFormatter(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run(getTestDataDir("govet_custom_formatter")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestLineDirectiveProcessedFilesLiteLoading(t *testing.T) {
|
|
r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config",
|
|
"--exclude-use-default=false", "-Egolint", getTestDataDir("quicktemplate"))
|
|
|
|
output := strings.Join([]string{
|
|
"testdata/quicktemplate/hello.qtpl.go:26:1: exported function `StreamHello` should have comment or be unexported (golint)",
|
|
"testdata/quicktemplate/hello.qtpl.go:50:1: exported function `Hello` should have comment or be unexported (golint)",
|
|
"testdata/quicktemplate/hello.qtpl.go:39:1: exported function `WriteHello` should have comment or be unexported (golint)",
|
|
}, "\n")
|
|
r.ExpectExitCode(exitcodes.IssuesFound).ExpectOutputEq(output + "\n")
|
|
}
|
|
|
|
func TestLineDirectiveProcessedFilesFullLoading(t *testing.T) {
|
|
r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config",
|
|
"--exclude-use-default=false", "-Egolint,govet", getTestDataDir("quicktemplate"))
|
|
|
|
output := strings.Join([]string{
|
|
"testdata/quicktemplate/hello.qtpl.go:26:1: exported function `StreamHello` should have comment or be unexported (golint)",
|
|
"testdata/quicktemplate/hello.qtpl.go:50:1: exported function `Hello` should have comment or be unexported (golint)",
|
|
"testdata/quicktemplate/hello.qtpl.go:39:1: exported function `WriteHello` should have comment or be unexported (golint)",
|
|
}, "\n")
|
|
r.ExpectExitCode(exitcodes.IssuesFound).ExpectOutputEq(output + "\n")
|
|
}
|
|
|
|
func TestSkippedDirsNoMatchArg(t *testing.T) {
|
|
dir := getTestDataDir("skipdirs", "skip_me", "nested")
|
|
r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "--skip-dirs", dir, "-Egolint", dir)
|
|
|
|
r.ExpectExitCode(exitcodes.IssuesFound).
|
|
ExpectOutputEq("testdata/skipdirs/skip_me/nested/with_issue.go:8:9: `if` block ends with " +
|
|
"a `return` statement, so drop this `else` and outdent its block (golint)\n")
|
|
}
|
|
|
|
func TestSkippedDirsTestdata(t *testing.T) {
|
|
r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "-Egolint", getTestDataDir("skipdirs", "..."))
|
|
|
|
r.ExpectNoIssues() // all was skipped because in testdata
|
|
}
|
|
|
|
func TestDeadcodeNoFalsePositivesInMainPkg(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--no-config", "--disable-all", "-Edeadcode", getTestDataDir("deadcode_main_pkg")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestIdentifierUsedOnlyInTests(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--no-config", "--disable-all", "-Eunused", getTestDataDir("used_only_in_tests")).ExpectNoIssues()
|
|
}
|
|
|
|
func TestUnusedCheckExported(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("-c", "testdata_etc/unused_exported/golangci.yml", "testdata_etc/unused_exported/...").ExpectNoIssues()
|
|
}
|
|
|
|
func TestConfigFileIsDetected(t *testing.T) {
|
|
checkGotConfig := func(r *testshared.RunResult) {
|
|
r.ExpectExitCode(exitcodes.Success).
|
|
ExpectOutputEq("test\n") // test config contains InternalTest: true, it triggers such output
|
|
}
|
|
|
|
r := testshared.NewLintRunner(t)
|
|
checkGotConfig(r.Run(getTestDataDir("withconfig", "pkg")))
|
|
checkGotConfig(r.Run(getTestDataDir("withconfig", "...")))
|
|
}
|
|
|
|
func TestEnableAllFastAndEnableCanCoexist(t *testing.T) {
|
|
r := testshared.NewLintRunner(t)
|
|
r.Run(withCommonRunArgs("--no-config", "--fast", "--enable-all", "--enable=typecheck", minimalPkg)...).
|
|
ExpectExitCode(exitcodes.Success, exitcodes.IssuesFound)
|
|
r.Run(withCommonRunArgs("--no-config", "--enable-all", "--enable=typecheck", minimalPkg)...).
|
|
ExpectExitCode(exitcodes.Failure)
|
|
}
|
|
|
|
func TestEnabledPresetsAreNotDuplicated(t *testing.T) {
|
|
testshared.NewLintRunner(t).Run("--no-config", "-v", "-p", "style,bugs", minimalPkg).
|
|
ExpectOutputContains("Active presets: [bugs style]")
|
|
}
|
|
|
|
func TestAbsPathDirAnalysis(t *testing.T) {
|
|
dir := filepath.Join("testdata_etc", "abspath") // abs paths don't work with testdata dir
|
|
absDir, err := filepath.Abs(dir)
|
|
assert.NoError(t, err)
|
|
|
|
r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "-Egolint", absDir)
|
|
r.ExpectHasIssue("`if` block ends with a `return` statement")
|
|
}
|
|
|
|
func TestAbsPathFileAnalysis(t *testing.T) {
|
|
dir := filepath.Join("testdata_etc", "abspath", "with_issue.go") // abs paths don't work with testdata dir
|
|
absDir, err := filepath.Abs(dir)
|
|
assert.NoError(t, err)
|
|
|
|
r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "-Egolint", absDir)
|
|
r.ExpectHasIssue("`if` block ends with a `return` statement")
|
|
}
|
|
|
|
func TestDisallowedOptionsInConfig(t *testing.T) {
|
|
type tc struct {
|
|
cfg string
|
|
option string
|
|
}
|
|
|
|
cases := []tc{
|
|
{
|
|
cfg: `
|
|
ruN:
|
|
Args:
|
|
- 1
|
|
`,
|
|
},
|
|
{
|
|
cfg: `
|
|
run:
|
|
CPUProfilePath: path
|
|
`,
|
|
option: "--cpu-profile-path=path",
|
|
},
|
|
{
|
|
cfg: `
|
|
run:
|
|
MemProfilePath: path
|
|
`,
|
|
option: "--mem-profile-path=path",
|
|
},
|
|
{
|
|
cfg: `
|
|
run:
|
|
Verbose: true
|
|
`,
|
|
option: "-v",
|
|
},
|
|
}
|
|
|
|
r := testshared.NewLintRunner(t)
|
|
for _, c := range cases {
|
|
// Run with disallowed option set only in config
|
|
r.RunWithYamlConfig(c.cfg, withCommonRunArgs(minimalPkg)...).ExpectExitCode(exitcodes.Failure)
|
|
|
|
if c.option == "" {
|
|
continue
|
|
}
|
|
|
|
args := []string{c.option, "--fast", minimalPkg}
|
|
|
|
// Run with disallowed option set only in command-line
|
|
r.Run(withCommonRunArgs(args...)...).ExpectExitCode(exitcodes.Success)
|
|
|
|
// Run with disallowed option set both in command-line and in config
|
|
r.RunWithYamlConfig(c.cfg, withCommonRunArgs(args...)...).ExpectExitCode(exitcodes.Failure)
|
|
}
|
|
}
|