Skip to content

Commit 8f7fb01

Browse files
committed
go/analysis/unitchecker: add test of go vet on std
This change adds a new test that runs go vet on std, using a unitchecker-based tool with (hopefully) the same set of analyzers as the real cmd/vet in GOROOT. This should serve as an early warning when a change to an analyzer causes it to become stricter on std packages. Change-Id: I87503f40ad2d54b928d876216a951ed88b216e58 Reviewed-on: https://go-review.googlesource.com/c/tools/+/493619 Run-TryBot: Alan Donovan <[email protected]> TryBot-Result: Gopher Robot <[email protected]> gopls-CI: kokoro <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 23e52a3 commit 8f7fb01

File tree

5 files changed

+123
-32
lines changed

5 files changed

+123
-32
lines changed

go/analysis/unitchecker/main.go

+14
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,23 @@ import (
2727
"golang.org/x/tools/go/analysis/passes/cgocall"
2828
"golang.org/x/tools/go/analysis/passes/composite"
2929
"golang.org/x/tools/go/analysis/passes/copylock"
30+
"golang.org/x/tools/go/analysis/passes/directive"
3031
"golang.org/x/tools/go/analysis/passes/errorsas"
32+
"golang.org/x/tools/go/analysis/passes/framepointer"
3133
"golang.org/x/tools/go/analysis/passes/httpresponse"
34+
"golang.org/x/tools/go/analysis/passes/ifaceassert"
3235
"golang.org/x/tools/go/analysis/passes/loopclosure"
3336
"golang.org/x/tools/go/analysis/passes/lostcancel"
3437
"golang.org/x/tools/go/analysis/passes/nilfunc"
3538
"golang.org/x/tools/go/analysis/passes/printf"
3639
"golang.org/x/tools/go/analysis/passes/shift"
40+
"golang.org/x/tools/go/analysis/passes/sigchanyzer"
3741
"golang.org/x/tools/go/analysis/passes/stdmethods"
42+
"golang.org/x/tools/go/analysis/passes/stringintconv"
3843
"golang.org/x/tools/go/analysis/passes/structtag"
44+
"golang.org/x/tools/go/analysis/passes/testinggoroutine"
3945
"golang.org/x/tools/go/analysis/passes/tests"
46+
"golang.org/x/tools/go/analysis/passes/timeformat"
4047
"golang.org/x/tools/go/analysis/passes/unmarshal"
4148
"golang.org/x/tools/go/analysis/passes/unreachable"
4249
"golang.org/x/tools/go/analysis/passes/unsafeptr"
@@ -53,16 +60,23 @@ func main() {
5360
cgocall.Analyzer,
5461
composite.Analyzer,
5562
copylock.Analyzer,
63+
directive.Analyzer,
5664
errorsas.Analyzer,
65+
framepointer.Analyzer,
5766
httpresponse.Analyzer,
67+
ifaceassert.Analyzer,
5868
loopclosure.Analyzer,
5969
lostcancel.Analyzer,
6070
nilfunc.Analyzer,
6171
printf.Analyzer,
6272
shift.Analyzer,
73+
sigchanyzer.Analyzer,
6374
stdmethods.Analyzer,
75+
stringintconv.Analyzer,
6476
structtag.Analyzer,
6577
tests.Analyzer,
78+
testinggoroutine.Analyzer,
79+
timeformat.Analyzer,
6680
unmarshal.Analyzer,
6781
unreachable.Analyzer,
6882
unsafeptr.Analyzer,

go/analysis/unitchecker/unitchecker.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,6 @@ func readConfig(filename string) (*Config, error) {
183183
return cfg, nil
184184
}
185185

186-
var importerForCompiler = func(_ *token.FileSet, compiler string, lookup importer.Lookup) types.Importer {
187-
// broken legacy implementation (https://golang.org/issue/28995)
188-
return importer.For(compiler, lookup)
189-
}
190-
191186
func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]result, error) {
192187
// Load, parse, typecheck.
193188
var files []*ast.File
@@ -203,7 +198,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
203198
}
204199
files = append(files, f)
205200
}
206-
compilerImporter := importerForCompiler(fset, cfg.Compiler, func(path string) (io.ReadCloser, error) {
201+
compilerImporter := importer.ForCompiler(fset, cfg.Compiler, func(path string) (io.ReadCloser, error) {
207202
// path is a resolved package path, not an import path.
208203
file, ok := cfg.PackageFile[path]
209204
if !ok {

go/analysis/unitchecker/unitchecker112.go

-14
This file was deleted.

go/analysis/unitchecker/unitchecker_test.go

+11-12
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build go1.12
6-
// +build go1.12
7-
85
package unitchecker_test
96

10-
// This test depends on features such as
11-
// go vet's support for vetx files (1.11) and
12-
// the (*os.ProcessState).ExitCode method (1.12).
13-
147
import (
158
"flag"
169
"os"
@@ -28,17 +21,23 @@ import (
2821
)
2922

3023
func TestMain(m *testing.M) {
31-
if os.Getenv("UNITCHECKER_CHILD") == "1" {
32-
// child process
33-
main()
24+
// child process?
25+
switch os.Getenv("ENTRYPOINT") {
26+
case "vet":
27+
vet()
28+
panic("unreachable")
29+
case "minivet":
30+
minivet()
3431
panic("unreachable")
3532
}
3633

34+
// test process
3735
flag.Parse()
3836
os.Exit(m.Run())
3937
}
4038

41-
func main() {
39+
// minivet is a vet-like tool with a few analyzers, for testing.
40+
func minivet() {
4241
unitchecker.Main(
4342
findcall.Analyzer,
4443
printf.Analyzer,
@@ -162,7 +161,7 @@ func _() {
162161
} {
163162
cmd := exec.Command("go", "vet", "-vettool="+os.Args[0], "-findcall.name=MyFunc123")
164163
cmd.Args = append(cmd.Args, strings.Fields(test.args)...)
165-
cmd.Env = append(exported.Config.Env, "UNITCHECKER_CHILD=1")
164+
cmd.Env = append(exported.Config.Env, "ENTRYPOINT=minivet")
166165
cmd.Dir = exported.Config.Dir
167166

168167
out, err := cmd.CombinedOutput()
+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package unitchecker_test
6+
7+
import (
8+
"os"
9+
"os/exec"
10+
"runtime"
11+
"strings"
12+
"testing"
13+
14+
"golang.org/x/tools/go/analysis/passes/asmdecl"
15+
"golang.org/x/tools/go/analysis/passes/assign"
16+
"golang.org/x/tools/go/analysis/passes/atomic"
17+
"golang.org/x/tools/go/analysis/passes/bools"
18+
"golang.org/x/tools/go/analysis/passes/buildtag"
19+
"golang.org/x/tools/go/analysis/passes/cgocall"
20+
"golang.org/x/tools/go/analysis/passes/composite"
21+
"golang.org/x/tools/go/analysis/passes/copylock"
22+
"golang.org/x/tools/go/analysis/passes/directive"
23+
"golang.org/x/tools/go/analysis/passes/errorsas"
24+
"golang.org/x/tools/go/analysis/passes/framepointer"
25+
"golang.org/x/tools/go/analysis/passes/httpresponse"
26+
"golang.org/x/tools/go/analysis/passes/ifaceassert"
27+
"golang.org/x/tools/go/analysis/passes/loopclosure"
28+
"golang.org/x/tools/go/analysis/passes/lostcancel"
29+
"golang.org/x/tools/go/analysis/passes/nilfunc"
30+
"golang.org/x/tools/go/analysis/passes/printf"
31+
"golang.org/x/tools/go/analysis/passes/shift"
32+
"golang.org/x/tools/go/analysis/passes/sigchanyzer"
33+
"golang.org/x/tools/go/analysis/passes/stdmethods"
34+
"golang.org/x/tools/go/analysis/passes/stringintconv"
35+
"golang.org/x/tools/go/analysis/passes/structtag"
36+
"golang.org/x/tools/go/analysis/passes/testinggoroutine"
37+
"golang.org/x/tools/go/analysis/passes/tests"
38+
"golang.org/x/tools/go/analysis/passes/timeformat"
39+
"golang.org/x/tools/go/analysis/passes/unmarshal"
40+
"golang.org/x/tools/go/analysis/passes/unreachable"
41+
"golang.org/x/tools/go/analysis/passes/unusedresult"
42+
"golang.org/x/tools/go/analysis/unitchecker"
43+
)
44+
45+
// vet is the entrypoint of this executable when ENTRYPOINT=vet.
46+
// Keep consistent with the actual vet in GOROOT/src/cmd/vet/main.go.
47+
func vet() {
48+
unitchecker.Main(
49+
asmdecl.Analyzer,
50+
assign.Analyzer,
51+
atomic.Analyzer,
52+
bools.Analyzer,
53+
buildtag.Analyzer,
54+
cgocall.Analyzer,
55+
composite.Analyzer,
56+
copylock.Analyzer,
57+
directive.Analyzer,
58+
errorsas.Analyzer,
59+
framepointer.Analyzer,
60+
httpresponse.Analyzer,
61+
ifaceassert.Analyzer,
62+
loopclosure.Analyzer,
63+
lostcancel.Analyzer,
64+
nilfunc.Analyzer,
65+
printf.Analyzer,
66+
shift.Analyzer,
67+
sigchanyzer.Analyzer,
68+
stdmethods.Analyzer,
69+
stringintconv.Analyzer,
70+
structtag.Analyzer,
71+
tests.Analyzer,
72+
testinggoroutine.Analyzer,
73+
timeformat.Analyzer,
74+
unmarshal.Analyzer,
75+
unreachable.Analyzer,
76+
// unsafeptr.Analyzer, // currently reports findings in runtime
77+
unusedresult.Analyzer,
78+
)
79+
}
80+
81+
// TestVetStdlib runs the same analyzers as the actual vet over the
82+
// standard library, using go vet and unitchecker, to ensure that
83+
// there are no findings.
84+
func TestVetStdlib(t *testing.T) {
85+
if testing.Short() {
86+
t.Skip("skipping in -short mode")
87+
}
88+
if version := runtime.Version(); !strings.HasPrefix(version, "devel") {
89+
t.Skipf("This test is only wanted on development branches where code can be easily fixed. Skipping because runtime.Version=%q.", version)
90+
}
91+
92+
cmd := exec.Command("go", "vet", "-vettool="+os.Args[0], "std")
93+
cmd.Env = append(os.Environ(), "ENTRYPOINT=vet")
94+
if out, err := cmd.CombinedOutput(); err != nil {
95+
t.Errorf("go vet std failed (%v):\n%s", err, out)
96+
}
97+
}

0 commit comments

Comments
 (0)