Software /
code /
prosody
Annotate
spec/util_async_spec.lua @ 8608:a2e6caf5848d
util.async: Add test to ensure waiters throw an error outside async contexts
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 16 Mar 2018 22:19:33 +0000 |
parent | 8607:62bb06cf8a43 |
child | 8609:9f6ab206d741 |
rev | line source |
---|---|
8605 | 1 local async = require "util.async"; |
2 | |
3 describe("util.async", function() | |
4 local debug = false; | |
5 local print = print; | |
6 if debug then | |
7 require "util.logger".add_simple_sink(print); | |
8 else | |
9 print = function () end | |
10 end | |
11 local function new(func, name) | |
12 local log = {}; | |
13 return async.runner(func, setmetatable({}, { | |
14 __index = function (_, event) | |
15 return function (runner, err) | |
16 print(name, "event", event, err) | |
17 print "--" | |
18 table.insert(log, { event = event, err = err }); | |
19 end; | |
20 end; | |
21 })), log; | |
22 end | |
23 describe("#runner", function() | |
24 it("should work", function() | |
25 local r, l = new(function (item) assert(type(item) == "number") end); | |
26 r:run(1); | |
27 r:run(2); | |
28 end); | |
8607
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
29 |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
30 it("should be ready after creation", function () |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
31 local r = async.runner(function (item) end); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
32 assert.equal(r.state, "ready"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
33 end); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
34 |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
35 describe("#errors", function () |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
36 local last_processed_item, last_error; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
37 local r; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
38 r = async.runner(function (item) |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
39 if item == "error" then |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
40 error({ e = "test error" }); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
41 end |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
42 last_processed_item = item; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
43 end, { |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
44 error = function (runner, err) |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
45 assert.equal(r, runner); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
46 last_error = err; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
47 end; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
48 }); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
49 |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
50 randomize(false); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
51 |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
52 it("should notify", function () |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
53 local last_processed_item, last_error; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
54 local r; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
55 r = async.runner(function (item) |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
56 if item == "error" then |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
57 error({ e = "test error" }); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
58 end |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
59 last_processed_item = item; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
60 end, { |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
61 error = function (runner, err) |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
62 assert.equal(r, runner); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
63 last_error = err; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
64 end; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
65 }); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
66 |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
67 r:run("hello"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
68 assert.equal(r.state, "ready"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
69 assert.equal(last_processed_item, "hello"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
70 |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
71 assert.equal(last_error, nil); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
72 r:run("error"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
73 assert.is_table(last_error); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
74 assert.equal(last_error.e, "test error"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
75 last_error = nil; |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
76 assert.equal(r.state, "ready"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
77 assert.equal(last_processed_item, "hello"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
78 end); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
79 it("should not be fatal to the runner", function () |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
80 r:run("world"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
81 assert.equal(r.state, "ready"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
82 assert.equal(last_processed_item, "world"); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
83 end); |
62bb06cf8a43
util.async: Add tests to specifically cover error handling
Matthew Wild <mwild1@gmail.com>
parents:
8605
diff
changeset
|
84 end); |
8605 | 85 end); |
86 describe("#waiter", function() | |
8608
a2e6caf5848d
util.async: Add test to ensure waiters throw an error outside async contexts
Matthew Wild <mwild1@gmail.com>
parents:
8607
diff
changeset
|
87 it("should error outside of async context", function () |
a2e6caf5848d
util.async: Add test to ensure waiters throw an error outside async contexts
Matthew Wild <mwild1@gmail.com>
parents:
8607
diff
changeset
|
88 assert.has_error(function () |
a2e6caf5848d
util.async: Add test to ensure waiters throw an error outside async contexts
Matthew Wild <mwild1@gmail.com>
parents:
8607
diff
changeset
|
89 async.waiter(); |
a2e6caf5848d
util.async: Add test to ensure waiters throw an error outside async contexts
Matthew Wild <mwild1@gmail.com>
parents:
8607
diff
changeset
|
90 end); |
a2e6caf5848d
util.async: Add test to ensure waiters throw an error outside async contexts
Matthew Wild <mwild1@gmail.com>
parents:
8607
diff
changeset
|
91 end); |
8605 | 92 it("should work", function () |
93 local wait, done; | |
94 | |
95 local r, l = new(function (item) | |
96 assert(type(item) == "number") | |
97 if item == 3 then | |
98 wait, done = async.waiter(); | |
99 wait(); | |
100 end | |
101 end); | |
102 | |
103 r:run(1); | |
104 assert(r.state == "ready"); | |
105 r:run(2); | |
106 assert(r.state == "ready"); | |
107 r:run(3); | |
108 assert(r.state == "waiting"); | |
109 done(); | |
110 assert(r.state == "ready"); | |
111 --for k, v in ipairs(l) do print(k,v) end | |
112 end); | |
113 | |
114 it("should work", function () | |
115 -------------------- | |
116 local wait, done; | |
117 local last_item = 0; | |
118 local r, l = new(function (item) | |
119 assert(type(item) == "number") | |
120 assert(item == last_item + 1); | |
121 last_item = item; | |
122 if item == 3 then | |
123 wait, done = async.waiter(); | |
124 wait(); | |
125 end | |
126 end); | |
127 | |
128 r:run(1); | |
129 assert(r.state == "ready"); | |
130 r:run(2); | |
131 assert(r.state == "ready"); | |
132 r:run(3); | |
133 assert(r.state == "waiting"); | |
134 r:run(4); | |
135 assert(r.state == "waiting"); | |
136 done(); | |
137 assert(r.state == "ready"); | |
138 --for k, v in ipairs(l) do print(k,v) end | |
139 end); | |
140 it("should work", function () | |
141 -------------------- | |
142 local wait, done; | |
143 local last_item = 0; | |
144 local r, l = new(function (item) | |
145 assert(type(item) == "number") | |
146 assert((item == last_item + 1) or item == 3); | |
147 last_item = item; | |
148 if item == 3 then | |
149 wait, done = async.waiter(); | |
150 wait(); | |
151 end | |
152 end); | |
153 | |
154 r:run(1); | |
155 assert(r.state == "ready"); | |
156 r:run(2); | |
157 assert(r.state == "ready"); | |
158 | |
159 local dones = {}; | |
160 r:run(3); | |
161 assert(r.state == "waiting"); | |
162 r:run(3); | |
163 assert(r.state == "waiting"); | |
164 r:run(3); | |
165 assert(r.state == "waiting"); | |
166 r:run(4); | |
167 assert(r.state == "waiting"); | |
168 | |
169 for i = 1, 3 do | |
170 done(); | |
171 if i < 3 then | |
172 assert(r.state == "waiting"); | |
173 end | |
174 end | |
175 | |
176 assert(r.state == "ready"); | |
177 --for k, v in ipairs(l) do print(k,v) end | |
178 end); | |
179 it("should work", function () | |
180 -------------------- | |
181 local wait, done; | |
182 local last_item = 0; | |
183 local r, l = new(function (item) | |
184 assert(type(item) == "number") | |
185 assert((item == last_item + 1) or item == 3); | |
186 last_item = item; | |
187 if item == 3 then | |
188 wait, done = async.waiter(); | |
189 wait(); | |
190 end | |
191 end); | |
192 | |
193 r:run(1); | |
194 assert(r.state == "ready"); | |
195 r:run(2); | |
196 assert(r.state == "ready"); | |
197 | |
198 local dones = {}; | |
199 r:run(3); | |
200 assert(r.state == "waiting"); | |
201 r:run(3); | |
202 assert(r.state == "waiting"); | |
203 | |
204 for i = 1, 2 do | |
205 done(); | |
206 if i < 2 then | |
207 assert(r.state == "waiting"); | |
208 end | |
209 end | |
210 | |
211 assert(r.state == "ready"); | |
212 r:run(4); | |
213 assert(r.state == "ready"); | |
214 | |
215 assert(r.state == "ready"); | |
216 --for k, v in ipairs(l) do print(k,v) end | |
217 end); | |
218 it("should work with multiple runners in parallel", function () | |
219 -- Now with multiple runners | |
220 -------------------- | |
221 local wait1, done1; | |
222 local last_item1 = 0; | |
223 local r1, l1 = new(function (item) | |
224 assert(type(item) == "number") | |
225 assert((item == last_item1 + 1) or item == 3); | |
226 last_item1 = item; | |
227 if item == 3 then | |
228 wait1, done1 = async.waiter(); | |
229 wait1(); | |
230 end | |
231 end, "r1"); | |
232 | |
233 local wait2, done2; | |
234 local last_item2 = 0; | |
235 local r2, l2 = new(function (item) | |
236 assert(type(item) == "number") | |
237 assert((item == last_item2 + 1) or item == 3); | |
238 last_item2 = item; | |
239 if item == 3 then | |
240 wait2, done2 = async.waiter(); | |
241 wait2(); | |
242 end | |
243 end, "r2"); | |
244 | |
245 r1:run(1); | |
246 assert(r1.state == "ready"); | |
247 r1:run(2); | |
248 assert(r1.state == "ready"); | |
249 | |
250 local dones = {}; | |
251 r1:run(3); | |
252 assert(r1.state == "waiting"); | |
253 r1:run(3); | |
254 assert(r1.state == "waiting"); | |
255 | |
256 r2:run(1); | |
257 assert(r1.state == "waiting"); | |
258 assert(r2.state == "ready"); | |
259 | |
260 r2:run(2); | |
261 assert(r1.state == "waiting"); | |
262 assert(r2.state == "ready"); | |
263 | |
264 r2:run(3); | |
265 assert(r1.state == "waiting"); | |
266 assert(r2.state == "waiting"); | |
267 done2(); | |
268 | |
269 r2:run(3); | |
270 assert(r1.state == "waiting"); | |
271 assert(r2.state == "waiting"); | |
272 done2(); | |
273 | |
274 r2:run(4); | |
275 assert(r1.state == "waiting"); | |
276 assert(r2.state == "ready"); | |
277 | |
278 for i = 1, 2 do | |
279 done1(); | |
280 if i < 2 then | |
281 assert(r1.state == "waiting"); | |
282 end | |
283 end | |
284 | |
285 assert(r1.state == "ready"); | |
286 r1:run(4); | |
287 assert(r1.state == "ready"); | |
288 | |
289 assert(r1.state == "ready"); | |
290 --for k, v in ipairs(l1) do print(k,v) end | |
291 end); | |
292 it("should work work with multiple runners in parallel", function () | |
293 -------------------- | |
294 local wait1, done1; | |
295 local last_item1 = 0; | |
296 local r1, l1 = new(function (item) | |
297 print("r1 processing ", item); | |
298 assert(type(item) == "number") | |
299 assert((item == last_item1 + 1) or item == 3); | |
300 last_item1 = item; | |
301 if item == 3 then | |
302 wait1, done1 = async.waiter(); | |
303 wait1(); | |
304 end | |
305 end, "r1"); | |
306 | |
307 local wait2, done2; | |
308 local last_item2 = 0; | |
309 local r2, l2 = new(function (item) | |
310 print("r2 processing ", item); | |
311 assert.is_number(item); | |
312 assert((item == last_item2 + 1) or item == 3); | |
313 last_item2 = item; | |
314 if item == 3 then | |
315 wait2, done2 = async.waiter(); | |
316 wait2(); | |
317 end | |
318 end, "r2"); | |
319 | |
320 r1:run(1); | |
321 assert.equal(r1.state, "ready"); | |
322 r1:run(2); | |
323 assert.equal(r1.state, "ready"); | |
324 | |
325 r1:run(5); | |
326 assert.equal(r1.state, "ready"); | |
327 | |
328 local dones = {}; | |
329 r1:run(3); | |
330 assert.equal(r1.state, "waiting"); | |
331 r1:run(5); -- Will error, when we get to it | |
332 assert.equal(r1.state, "waiting"); | |
333 done1(); | |
334 assert.equal(r1.state, "ready"); | |
335 r1:run(3); | |
336 assert.equal(r1.state, "waiting"); | |
337 | |
338 r2:run(1); | |
339 assert.equal(r1.state, "waiting"); | |
340 assert.equal(r2.state, "ready"); | |
341 | |
342 r2:run(2); | |
343 assert.equal(r1.state, "waiting"); | |
344 assert.equal(r2.state, "ready"); | |
345 | |
346 r2:run(3); | |
347 assert.equal(r1.state, "waiting"); | |
348 assert.equal(r2.state, "waiting"); | |
349 | |
350 done2(); | |
351 assert.equal(r1.state, "waiting"); | |
352 assert.equal(r2.state, "ready"); | |
353 | |
354 r2:run(3); | |
355 assert.equal(r1.state, "waiting"); | |
356 assert.equal(r2.state, "waiting"); | |
357 | |
358 done2(); | |
359 assert.equal(r1.state, "waiting"); | |
360 assert.equal(r2.state, "ready"); | |
361 | |
362 r2:run(4); | |
363 assert.equal(r1.state, "waiting"); | |
364 assert.equal(r2.state, "ready"); | |
365 | |
366 done1(); | |
367 | |
368 assert.equal(r1.state, "ready"); | |
369 r1:run(4); | |
370 assert.equal(r1.state, "ready"); | |
371 | |
372 assert.equal(r1.state, "ready"); | |
373 --for k, v in ipairs(l1) do print(k,v) end | |
374 end); | |
375 end); | |
376 end); |