e456945466
On a few occasions I've had to read timeout stack traces for tests and noticed that retry.Run runs the function in a goroutine. This makes debuging a timeout more difficult because the gourinte of the retryable function is disconnected from the stack of the actual test. It requires searching through the entire stack trace to find the other goroutine. By using panic instead of runtime.Goexit() we remove the need for a separate goroutine. Also a few other small improvements: * add `R.Helper` so that an assertion function can be used with both testing.T and retry.R. * Pass t to `Retryer.NextOr`, and call `t.Helper` in a number of places so that the line number reported by `t.Log` is the line in the test where `retry.Run` was called, instead of some line in `retry.go` that is not relevant to the failure. * improve the implementation of `dedup` by removing the need to iterate twice. Instad track the lines and skip any duplicate when writing to the buffer.
44 lines
1.1 KiB
Go
44 lines
1.1 KiB
Go
package retry
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// delta defines the time band a test run should complete in.
|
|
var delta = 25 * time.Millisecond
|
|
|
|
func TestRetryer(t *testing.T) {
|
|
tests := []struct {
|
|
desc string
|
|
r Retryer
|
|
}{
|
|
{"counter", &Counter{Count: 3, Wait: 100 * time.Millisecond}},
|
|
{"timer", &Timer{Timeout: 200 * time.Millisecond, Wait: 100 * time.Millisecond}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
var iters, fails int
|
|
fail := func() { fails++ }
|
|
start := time.Now()
|
|
for tt.r.NextOr(t, fail) {
|
|
iters++
|
|
}
|
|
dur := time.Since(start)
|
|
if got, want := iters, 3; got != want {
|
|
t.Fatalf("got %d retries want %d", got, want)
|
|
}
|
|
if got, want := fails, 1; got != want {
|
|
t.Fatalf("got %d FailNow calls want %d", got, want)
|
|
}
|
|
// since the first iteration happens immediately
|
|
// the retryer waits only twice for three iterations.
|
|
// order of events: (true, (wait) true, (wait) true, false)
|
|
if got, want := dur, 200*time.Millisecond; got < (want-delta) || got > (want+delta) {
|
|
t.Fatalf("loop took %v want %v (+/- %v)", got, want, delta)
|
|
}
|
|
})
|
|
}
|
|
}
|