aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/moricho
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
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/github.com/moricho')
-rw-r--r--vendor/github.com/moricho/tparallel/.gitignore3
-rw-r--r--vendor/github.com/moricho/tparallel/.goreleaser.yml38
-rw-r--r--vendor/github.com/moricho/tparallel/LICENSE21
-rw-r--r--vendor/github.com/moricho/tparallel/Makefile13
-rw-r--r--vendor/github.com/moricho/tparallel/README.md100
-rw-r--r--vendor/github.com/moricho/tparallel/go.mod8
-rw-r--r--vendor/github.com/moricho/tparallel/go.sum34
-rw-r--r--vendor/github.com/moricho/tparallel/pkg/ssafunc/ssafunc.go34
-rw-r--r--vendor/github.com/moricho/tparallel/pkg/ssainstr/ssainstr.go63
-rw-r--r--vendor/github.com/moricho/tparallel/testmap.go63
-rw-r--r--vendor/github.com/moricho/tparallel/tparallel.go72
11 files changed, 449 insertions, 0 deletions
diff --git a/vendor/github.com/moricho/tparallel/.gitignore b/vendor/github.com/moricho/tparallel/.gitignore
new file mode 100644
index 000000000..71342280e
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/.gitignore
@@ -0,0 +1,3 @@
+/tparallel
+.envrc
+/dist
diff --git a/vendor/github.com/moricho/tparallel/.goreleaser.yml b/vendor/github.com/moricho/tparallel/.goreleaser.yml
new file mode 100644
index 000000000..e9f6d727e
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/.goreleaser.yml
@@ -0,0 +1,38 @@
+project_name: tparallel
+env:
+ - GO111MODULE=on
+before:
+ hooks:
+ - go mod tidy
+builds:
+ - main: ./cmd/tparallel
+ binary: tparallel
+ ldflags:
+ - -s -w
+ - -X main.Version={{.Version}}
+ - -X main.Revision={{.ShortCommit}}
+ env:
+ - CGO_ENABLED=0
+archives:
+ - name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
+ replacements:
+ darwin: darwin
+ linux: linux
+ windows: windows
+ 386: i386
+ amd64: x86_64
+ format_overrides:
+ - goos: windows
+ format: zip
+release:
+ prerelease: auto
+brews:
+ - tap:
+ owner: moricho
+ name: homebrew-tparallel
+ homepage: https://github.com/moricho/tparallel
+ description: tparallel detects inappropriate usage of t.Parallel() method in your Go test codes
+ install: |
+ bin.install "tparallel"
+ test: |
+ system "#{bin}/goreleaser -v"
diff --git a/vendor/github.com/moricho/tparallel/LICENSE b/vendor/github.com/moricho/tparallel/LICENSE
new file mode 100644
index 000000000..4f029982f
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 moricho
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/moricho/tparallel/Makefile b/vendor/github.com/moricho/tparallel/Makefile
new file mode 100644
index 000000000..fb3588069
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/Makefile
@@ -0,0 +1,13 @@
+all: build
+
+.PHONY: build
+build:
+ go build -o tparallel ./cmd/tparallel
+
+.PHONY: build_race
+build_race:
+ go build -race -o tparallel ./cmd/tparallel
+
+.PHONY: test
+test: build_race
+ go test -v ./...
diff --git a/vendor/github.com/moricho/tparallel/README.md b/vendor/github.com/moricho/tparallel/README.md
new file mode 100644
index 000000000..cd358d155
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/README.md
@@ -0,0 +1,100 @@
+# tparallel
+[![tparallel](https://github.com/moricho/tparallel/workflows/tparallel/badge.svg?branch=master)](https://github.com/moricho/tparallel/actions)
+[![Go Report Card](https://goreportcard.com/badge/github.com/moricho/tparallel)](https://goreportcard.com/report/github.com/moricho/tparallel)
+[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
+
+`tparallel` finds inappropriate usage of `t.Parallel()` method in your Go test codes.
+It detects the following:
+- `t.Parallel()` is called in either a top-level test function or a sub-test function only
+- Although `t.Parallel()` is called in the sub-test function, it is post-processed by `defer` instead of `t.Cleanup()`
+
+This tool was inspired by this blog: [Go言語でのテストの並列化 〜t.Parallel()メソッドを理解する〜](https://engineering.mercari.com/blog/entry/how_to_use_t_parallel/)
+
+## Installation
+
+### From GitHub Releases
+Please see [GitHub Releases](https://github.com/moricho/tparallel/releases).
+Available binaries are:
+- macOS
+- Linux
+- Windows
+
+### macOS
+``` sh
+$ brew tap moricho/tparallel
+$ brew install tparallel
+```
+
+### go get
+```sh
+$ go get -u github.com/moricho/tparallel/cmd/tparallel
+```
+
+## Usage
+
+```sh
+$ go vet -vettool=`which tparallel` <pkgname>
+```
+
+## Example
+
+```go
+package sample
+
+import (
+ "testing"
+)
+
+func Test_Table1(t *testing.T) {
+ teardown := setup("Test_Table1")
+ defer teardown()
+
+ tests := []struct {
+ name string
+ }{
+ {
+ name: "Table1_Sub1",
+ },
+ {
+ name: "Table1_Sub2",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ call(tt.name)
+ })
+ }
+}
+
+func Test_Table2(t *testing.T) {
+ teardown := setup("Test_Table2")
+ t.Cleanup(teardown)
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ }{
+ {
+ name: "Table2_Sub1",
+ },
+ {
+ name: "Table2_Sub2",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ call(tt.name)
+ })
+ }
+}
+```
+
+```console
+# github.com/moricho/tparallel/testdata/src/sample
+testdata/src/sample/table_test.go:7:6: Test_Table1 should use t.Cleanup
+testdata/src/sample/table_test.go:7:6: Test_Table1 should call t.Parallel on the top level as well as its subtests
+testdata/src/sample/table_test.go:30:6: Test_Table2's subtests should call t.Parallel
+```
diff --git a/vendor/github.com/moricho/tparallel/go.mod b/vendor/github.com/moricho/tparallel/go.mod
new file mode 100644
index 000000000..9947ccb60
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/go.mod
@@ -0,0 +1,8 @@
+module github.com/moricho/tparallel
+
+go 1.15
+
+require (
+ github.com/gostaticanalysis/analysisutil v0.1.0
+ golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65
+)
diff --git a/vendor/github.com/moricho/tparallel/go.sum b/vendor/github.com/moricho/tparallel/go.sum
new file mode 100644
index 000000000..bcc4158da
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/go.sum
@@ -0,0 +1,34 @@
+github.com/gostaticanalysis/analysisutil v0.1.0 h1:E4c8Y1EQURbBEAHoXc/jBTK7Np14ArT8NPUiSFOl9yc=
+github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
+github.com/gostaticanalysis/comment v1.3.0 h1:wTVgynbFu8/nz6SGgywA0TcyIoAVsYc7ai/Zp5xNGlw=
+github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65 h1:DajXNh69ob79PCQz1N7OHxmqq6ASZC5xAnJJWIQGR6I=
+golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/github.com/moricho/tparallel/pkg/ssafunc/ssafunc.go b/vendor/github.com/moricho/tparallel/pkg/ssafunc/ssafunc.go
new file mode 100644
index 000000000..5a8e637bd
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/pkg/ssafunc/ssafunc.go
@@ -0,0 +1,34 @@
+package ssafunc
+
+import (
+ "go/types"
+
+ "github.com/gostaticanalysis/analysisutil"
+ "github.com/moricho/tparallel/pkg/ssainstr"
+ "golang.org/x/tools/go/ssa"
+)
+
+// IsDeferCalled returns whether the given ssa.Function calls `defer`
+func IsDeferCalled(f *ssa.Function) bool {
+ for _, block := range f.Blocks {
+ for _, instr := range block.Instrs {
+ switch instr.(type) {
+ case *ssa.Defer:
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// IsCalled returns whether the given ssa.Function calls `fn` func
+func IsCalled(f *ssa.Function, fn *types.Func) bool {
+ block := f.Blocks[0]
+ for _, instr := range block.Instrs {
+ called := analysisutil.Called(instr, nil, fn)
+ if _, ok := ssainstr.LookupCalled(instr, fn); ok || called {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/moricho/tparallel/pkg/ssainstr/ssainstr.go b/vendor/github.com/moricho/tparallel/pkg/ssainstr/ssainstr.go
new file mode 100644
index 000000000..374553f5e
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/pkg/ssainstr/ssainstr.go
@@ -0,0 +1,63 @@
+package ssainstr
+
+import (
+ "go/types"
+
+ "github.com/gostaticanalysis/analysisutil"
+ "golang.org/x/tools/go/ssa"
+)
+
+// LookupCalled looks up ssa.Instruction that call the `fn` func in the given instr
+func LookupCalled(instr ssa.Instruction, fn *types.Func) ([]ssa.Instruction, bool) {
+ instrs := []ssa.Instruction{}
+
+ call, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ return instrs, false
+ }
+
+ ssaCall := call.Value()
+ if ssaCall == nil {
+ return instrs, false
+ }
+ common := ssaCall.Common()
+ if common == nil {
+ return instrs, false
+ }
+ val := common.Value
+
+ called := false
+ switch fnval := val.(type) {
+ case *ssa.Function:
+ for _, block := range fnval.Blocks {
+ for _, instr := range block.Instrs {
+ if analysisutil.Called(instr, nil, fn) {
+ called = true
+ instrs = append(instrs, instr)
+ }
+ }
+ }
+ }
+
+ return instrs, called
+}
+
+// HasArgs returns whether the given ssa.Instruction has `typ` type args
+func HasArgs(instr ssa.Instruction, typ types.Type) bool {
+ call, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ return false
+ }
+
+ ssaCall := call.Value()
+ if ssaCall == nil {
+ return false
+ }
+
+ for _, arg := range ssaCall.Call.Args {
+ if types.Identical(arg.Type(), typ) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/moricho/tparallel/testmap.go b/vendor/github.com/moricho/tparallel/testmap.go
new file mode 100644
index 000000000..fa9bed708
--- /dev/null
+++ b/vendor/github.com/moricho/tparallel/testmap.go
@@ -0,0 +1,63 @@
+package tparallel
+
+import (
+ "go/types"
+ "strings"
+
+ "github.com/gostaticanalysis/analysisutil"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/moricho/tparallel/pkg/ssainstr"
+)
+
+// getTestMap gets a set of a top-level test and its sub-tests
+func getTestMap(ssaanalyzer *buildssa.SSA, testTyp types.Type) map[*ssa.Function][]*ssa.Function {
+ testMap := map[*ssa.Function][]*ssa.Function{}
+
+ trun := analysisutil.MethodOf(testTyp, "Run")
+ for _, f := range ssaanalyzer.SrcFuncs {
+ if !strings.HasPrefix(f.Name(), "Test") || !(f.Parent() == (*ssa.Function)(nil)) {
+ continue
+ }
+ testMap[f] = []*ssa.Function{}
+ for _, block := range f.Blocks {
+ for _, instr := range block.Instrs {
+ called := analysisutil.Called(instr, nil, trun)
+
+ if !called && ssainstr.HasArgs(instr, types.NewPointer(testTyp)) {
+ if instrs, ok := ssainstr.LookupCalled(instr, trun); ok {
+ for _, v := range instrs {
+ testMap[f] = appendTestMap(testMap[f], v)
+ }
+ }
+ } else if called {
+ testMap[f] = appendTestMap(testMap[f], instr)
+ }
+ }
+ }
+ }
+
+ return testMap
+}
+
+// appendTestMap converts ssa.Instruction to ssa.Function and append it to a given sub-test slice
+func appendTestMap(subtests []*ssa.Function, instr ssa.Instruction) []*ssa.Function {
+ call, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ return subtests
+ }
+
+ ssaCall := call.Value()
+ for _, arg := range ssaCall.Call.Args {
+ switch arg := arg.(type) {
+ case *ssa.Function:
+ subtests = append(subtests, arg)
+ case *ssa.MakeClosure:
+ fn, _ := arg.Fn.(*ssa.Function)
+ subtests = append(subtests, fn)
+ }
+ }
+
+ return subtests
+}
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
+}