From f124b50345853d5b6885e7459fc91d7dda3d9307 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sat, 4 Feb 2023 17:28:11 +0000 Subject: [PATCH] cmd/stringer: streamline test subprocesses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Execute the test binary itself as cmd/stringer instead of invoking (and cleaning up after) 'go build'. - Replace os.MkdirTemp with T.TempDir Changes are similar to https://go.dev/cl/377836. Change-Id: I5f9fca20e0f1f045826c385d556257fc5982ed53 GitHub-Last-Rev: f6c6b7735c97d3c2f508de91a268cf6795291ffd GitHub-Pull-Request: golang/tools#425 Reviewed-on: https://go-review.googlesource.com/c/tools/+/464350 Reviewed-by: Bryan Mills Auto-Submit: Bryan Mills Reviewed-by: Daniel Martí Reviewed-by: Michael Knyszek TryBot-Result: Gopher Robot Run-TryBot: Bryan Mills --- cmd/stringer/endtoend_test.go | 54 +++++++++++++++++++++-------------- cmd/stringer/golden_test.go | 7 +---- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/cmd/stringer/endtoend_test.go b/cmd/stringer/endtoend_test.go index 268c2f61be2..29eb91860ff 100644 --- a/cmd/stringer/endtoend_test.go +++ b/cmd/stringer/endtoend_test.go @@ -19,9 +19,9 @@ import ( "path" "path/filepath" "strings" + "sync" "testing" - "golang.org/x/tools/internal/testenv" "golang.org/x/tools/internal/typeparams" ) @@ -30,9 +30,22 @@ import ( // we run stringer -type X and then compile and run the program. The resulting // binary panics if the String method for X is not correct, including for error cases. +func TestMain(m *testing.M) { + if os.Getenv("STRINGER_TEST_IS_STRINGER") != "" { + main() + os.Exit(0) + } + + // Inform subprocesses that they should run the cmd/stringer main instead of + // running tests. It's a close approximation to building and running the real + // command, and much less complicated and expensive to build and clean up. + os.Setenv("STRINGER_TEST_IS_STRINGER", "1") + + os.Exit(m.Run()) +} + func TestEndToEnd(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) + stringer := stringerPath(t) // Read the testdata directory. fd, err := os.Open("testdata") if err != nil { @@ -64,7 +77,7 @@ func TestEndToEnd(t *testing.T) { t.Logf("cgo is not enabled for %s", name) continue } - stringerCompileAndRun(t, dir, stringer, typeName(name), name) + stringerCompileAndRun(t, t.TempDir(), stringer, typeName(name), name) } } @@ -91,8 +104,8 @@ func moreTests(t *testing.T, dirname, prefix string) []string { // TestTags verifies that the -tags flag works as advertised. func TestTags(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) + stringer := stringerPath(t) + dir := t.TempDir() var ( protectedConst = []byte("TagProtected") output = filepath.Join(dir, "const_string.go") @@ -139,8 +152,8 @@ func TestTags(t *testing.T) { // TestConstValueChange verifies that if a constant value changes and // the stringer code is not regenerated, we'll get a compiler error. func TestConstValueChange(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) + stringer := stringerPath(t) + dir := t.TempDir() source := filepath.Join(dir, "day.go") err := copy(source, filepath.Join("testdata", "day.go")) if err != nil { @@ -178,21 +191,20 @@ func TestConstValueChange(t *testing.T) { } } -// buildStringer creates a temporary directory and installs stringer there. -func buildStringer(t *testing.T) (dir string, stringer string) { - t.Helper() - testenv.NeedsTool(t, "go") +var exe struct { + path string + err error + once sync.Once +} - dir, err := os.MkdirTemp("", "stringer") - if err != nil { - t.Fatal(err) - } - stringer = filepath.Join(dir, "stringer.exe") - err = run("go", "build", "-o", stringer) - if err != nil { - t.Fatalf("building stringer: %s", err) +func stringerPath(t *testing.T) string { + exe.once.Do(func() { + exe.path, exe.err = os.Executable() + }) + if exe.err != nil { + t.Fatal(exe.err) } - return dir, stringer + return exe.path } // stringerCompileAndRun runs stringer for the named file and compiles and diff --git a/cmd/stringer/golden_test.go b/cmd/stringer/golden_test.go index 2e2ec58de69..250af05f903 100644 --- a/cmd/stringer/golden_test.go +++ b/cmd/stringer/golden_test.go @@ -451,12 +451,7 @@ func (i Token) String() string { func TestGolden(t *testing.T) { testenv.NeedsTool(t, "go") - dir, err := os.MkdirTemp("", "stringer") - if err != nil { - t.Error(err) - } - defer os.RemoveAll(dir) - + dir := t.TempDir() for _, test := range golden { g := Generator{ trimPrefix: test.trimPrefix,