]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: don't serialize all builds in test
authorIan Lance Taylor <iant@golang.org>
Wed, 17 Nov 2021 06:18:02 +0000 (22:18 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 17 Nov 2021 17:36:36 +0000 (17:36 +0000)
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>

src/runtime/crash_test.go

index e0c0bac8926adc2bd5465fb8fdcb64b53dac441d..91a1a41ed53a7a20f935e35f68e82621c2298b73 100644 (file)
@@ -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) {