diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go index c97e6df399..950e0eabe1 100644 --- a/src/time/sleep_test.go +++ b/src/time/sleep_test.go @@ -235,28 +235,59 @@ func TestAfterTick(t *testing.T) { } func TestAfterStop(t *testing.T) { - AfterFunc(100*Millisecond, func() {}) - t0 := NewTimer(50 * Millisecond) - c1 := make(chan bool, 1) - t1 := AfterFunc(150*Millisecond, func() { c1 <- true }) - c2 := After(200 * Millisecond) - if !t0.Stop() { - t.Fatalf("failed to stop event 0") + // We want to test that we stop a timer before it runs. + // We also want to test that it didn't run after a longer timer. + // Since we don't want the test to run for too long, we don't + // want to use lengthy times. That makes the test inherently flaky. + // So only report an error if it fails five times in a row. + + var errs []string + logErrs := func() { + for _, e := range errs { + t.Log(e) + } } - if !t1.Stop() { - t.Fatalf("failed to stop event 1") - } - <-c2 - select { - case <-t0.C: - t.Fatalf("event 0 was not stopped") - case <-c1: - t.Fatalf("event 1 was not stopped") - default: - } - if t1.Stop() { - t.Fatalf("Stop returned true twice") + + for i := 0; i < 5; i++ { + AfterFunc(100*Millisecond, func() {}) + t0 := NewTimer(50 * Millisecond) + c1 := make(chan bool, 1) + t1 := AfterFunc(150*Millisecond, func() { c1 <- true }) + c2 := After(200 * Millisecond) + if !t0.Stop() { + errs = append(errs, "failed to stop event 0") + continue + } + if !t1.Stop() { + errs = append(errs, "failed to stop event 1") + continue + } + <-c2 + select { + case <-t0.C: + errs = append(errs, "event 0 was not stopped") + continue + case <-c1: + errs = append(errs, "event 1 was not stopped") + continue + default: + } + if t1.Stop() { + errs = append(errs, "Stop returned true twice") + continue + } + + // Test passed, so all done. + if len(errs) > 0 { + t.Logf("saw %d errors, ignoring to avoid flakiness", len(errs)) + logErrs() + } + + return } + + t.Errorf("saw %d errors", len(errs)) + logErrs() } func TestAfterQueuing(t *testing.T) {