vxx2 / vlib / x / executor / errors_test.v
133 lines · 114 sloc · 2.98 KB · e80386b6af8a071a2e13fd654ebcdb2105fb9202
Raw
1module executor
2
3import time
4
5fn test_first_job_error_is_returned_after_accepted_jobs_drain() {
6 mut ex := new(queue_size: 4)!
7 ran := chan int{cap: 2}
8 result := chan string{cap: 1}
9
10 ex.try_post(fn [ran] () ! {
11 ran <- 1
12 return error('first owner failure')
13 })!
14 ex.try_post(fn [ran] () ! {
15 ran <- 2
16 })!
17
18 runner := spawn fn [mut ex, result] () {
19 ex.run() or {
20 result <- err.msg()
21 return
22 }
23 result <- 'ok'
24 }()
25
26 assert wait_for_int(ran, 'first job did not run') == 1
27 assert wait_for_int(ran, 'accepted job after error did not drain') == 2
28 assert wait_for_string(result, 'run did not return first job error') == 'first owner failure'
29 ex.wait() or {
30 assert err.msg() == 'first owner failure'
31 runner.wait()
32 return
33 }
34 assert false, 'wait did not return first job error'
35}
36
37fn test_admission_closes_after_first_job_error() {
38 mut ex := new(queue_size: 1)!
39 ex.try_post(fn () ! {
40 return error('owner failure')
41 })!
42 mut saw_job_error := false
43 ex.run_one() or {
44 assert err.msg() == 'owner failure'
45 saw_job_error = true
46 }
47 assert saw_job_error
48
49 ex.try_post(fn () ! {}) or {
50 assert err.msg() == 'executor: executor is closed'
51 ex.wait() or { assert err.msg() == 'owner failure' }
52 return
53 }
54 assert false, 'try_post accepted after first job error'
55}
56
57fn test_run_one_after_job_error_requires_continued_pumping_to_drain() {
58 mut ex := new(queue_size: 3)!
59 ran := chan int{cap: 2}
60
61 ex.try_post(fn [ran] () ! {
62 ran <- 1
63 return error('owner failure')
64 })!
65 ex.try_post(fn [ran] () ! {
66 ran <- 2
67 })!
68
69 ex.run_one() or { assert err.msg() == 'owner failure' }
70 assert wait_for_int(ran, 'erroring job did not run') == 1
71
72 ex.run_one() or { assert err.msg() == 'owner failure' }
73 assert wait_for_int(ran, 'accepted job after error was not drained') == 2
74
75 ex.wait() or {
76 assert err.msg() == 'owner failure'
77 return
78 }
79 assert false, 'wait did not return the stored owner failure'
80}
81
82fn test_drain_pending_after_job_error_requires_continued_pumping_when_limit_is_reached() {
83 mut ex := new(queue_size: 4)!
84 ran := chan int{cap: 3}
85
86 ex.try_post(fn [ran] () ! {
87 ran <- 1
88 return error('owner failure')
89 })!
90 ex.try_post(fn [ran] () ! {
91 ran <- 2
92 })!
93 ex.try_post(fn [ran] () ! {
94 ran <- 3
95 })!
96
97 ex.drain_pending(1) or { assert err.msg() == 'owner failure' }
98 assert wait_for_int(ran, 'erroring drain job did not run') == 1
99
100 ex.drain_pending(8) or { assert err.msg() == 'owner failure' }
101 assert wait_for_int(ran, 'second accepted job was not drained') == 2
102 assert wait_for_int(ran, 'third accepted job was not drained') == 3
103
104 ex.wait() or {
105 assert err.msg() == 'owner failure'
106 return
107 }
108 assert false, 'wait did not return the stored owner failure'
109}
110
111fn wait_for_int(signal chan int, message string) int {
112 select {
113 value := <-signal {
114 return value
115 }
116 1 * time.second {
117 assert false, message
118 }
119 }
120 return 0
121}
122
123fn wait_for_string(signal chan string, message string) string {
124 select {
125 value := <-signal {
126 return value
127 }
128 1 * time.second {
129 assert false, message
130 }
131 }
132 return ''
133}
134