aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/moricho/tparallel/tparallel.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-02-22 20:37:25 +0100
committerDmitry Vyukov <dvyukov@google.com>2021-02-22 21:02:12 +0100
commitfcc6d71be2c3ce7d9305c04fc2e87af554571bac (patch)
treeb01dbb3d1e2988e28ea158d2d543d603ec0b9569 /vendor/github.com/moricho/tparallel/tparallel.go
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/github.com/moricho/tparallel/tparallel.go')
-rw-r--r--vendor/github.com/moricho/tparallel/tparallel.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/vendor/github.com/moricho/tparallel/tparallel.go b/vendor/github.com/moricho/tparallel/tparallel.go
new file mode 100644
index 000000000..3139e0425
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/tparallel.go
@@ -0,0 +1,72 @@
+package tparallel
+
+import (
+ "go/types"
+
+ "github.com/gostaticanalysis/analysisutil"
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+
+ "github.com/moricho/tparallel/pkg/ssafunc"
+)
+
+const doc = "tparallel detects inappropriate usage of t.Parallel() method in your Go test codes."
+
+// Analyzer analyzes Go test codes whether they use t.Parallel() appropriately
+// by using SSA (Single Static Assignment)
+var Analyzer = &analysis.Analyzer{
+ Name: "tparallel",
+ Doc: doc,
+ Run: run,
+ Requires: []*analysis.Analyzer{
+ buildssa.Analyzer,
+ },
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ ssaanalyzer := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
+
+ obj := analysisutil.ObjectOf(pass, "testing", "T")
+ if obj == nil {
+ // skip checking
+ return nil, nil
+ }
+ testTyp, testPkg := obj.Type(), obj.Pkg()
+
+ p, _, _ := types.LookupFieldOrMethod(testTyp, true, testPkg, "Parallel")
+ parallel, _ := p.(*types.Func)
+ c, _, _ := types.LookupFieldOrMethod(testTyp, true, testPkg, "Cleanup")
+ cleanup, _ := c.(*types.Func)
+
+ testMap := getTestMap(ssaanalyzer, testTyp) // ex. {Test1: [TestSub1, TestSub2], Test2: [TestSub1, TestSub2, TestSub3], ...}
+ for top, subs := range testMap {
+ if len(subs) == 0 {
+ continue
+ }
+ isParallelTop := ssafunc.IsCalled(top, parallel)
+ isPararellSub := false
+ for _, sub := range subs {
+ isPararellSub = ssafunc.IsCalled(sub, parallel)
+ if isPararellSub {
+ break
+ }
+ }
+
+ if ssafunc.IsDeferCalled(top) {
+ useCleanup := ssafunc.IsCalled(top, cleanup)
+ if isPararellSub && !useCleanup {
+ pass.Reportf(top.Pos(), "%s should use t.Cleanup instead of defer", top.Name())
+ }
+ }
+
+ if isParallelTop == isPararellSub {
+ continue
+ } else if isPararellSub {
+ pass.Reportf(top.Pos(), "%s should call t.Parallel on the top level as well as its subtests", top.Name())
+ } else if isParallelTop {
+ pass.Reportf(top.Pos(), "%s's subtests should call t.Parallel", top.Name())
+ }
+ }
+
+ return nil, nil
+}