Skip to content

Commit 926e76d

Browse files
authored
Add tparallel linter (#1380)
1 parent c88841d commit 926e76d

File tree

8 files changed

+130
-8
lines changed

8 files changed

+130
-8
lines changed

Diff for: go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ require (
3434
github.com/mattn/go-colorable v0.1.7
3535
github.com/mitchellh/go-homedir v1.1.0
3636
github.com/mitchellh/go-ps v1.0.0
37+
github.com/moricho/tparallel v0.2.1
3738
github.com/nakabonne/nestif v0.3.0
3839
github.com/nishanths/exhaustive v0.0.0-20200811152831-6cf413ae40e0
3940
github.com/pkg/errors v0.9.1

Diff for: go.sum

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pkg/golinters/tparallel.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package golinters
2+
3+
import (
4+
"github.com/moricho/tparallel"
5+
"golang.org/x/tools/go/analysis"
6+
7+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
8+
)
9+
10+
func NewTparallel() *goanalysis.Linter {
11+
analyzers := []*analysis.Analyzer{
12+
tparallel.Analyzer,
13+
}
14+
15+
return goanalysis.NewLinter(
16+
"tparallel",
17+
"tparallel detects inappropriate usage of t.Parallel() method in your Go test codes",
18+
analyzers,
19+
nil,
20+
).WithLoadMode(goanalysis.LoadModeTypesInfo)
21+
}

Diff for: pkg/lint/lintersdb/manager.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ func (m *Manager) WithCustomLinters() *Manager {
5656
}
5757

5858
func (Manager) AllPresets() []string {
59-
return []string{linter.PresetBugs, linter.PresetComplexity, linter.PresetFormatting,
60-
linter.PresetPerformance, linter.PresetStyle, linter.PresetUnused}
59+
return []string{
60+
linter.PresetBugs, linter.PresetComplexity, linter.PresetFormatting,
61+
linter.PresetPerformance, linter.PresetStyle, linter.PresetUnused,
62+
}
6163
}
6264

6365
func (m Manager) allPresetsSet() map[string]bool {
@@ -305,6 +307,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
305307
WithPresets(linter.PresetStyle).
306308
WithLoadForGoAnalysis().
307309
WithURL("https://github.com/ssgreg/nlreturn"),
310+
linter.NewConfig(golinters.NewTparallel()).
311+
WithPresets(linter.PresetStyle).
312+
WithLoadForGoAnalysis().
313+
WithURL("https://github.com/moricho/tparallel"),
308314
// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
309315
linter.NewConfig(golinters.NewNoLintLint()).
310316
WithPresets(linter.PresetStyle).

Diff for: test/linters_test.go

+50-6
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,55 @@ func TestExtractRunContextFromComments(t *testing.T) {
252252
assert.Equal(t, []string{"-Egoimports"}, rc.args)
253253
}
254254

255-
func TestGolintConsumesXTestFiles(t *testing.T) {
256-
dir := getTestDataDir("withxtest")
257-
const expIssue = "`if` block ends with a `return` statement, so drop this `else` and outdent its block"
255+
func TestTparallel(t *testing.T) {
256+
t.Run("should fail on missing top-level Parallel()", func(t *testing.T) {
257+
sourcePath := filepath.Join(testdataDir, "tparallel", "missing_toplevel_test.go")
258+
args := []string{
259+
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", "--enable", "tparallel",
260+
sourcePath,
261+
}
262+
rc := extractRunContextFromComments(t, sourcePath)
263+
args = append(args, rc.args...)
264+
265+
cfg, err := yaml.Marshal(rc.config)
266+
assert.NoError(t, err)
267+
268+
testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...).
269+
ExpectHasIssue(
270+
"testdata/tparallel/missing_toplevel_test.go:7:6: TestTopLevel should call t.Parallel on the top level as well as its subtests\n",
271+
)
272+
})
273+
274+
t.Run("should fail on missing subtest Parallel()", func(t *testing.T) {
275+
sourcePath := filepath.Join(testdataDir, "tparallel", "missing_subtest_test.go")
276+
args := []string{
277+
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", "--enable", "tparallel",
278+
sourcePath,
279+
}
280+
rc := extractRunContextFromComments(t, sourcePath)
281+
args = append(args, rc.args...)
282+
283+
cfg, err := yaml.Marshal(rc.config)
284+
assert.NoError(t, err)
285+
286+
testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...).
287+
ExpectHasIssue(
288+
"testdata/tparallel/missing_subtest_test.go:7:6: TestSubtests's subtests should call t.Parallel\n",
289+
)
290+
})
291+
292+
t.Run("should pass on parallel test with no subtests", func(t *testing.T) {
293+
sourcePath := filepath.Join(testdataDir, "tparallel", "happy_path_test.go")
294+
args := []string{
295+
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", "--enable", "tparallel",
296+
sourcePath,
297+
}
298+
rc := extractRunContextFromComments(t, sourcePath)
299+
args = append(args, rc.args...)
300+
301+
cfg, err := yaml.Marshal(rc.config)
302+
assert.NoError(t, err)
258303

259-
r := testshared.NewLintRunner(t)
260-
r.Run("--no-config", "--disable-all", "-Egolint", dir).ExpectHasIssue(expIssue)
261-
r.Run("--no-config", "--disable-all", "-Egolint", filepath.Join(dir, "p_test.go")).ExpectHasIssue(expIssue)
304+
testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...).ExpectNoIssues()
305+
})
262306
}

Diff for: test/testdata/tparallel/happy_path_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package testdata
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestValidHappyPath(t *testing.T) {
8+
t.Parallel()
9+
t.Run("", func(t *testing.T) {
10+
t.Parallel()
11+
})
12+
}
13+
14+
func TestValidNoSubTest(t *testing.T) {
15+
t.Parallel()
16+
}

Diff for: test/testdata/tparallel/missing_subtest_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package testdata
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestSubtests(t *testing.T) {
8+
t.Parallel()
9+
10+
t.Run("", func(t *testing.T) {
11+
})
12+
}

Diff for: test/testdata/tparallel/missing_toplevel_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package testdata
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestTopLevel(t *testing.T) {
8+
t.Run("", func(t *testing.T) {
9+
t.Parallel()
10+
})
11+
}

0 commit comments

Comments
 (0)