"time"
)
+var testDeadline time.Time
+
+func TestMain(m *testing.M) {
+ flag.Parse()
+
+ // TODO(golang.org/issue/28135): Remove this setup and use t.Deadline instead.
+ timeoutFlag := flag.Lookup("test.timeout")
+ if timeoutFlag != nil {
+ if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 {
+ testDeadline = time.Now().Add(d)
+ }
+ }
+
+ os.Exit(m.Run())
+}
+
func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
// Sleep multiple times to give the kernel more tries to
// deliver the signal.
const execs = 10
for i := 0; i < execs; i++ {
- cmd := exec.Command(os.Args[0], "-test.run=TestAtomicStop")
+ timeout := "0"
+ if !testDeadline.IsZero() {
+ timeout = testDeadline.Sub(time.Now()).String()
+ }
+ cmd := exec.Command(os.Args[0], "-test.run=TestAtomicStop", "-test.timeout="+timeout)
cmd.Env = append(os.Environ(), "GO_TEST_ATOMIC_STOP=1")
out, err := cmd.CombinedOutput()
if err == nil {
// either catch a signal or die from it.
func atomicStopTestProgram() {
const tries = 10
+
+ timeout := 2 * time.Second
+ if !testDeadline.IsZero() {
+ // Give each try an equal slice of the deadline, with one slice to spare for
+ // cleanup.
+ timeout = testDeadline.Sub(time.Now()) / (tries + 1)
+ }
+
pid := syscall.Getpid()
printed := false
for i := 0; i < tries; i++ {
select {
case <-cs:
- case <-time.After(2 * time.Second):
+ case <-time.After(timeout):
if !printed {
fmt.Print("lost signal on tries:")
printed = true