mirror of
https://github.com/Luzifer/ansible-role-version.git
synced 2024-12-23 19:11:20 +00:00
125 lines
2.7 KiB
Go
125 lines
2.7 KiB
Go
|
package ctxext
|
||
|
|
||
|
import (
|
||
|
"math/rand"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
context "golang.org/x/net/context"
|
||
|
)
|
||
|
|
||
|
func TestWithParentsSingle(t *testing.T) {
|
||
|
ctx1, cancel := context.WithCancel(context.Background())
|
||
|
ctx2 := WithParents(ctx1)
|
||
|
|
||
|
select {
|
||
|
case <-ctx2.Done():
|
||
|
t.Fatal("ended too early")
|
||
|
case <-time.After(time.Millisecond):
|
||
|
}
|
||
|
|
||
|
cancel()
|
||
|
|
||
|
select {
|
||
|
case <-ctx2.Done():
|
||
|
case <-time.After(time.Millisecond):
|
||
|
t.Error("should've cancelled it")
|
||
|
}
|
||
|
|
||
|
if ctx2.Err() != ctx1.Err() {
|
||
|
t.Error("errors should match")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestWithParentsDeadline(t *testing.T) {
|
||
|
ctx1, _ := context.WithCancel(context.Background())
|
||
|
ctx2, _ := context.WithTimeout(context.Background(), time.Second)
|
||
|
ctx3, _ := context.WithTimeout(context.Background(), time.Second*2)
|
||
|
|
||
|
ctx := WithParents(ctx1)
|
||
|
d, ok := ctx.Deadline()
|
||
|
if ok {
|
||
|
t.Error("ctx should have no deadline")
|
||
|
}
|
||
|
|
||
|
ctx = WithParents(ctx1, ctx2, ctx3)
|
||
|
d, ok = ctx.Deadline()
|
||
|
d2, ok2 := ctx2.Deadline()
|
||
|
if !ok {
|
||
|
t.Error("ctx should have deadline")
|
||
|
} else if !ok2 {
|
||
|
t.Error("ctx2 should have deadline")
|
||
|
} else if !d.Equal(d2) {
|
||
|
t.Error("ctx should have ctx2 deadline")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func SubtestWithParentsMany(t *testing.T, n int) {
|
||
|
|
||
|
ctxs := make([]context.Context, n)
|
||
|
cancels := make([]context.CancelFunc, n)
|
||
|
for i := 0; i < n; i++ {
|
||
|
if i == 0 { // first must be new.
|
||
|
ctxs[i], cancels[i] = context.WithCancel(context.Background())
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
r := rand.Intn(i) // select a previous context
|
||
|
switch rand.Intn(6) {
|
||
|
case 0: // same as old
|
||
|
ctxs[i], cancels[i] = ctxs[r], cancels[r]
|
||
|
case 1: // derive from another
|
||
|
ctxs[i], cancels[i] = context.WithCancel(ctxs[r])
|
||
|
case 2: // deadline
|
||
|
t := (time.Second) * time.Duration(r+2) // +2 so we dont run into 0 or timing bugs
|
||
|
ctxs[i], cancels[i] = context.WithTimeout(ctxs[r], t)
|
||
|
default: // new context
|
||
|
ctxs[i], cancels[i] = context.WithCancel(context.Background())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ctx := WithParents(ctxs...)
|
||
|
|
||
|
// test deadline is earliest.
|
||
|
d1 := earliestDeadline(ctxs)
|
||
|
d2, ok := ctx.Deadline()
|
||
|
switch {
|
||
|
case d1 == nil && ok:
|
||
|
t.Error("nil, should not have deadline")
|
||
|
case d1 != nil && !ok:
|
||
|
t.Error("not nil, should have deadline")
|
||
|
case d1 != nil && ok && !d1.Equal(d2):
|
||
|
t.Error("should find same deadline")
|
||
|
}
|
||
|
if ok {
|
||
|
t.Logf("deadline - now: %s", d2.Sub(time.Now()))
|
||
|
}
|
||
|
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
t.Fatal("ended too early")
|
||
|
case <-time.After(time.Millisecond):
|
||
|
}
|
||
|
|
||
|
// cancel just one
|
||
|
r := rand.Intn(len(cancels))
|
||
|
cancels[r]()
|
||
|
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
case <-time.After(time.Millisecond):
|
||
|
t.Error("any should've cancelled it")
|
||
|
}
|
||
|
|
||
|
if ctx.Err() != ctxs[r].Err() {
|
||
|
t.Error("errors should match")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestWithParentsMany(t *testing.T) {
|
||
|
n := 100
|
||
|
for i := 1; i < n; i++ {
|
||
|
SubtestWithParentsMany(t, i)
|
||
|
}
|
||
|
}
|