File: dagctx_test.go

package info (click to toggle)
golang-github-jbenet-go-context 0.0~git20150711.d14ea06-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 84 kB
  • sloc: makefile: 2
file content (124 lines) | stat: -rw-r--r-- 2,765 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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)
	}
}