mirror of
https://github.com/golang/go
synced 2024-11-14 15:10:54 -07:00
b0e238add5
Each different file that does import "C" must be compiled and analyzed separately by cgo. Having fewer files import "C" reduces the cost of building the test. This is especially important because this test is built and run four different times (with different settings) during all.bash. go test -c in this directory used to take over 20 seconds on my laptop. Now it takes under 5 seconds. Removes 23.4r 29.0u 21.5s from all.bash. For #26473. Change-Id: Ie7cb7b0d9d6138ebd2eb548d0d8ea6e409ae10b9 Reviewed-on: https://go-review.googlesource.com/c/go/+/177558 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
129 lines
2.8 KiB
Go
129 lines
2.8 KiB
Go
// Copyright 2016 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.
|
|
|
|
// +build !windows
|
|
|
|
// Issue 18146: pthread_create failure during syscall.Exec.
|
|
|
|
package cgotest
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/md5"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func test18146(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skipping in short mode")
|
|
}
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
t.Skipf("skipping flaky test on %s; see golang.org/issue/18202", runtime.GOOS)
|
|
}
|
|
|
|
if runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
|
|
t.Skipf("skipping on %s", runtime.GOARCH)
|
|
}
|
|
|
|
attempts := 1000
|
|
threads := 4
|
|
|
|
// Restrict the number of attempts based on RLIMIT_NPROC.
|
|
// Tediously, RLIMIT_NPROC was left out of the syscall package,
|
|
// probably because it is not in POSIX.1, so we define it here.
|
|
// It is not defined on Solaris.
|
|
var nproc int
|
|
setNproc := true
|
|
switch runtime.GOOS {
|
|
default:
|
|
setNproc = false
|
|
case "aix":
|
|
nproc = 9
|
|
case "linux":
|
|
nproc = 6
|
|
case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd":
|
|
nproc = 7
|
|
}
|
|
if setNproc {
|
|
var rlim syscall.Rlimit
|
|
if syscall.Getrlimit(nproc, &rlim) == nil {
|
|
max := int(rlim.Cur) / (threads + 5)
|
|
if attempts > max {
|
|
t.Logf("lowering attempts from %d to %d for RLIMIT_NPROC", attempts, max)
|
|
attempts = max
|
|
}
|
|
}
|
|
}
|
|
|
|
if os.Getenv("test18146") == "exec" {
|
|
runtime.GOMAXPROCS(1)
|
|
for n := threads; n > 0; n-- {
|
|
go func() {
|
|
for {
|
|
_ = md5.Sum([]byte("Hello, !"))
|
|
}
|
|
}()
|
|
}
|
|
runtime.GOMAXPROCS(threads)
|
|
argv := append(os.Args, "-test.run=NoSuchTestExists")
|
|
if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
var cmds []*exec.Cmd
|
|
defer func() {
|
|
for _, cmd := range cmds {
|
|
cmd.Process.Kill()
|
|
}
|
|
}()
|
|
|
|
args := append(append([]string(nil), os.Args[1:]...), "-test.run=Test18146")
|
|
for n := attempts; n > 0; n-- {
|
|
cmd := exec.Command(os.Args[0], args...)
|
|
cmd.Env = append(os.Environ(), "test18146=exec")
|
|
buf := bytes.NewBuffer(nil)
|
|
cmd.Stdout = buf
|
|
cmd.Stderr = buf
|
|
if err := cmd.Start(); err != nil {
|
|
// We are starting so many processes that on
|
|
// some systems (problem seen on Darwin,
|
|
// Dragonfly, OpenBSD) the fork call will fail
|
|
// with EAGAIN.
|
|
if pe, ok := err.(*os.PathError); ok {
|
|
err = pe.Err
|
|
}
|
|
if se, ok := err.(syscall.Errno); ok && (se == syscall.EAGAIN || se == syscall.EMFILE) {
|
|
time.Sleep(time.Millisecond)
|
|
continue
|
|
}
|
|
|
|
t.Error(err)
|
|
return
|
|
}
|
|
cmds = append(cmds, cmd)
|
|
}
|
|
|
|
failures := 0
|
|
for _, cmd := range cmds {
|
|
err := cmd.Wait()
|
|
if err == nil {
|
|
continue
|
|
}
|
|
|
|
t.Errorf("syscall.Exec failed: %v\n%s", err, cmd.Stdout)
|
|
failures++
|
|
}
|
|
|
|
if failures > 0 {
|
|
t.Logf("Failed %v of %v attempts.", failures, len(cmds))
|
|
}
|
|
}
|