v2 / vlib / context / cause_test.v
112 lines · 84 sloc · 2.46 KB · 56e02481a4f0e421009413f58493620cc3a51f87
Raw
1// vtest retry: 3
2module context
3
4import time
5
6fn test_with_cancel_cause_no_cause() {
7 mut bg := background()
8 mut ctx, cancel := with_cancel_cause(mut bg)
9 defer {
10 cancel(none)
11 }
12
13 assert ctx.err() is none
14 assert cause(ctx) is none
15
16 cancel(none)
17 assert ctx.err().str() == 'context canceled'
18 // cause falls back to err() when no cause was set
19 assert cause(ctx).str() == 'context canceled'
20}
21
22fn test_with_cancel_cause_with_cause() {
23 my_err := error('my custom cause')
24
25 mut bg := background()
26 mut ctx, cancel := with_cancel_cause(mut bg)
27 defer {
28 cancel(none)
29 }
30
31 assert ctx.err() is none
32
33 cancel(my_err)
34 assert ctx.err().str() == 'context canceled'
35 assert cause(ctx).str() == 'my custom cause'
36}
37
38fn test_with_cancel_cause_first_cause_wins() {
39 first := error('first cause')
40 second := error('second cause')
41
42 mut bg := background()
43 mut ctx, cancel := with_cancel_cause(mut bg)
44
45 cancel(first)
46 cancel(second) // should be ignored
47 cancel(none) // should be ignored
48
49 assert cause(ctx).str() == 'first cause'
50}
51
52fn test_with_cancel_cause_parent_cancel_propagates() {
53 mut bg := background()
54 mut parent, parent_cancel := with_cancel(mut bg)
55 mut ctx, _ := with_cancel_cause(mut parent)
56
57 assert ctx.err() is none
58
59 parent_cancel()
60 // give goroutine a moment to propagate
61 time.sleep(5 * time.millisecond)
62
63 assert ctx.err().str() == 'context canceled'
64}
65
66fn test_with_timeout_cause_fires_cause() {
67 my_cause := error('timed out for testing')
68
69 mut bg := background()
70 mut ctx, cancel := with_timeout_cause(mut bg, 30 * time.millisecond, my_cause)
71 defer {
72 cancel()
73 }
74
75 // not done yet
76 assert ctx.err() is none
77
78 // wait for timeout
79 time.sleep(60 * time.millisecond)
80
81 assert ctx.err().str() == 'context deadline exceeded'
82 assert cause(ctx).str() == 'timed out for testing'
83}
84
85fn test_with_timeout_cause_cancel_before_deadline() {
86 my_cause := error('deadline cause')
87
88 mut bg := background()
89 mut ctx, cancel := with_timeout_cause(mut bg, 500 * time.millisecond, my_cause)
90
91 // cancel before deadline fires
92 cancel()
93 time.sleep(5 * time.millisecond)
94
95 assert ctx.err().str() == 'context canceled'
96 // no cause was set via CancelCauseFunc; cause falls back to err()
97 assert cause(ctx).str() == 'context canceled'
98}
99
100fn test_cause_on_plain_cancel_context() {
101 // cause() on a non-cause context should just return ctx.err()
102 mut bg := background()
103 mut ctx, cancel := with_cancel(mut bg)
104 defer {
105 cancel()
106 }
107
108 assert cause(ctx) is none
109
110 cancel()
111 assert cause(ctx).str() == 'context canceled'
112}
113