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.
// 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")
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)
}
}
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)
--- /dev/null
+// 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)
+ }
+}