]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cover: use -toolexec in tests to run newly built cover program
authorIan Lance Taylor <iant@golang.org>
Thu, 6 Dec 2018 22:08:19 +0000 (14:08 -0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 18 Dec 2018 20:55:57 +0000 (20:55 +0000)
This ensures that "go test cmd/cover" tests the current cover program,
not the installed cover program.

Change-Id: I58e718ded7eb1cd8da448d0194262209bb025b20
Reviewed-on: https://go-review.googlesource.com/c/153058
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/cover/cover_test.go
src/cmd/cover/testdata/toolexec.go [new file with mode: 0644]

index aebe6f8cb511f1aa0329bce2c0152b1ed9cfca25..3e5c076d361822925a64785cab596670d7d11194 100644 (file)
@@ -30,9 +30,10 @@ const (
 
 var (
        // Input files.
-       testMain     = filepath.Join(testdata, "main.go")
-       testTest     = filepath.Join(testdata, "test.go")
-       coverProfile = filepath.Join(testdata, "profile.cov")
+       testMain       = filepath.Join(testdata, "main.go")
+       testTest       = filepath.Join(testdata, "test.go")
+       coverProfile   = filepath.Join(testdata, "profile.cov")
+       toolexecSource = filepath.Join(testdata, "toolexec.go")
 
        // The HTML test files are in a separate directory
        // so they are a complete package.
@@ -53,11 +54,17 @@ var (
        // testcover is a newly built version of the cover program.
        testcover string
 
-       // testcoverErr records an error building testcover.
+       // toolexec is a program to use as the go tool's -toolexec argument.
+       toolexec string
+
+       // testcoverErr records an error building testcover or toolexec.
        testcoverErr error
 
        // testcoverOnce is used to build testcover once.
        testcoverOnce sync.Once
+
+       // toolexecArg is the argument to pass to the go tool.
+       toolexecArg string
 )
 
 var debug = flag.Bool("debug", false, "keep rewritten files for debugging")
@@ -94,14 +101,43 @@ func buildCover(t *testing.T) {
        t.Helper()
        testenv.MustHaveGoBuild(t)
        testcoverOnce.Do(func() {
-               testcover = filepath.Join(testTempDir, "testcover.exe")
-               t.Logf("running [go build -o %s]", testcover)
-               out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", testcover).CombinedOutput()
-               t.Logf("%s", out)
-               testcoverErr = err
+               var wg sync.WaitGroup
+               wg.Add(2)
+
+               var err1, err2 error
+               go func() {
+                       defer wg.Done()
+                       testcover = filepath.Join(testTempDir, "cover.exe")
+                       t.Logf("running [go build -o %s]", testcover)
+                       out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", testcover).CombinedOutput()
+                       if len(out) > 0 {
+                               t.Logf("%s", out)
+                       }
+                       err1 = err
+               }()
+
+               go func() {
+                       defer wg.Done()
+                       toolexec = filepath.Join(testTempDir, "toolexec.exe")
+                       t.Logf("running [go -build -o %s %s]", toolexec, toolexecSource)
+                       out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", toolexec, toolexecSource).CombinedOutput()
+                       if len(out) > 0 {
+                               t.Logf("%s", out)
+                       }
+                       err2 = err
+               }()
+
+               wg.Wait()
+
+               testcoverErr = err1
+               if err2 != nil && err1 == nil {
+                       testcoverErr = err2
+               }
+
+               toolexecArg = "-toolexec=" + toolexec + " " + testcover
        })
        if testcoverErr != nil {
-               t.Fatal("failed to build testcover program:", testcoverErr)
+               t.Fatal("failed to build testcover or toolexec program:", testcoverErr)
        }
 }
 
@@ -335,7 +371,7 @@ func TestCoverHTML(t *testing.T) {
        buildCover(t)
 
        // go test -coverprofile testdata/html/html.cov cmd/cover/testdata/html
-       cmd := exec.Command(testenv.GoToolPath(t), "test", "-coverprofile", htmlProfile, "cmd/cover/testdata/html")
+       cmd := exec.Command(testenv.GoToolPath(t), "test", toolexecArg, "-coverprofile", htmlProfile, "cmd/cover/testdata/html")
        run(cmd, t)
        // testcover -html testdata/html/html.cov -o testdata/html/html.html
        cmd = exec.Command(testcover, "-html", htmlProfile, "-o", htmlHTML)
diff --git a/src/cmd/cover/testdata/toolexec.go b/src/cmd/cover/testdata/toolexec.go
new file mode 100644 (file)
index 0000000..1769efe
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The toolexec program is a helper program for cmd/cover tests.
+// It is used so that the go tool will call the newly built version
+// of the cover program, rather than the installed one.
+//
+// The tests arrange to run the go tool with the argument
+//    -toolexec="/path/to/toolexec /path/to/testcover"
+// The go tool will invoke this program (compiled into /path/to/toolexec)
+// with the arguments shown above followed by the command to run.
+// This program will check whether it is expected to run the cover
+// program, and if so replace it with /path/to/testcover.
+package main
+
+import (
+       "os"
+       "os/exec"
+       "strings"
+)
+
+func main() {
+       if strings.HasSuffix(strings.TrimSuffix(os.Args[2], ".exe"), "cover") {
+               os.Args[2] = os.Args[1]
+       }
+       cmd := exec.Command(os.Args[2], os.Args[3:]...)
+       cmd.Stdout = os.Stdout
+       cmd.Stderr = os.Stderr
+       if err := cmd.Run(); err != nil {
+               os.Exit(1)
+       }
+}