aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/crash_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-11-16 22:18:02 -0800
committerIan Lance Taylor <iant@golang.org>2021-11-17 17:36:36 +0000
commit0555ea3ce997db6e6ef14ba9f55857f359b3fbf2 (patch)
tree435374ff0b7c2089ee3adb50ea503e81639e8994 /src/runtime/crash_test.go
parentab75484d7130496ac9b204b0d418b1ec95bee2f8 (diff)
downloadgo-0555ea3ce997db6e6ef14ba9f55857f359b3fbf2.tar.xz
runtime: don't serialize all builds in test
Permit a test whose program is already built to run immediately, rather than waiting for another test to complete its build. For #44422 Change-Id: I2d1b35d055ee4c4251f4caef3b52dccc82b71a1b Reviewed-on: https://go-review.googlesource.com/c/go/+/364654 Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'src/runtime/crash_test.go')
-rw-r--r--src/runtime/crash_test.go61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index e0c0bac892..91a1a41ed5 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -6,6 +6,7 @@ package runtime_test
import (
"bytes"
+ "errors"
"flag"
"fmt"
"internal/testenv"
@@ -34,12 +35,13 @@ func TestMain(m *testing.M) {
var testprog struct {
sync.Mutex
dir string
- target map[string]buildexe
+ target map[string]*buildexe
}
type buildexe struct {
- exe string
- err error
+ once sync.Once
+ exe string
+ err error
}
func runTestProg(t *testing.T, binary, name string, env ...string) string {
@@ -108,13 +110,15 @@ func runBuiltTestProg(t *testing.T, exe, name string, env ...string) string {
return b.String()
}
+var serializeBuild = make(chan bool, 2)
+
func buildTestProg(t *testing.T, binary string, flags ...string) (string, error) {
if *flagQuick {
t.Skip("-quick")
}
+ testenv.MustHaveGoBuild(t)
testprog.Lock()
- defer testprog.Unlock()
if testprog.dir == "" {
dir, err := os.MkdirTemp("", "go-build")
if err != nil {
@@ -125,29 +129,48 @@ func buildTestProg(t *testing.T, binary string, flags ...string) (string, error)
}
if testprog.target == nil {
- testprog.target = make(map[string]buildexe)
+ testprog.target = make(map[string]*buildexe)
}
name := binary
if len(flags) > 0 {
name += "_" + strings.Join(flags, "_")
}
target, ok := testprog.target[name]
- if ok {
- return target.exe, target.err
- }
-
- exe := filepath.Join(testprog.dir, name+".exe")
- cmd := exec.Command(testenv.GoToolPath(t), append([]string{"build", "-o", exe}, flags...)...)
- cmd.Dir = "testdata/" + binary
- out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
- if err != nil {
- target.err = fmt.Errorf("building %s %v: %v\n%s", binary, flags, err, out)
+ if !ok {
+ target = &buildexe{}
testprog.target[name] = target
- return "", target.err
}
- target.exe = exe
- testprog.target[name] = target
- return exe, nil
+
+ dir := testprog.dir
+
+ // Unlock testprog while actually building, so that other
+ // tests can look up executables that were already built.
+ testprog.Unlock()
+
+ target.once.Do(func() {
+ // Only do two "go build"'s at a time,
+ // to keep load from getting too high.
+ serializeBuild <- true
+ defer func() { <-serializeBuild }()
+
+ // Don't get confused if testenv.GoToolPath calls t.Skip.
+ target.err = errors.New("building test called t.Skip")
+
+ exe := filepath.Join(dir, name+".exe")
+
+ t.Logf("running go build -o %s %s", exe, strings.Join(flags, " "))
+ cmd := exec.Command(testenv.GoToolPath(t), append([]string{"build", "-o", exe}, flags...)...)
+ cmd.Dir = "testdata/" + binary
+ out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
+ if err != nil {
+ target.err = fmt.Errorf("building %s %v: %v\n%s", binary, flags, err, out)
+ } else {
+ target.exe = exe
+ target.err = nil
+ }
+ })
+
+ return target.exe, target.err
}
func TestVDSO(t *testing.T) {