-
-
Save calmh/14f6ff12ffbedccaf5e531ba045cd6b7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func TestTimeoutCond(t *testing.T) { | |
const ( | |
// Low values to avoid being intrusive in continous testing. Can be | |
// increased significantly for stress testing. | |
iterations = 100 | |
routines = 10 | |
timeMult = 2 | |
) | |
c := NewTimeoutCond(NewMutex()) | |
// Start a routine to periodically broadcast on the cond. | |
go func() { | |
d := time.Duration(routines) * timeMult * time.Millisecond / 2 | |
t.Log("Broadcasting every", d) | |
for i := 0; i < iterations; i++ { | |
time.Sleep(d) | |
c.L.Lock() | |
c.Broadcast() | |
c.L.Unlock() | |
} | |
}() | |
// Start several routines that wait on it with different timeouts. | |
var results [routines][2]int | |
var wg sync.WaitGroup | |
for i := 0; i < routines; i++ { | |
i := i | |
wg.Add(1) | |
go func() { | |
d := time.Duration(i) * timeMult * time.Millisecond | |
t.Logf("Routine %d waits for %v\n", i, d) | |
succ, fail := runLocks(t, iterations, c, d) | |
results[i][0] = succ | |
results[i][1] = fail | |
wg.Done() | |
}() | |
} | |
wg.Wait() | |
// Print a table of routine number: successes, failures. | |
for i, v := range results { | |
t.Logf("%4d: %4d %4d\n", i, v[0], v[1]) | |
} | |
} | |
func runLocks(t *testing.T, iterations int, c *TimeoutCond, d time.Duration) (succ, fail int) { | |
for i := 0; i < iterations; i++ { | |
c.L.Lock() | |
w := c.SetupWait(d) | |
t0 := time.Now() | |
res := w.Wait() | |
waited := time.Since(t0) | |
// Allow 20% slide in either direction, and a five milliseconds of | |
// scheduling delay... In tweaking these it was clear that things | |
// worked like the should, so if this becomes a spurious failure | |
// kind of thing feel free to remove or give significantly more | |
// slack. | |
if !res && waited < d*8/10 { | |
t.Errorf("Wait failed early, %v < %v", waited, d) | |
} | |
if res && waited > d*11/10+5*time.Millisecond { | |
t.Errorf("Wait succeeded late, %v > %v", waited, d) | |
} | |
if res { | |
succ++ | |
} else { | |
fail++ | |
} | |
c.L.Unlock() | |
} | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment