Skip to content

Instantly share code, notes, and snippets.

@vdemeester
Last active December 29, 2016 17:19
Show Gist options
  • Save vdemeester/fdb71a3ac11ac295a67a80e6b78a030d to your computer and use it in GitHub Desktop.
Save vdemeester/fdb71a3ac11ac295a67a80e6b78a030d to your computer and use it in GitHub Desktop.
λ go test ./... 1 ↵
--- FAIL: TestRetryAlwaysFailing (1.01s)
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
retry_test.go:10: I am always failing
FAIL
FAIL github.com/libkermit/retry 1.309s
package retry
import (
"io"
"sync"
"testing"
"time"
"unsafe"
)
type _T struct {
common
isParallel bool
context *testContext // For running tests and subtests.
}
type common struct {
mu sync.RWMutex // guards output, failed, and done.
output []byte // Output generated by test or benchmark.
w io.Writer // For flushToParent.
chatty bool // A copy of the chatty flag.
failed bool // Test or benchmark has failed.
skipped bool // Test of benchmark has been skipped.
finished bool // Test function has completed.
done bool // Test is finished and all subtests have completed.
parent *common
level int // Nesting depth of test or benchmark.
name string // Name of test or benchmark.
start time.Time // Time test or benchmark started
duration time.Duration
barrier chan bool // To signal parallel subtests they may start.
signal chan bool // To signal a test is done.
sub []*testing.T // Queue of subtests to be run in parallel.
}
type testContext struct {
match *matcher
mu sync.Mutex
// Channel used to signal tests that are ready to be run in parallel.
startParallel chan bool
// running is the number of tests currently running in parallel.
// This does not include tests that are waiting for subtests to complete.
running int
// numWaiting is the number tests waiting to be run in parallel.
numWaiting int
// maxParallel is a copy of the parallel flag.
maxParallel int
}
type matcher struct {
filter []string
matchFunc func(pat, str string) (bool, error)
mu sync.Mutex
subNames map[string]int64
}
func For(t *testing.T, timeout time.Duration, fn func(*testing.T)) {
ht := (*_T)(unsafe.Pointer(t))
after := time.After(timeout)
var timedOut bool
for {
fn(t)
select {
case <-after:
timedOut = true
default:
}
if !t.Failed() {
break
}
if !timedOut {
ht.mu.Lock()
ht.failed = false
ht.mu.Unlock()
}
if timedOut {
break
}
time.Sleep(100 * time.Millisecond)
}
}
package retry
import (
"testing"
"time"
)
func TestRetryAlwaysFailing(t *testing.T) {
For(t, time.Second, func(t *testing.T) {
t.Error("I am always failing")
})
}
func TestRetryFailingABit(t *testing.T) {
i := 0
For(t, time.Second, func(t *testing.T) {
if i < 3 {
t.Error("I am always failing")
}
i++
})
}
func TestRetryAlwaysSucceeding(t *testing.T) {
For(t, time.Second, func(t *testing.T) {
// don't do a thing
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment