Software /
code /
prosody
Comparison
spec/util_async_spec.lua @ 8618:680b1caa2dea
util.async: tests: replace peeking at internal state with monitoring correct callback behaviour
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 17 Mar 2018 17:59:58 +0000 |
parent | 8617:fafb4036771c |
child | 8622:92fee8a6c988 |
comparison
equal
deleted
inserted
replaced
8617:fafb4036771c | 8618:680b1caa2dea |
---|---|
83 end | 83 end |
84 assert.equal(last_item, values[#values]); | 84 assert.equal(last_item, values[#values]); |
85 end); | 85 end); |
86 | 86 |
87 describe("#errors", function () | 87 describe("#errors", function () |
88 describe("should notify", function () | |
89 local last_processed_item, last_error; | |
90 local r; | |
91 r = async.runner(function (item) | |
92 if item == "error" then | |
93 error({ e = "test error" }); | |
94 end | |
95 last_processed_item = item; | |
96 end, mock{ | |
97 ready = function () end; | |
98 waiting = function () end; | |
99 error = function (runner, err) | |
100 assert.equal(r, runner); | |
101 last_error = err; | |
102 end; | |
103 }); | |
104 | |
105 -- Simple item, no error | |
106 r:run("hello"); | |
107 assert.equal(r.state, "ready"); | |
108 assert.equal(last_processed_item, "hello"); | |
109 assert.spy(r.watchers.ready).was_not.called(); | |
110 assert.spy(r.watchers.error).was_not.called(); | |
111 | |
112 -- Trigger an error inside the runner | |
113 assert.equal(last_error, nil); | |
114 r:run("error"); | |
115 test("the correct watcher functions", function () | |
116 -- Only the error watcher should have been called | |
117 assert.spy(r.watchers.ready).was_not.called(); | |
118 assert.spy(r.watchers.waiting).was_not.called(); | |
119 assert.spy(r.watchers.error).was.called(1); | |
120 end); | |
121 test("with the correct error", function () | |
122 -- The error watcher state should be correct, to | |
123 -- demonstrate the error was passed correctly | |
124 assert.is_table(last_error); | |
125 assert.equal(last_error.e, "test error"); | |
126 last_error = nil; | |
127 end); | |
128 assert.equal(r.state, "ready"); | |
129 assert.equal(last_processed_item, "hello"); | |
130 end); | |
131 | |
132 | |
88 local last_processed_item, last_error; | 133 local last_processed_item, last_error; |
89 local r; | 134 local r; |
90 local wait, done; | 135 local wait, done; |
91 r = async.runner(function (item) | 136 r = async.runner(function (item) |
92 if item == "error" then | 137 if item == "error" then |
95 wait, done = async.waiter(); | 140 wait, done = async.waiter(); |
96 wait(); | 141 wait(); |
97 error({ e = "post wait error" }); | 142 error({ e = "post wait error" }); |
98 end | 143 end |
99 last_processed_item = item; | 144 last_processed_item = item; |
100 end, { | 145 end, mock({ |
146 ready = function () end; | |
147 waiting = function () end; | |
101 error = function (runner, err) | 148 error = function (runner, err) |
102 assert.equal(r, runner); | 149 assert.equal(r, runner); |
103 last_error = err; | 150 last_error = err; |
104 end; | 151 end; |
105 }); | 152 })); |
106 | 153 |
107 randomize(false); | 154 randomize(false); |
108 | 155 |
109 it("should notify", function () | |
110 local last_processed_item, last_error; | |
111 local r; | |
112 r = async.runner(function (item) | |
113 if item == "error" then | |
114 error({ e = "test error" }); | |
115 end | |
116 last_processed_item = item; | |
117 end, { | |
118 error = function (runner, err) | |
119 assert.equal(r, runner); | |
120 last_error = err; | |
121 end; | |
122 }); | |
123 | |
124 r:run("hello"); | |
125 assert.equal(r.state, "ready"); | |
126 assert.equal(last_processed_item, "hello"); | |
127 | |
128 assert.equal(last_error, nil); | |
129 r:run("error"); | |
130 assert.is_table(last_error); | |
131 assert.equal(last_error.e, "test error"); | |
132 last_error = nil; | |
133 assert.equal(r.state, "ready"); | |
134 assert.equal(last_processed_item, "hello"); | |
135 end); | |
136 it("should not be fatal to the runner", function () | 156 it("should not be fatal to the runner", function () |
137 r:run("world"); | 157 r:run("world"); |
138 assert.equal(r.state, "ready"); | 158 assert.equal(r.state, "ready"); |
159 assert.spy(r.watchers.ready).was_not.called(); | |
139 assert.equal(last_processed_item, "world"); | 160 assert.equal(last_processed_item, "world"); |
140 end); | 161 end); |
141 it("should work despite a #waiter", function () | 162 it("should work despite a #waiter", function () |
142 -- This test covers an important case where a runner | 163 -- This test covers an important case where a runner |
143 -- throws an error while being executed outside of the | 164 -- throws an error while being executed outside of the |
144 -- main loop. This happens when it was blocked ('waiting'), | 165 -- main loop. This happens when it was blocked ('waiting'), |
145 -- and then released (via a call to done()). | 166 -- and then released (via a call to done()). |
146 last_error = nil; | 167 last_error = nil; |
147 r:run("wait"); | 168 r:run("wait"); |
148 assert.equal(r.state, "waiting"); | 169 assert.equal(r.state, "waiting"); |
170 assert.spy(r.watchers.waiting).was.called(1); | |
149 done(); | 171 done(); |
150 -- At this point an error happens (state goes error->ready) | 172 -- At this point an error happens (state goes error->ready) |
151 assert.equal(r.state, "ready"); | 173 assert.equal(r.state, "ready"); |
174 assert.spy(r.watchers.error).was.called(1); | |
175 assert.spy(r.watchers.ready).was.called(1); | |
152 assert.is_table(last_error); | 176 assert.is_table(last_error); |
153 assert.equal(last_error.e, "post wait error"); | 177 assert.equal(last_error.e, "post wait error"); |
154 last_error = nil; | 178 last_error = nil; |
155 r:run("hello again"); | 179 r:run("hello again"); |
180 assert.spy(r.watchers.ready).was.called(1); | |
181 assert.spy(r.watchers.waiting).was.called(1); | |
182 assert.spy(r.watchers.error).was.called(1); | |
156 assert.equal(r.state, "ready"); | 183 assert.equal(r.state, "ready"); |
157 assert.equal(last_processed_item, "hello again"); | 184 assert.equal(last_processed_item, "hello again"); |
158 end); | 185 end); |
159 | 186 |
160 it("should continue to process work items", function () | 187 it("should continue to process work items", function () |
161 local wait, done, last_item; | 188 local wait, done, last_item; |
162 local runner_func = spy.new(function (item) | 189 local runner_func = spy.new(function (item) |
163 if item == "error" then | 190 if item == "error" then |
164 error("test error"); | 191 error("test error"); |
165 elseif item == "wait-error" then | 192 end |
193 last_item = item; | |
194 end); | |
195 local runner = async.runner(runner_func, mock{ | |
196 ready = function () end; | |
197 waiting = function () end; | |
198 error = function () end; | |
199 }); | |
200 runner:enqueue("one"); | |
201 runner:enqueue("error"); | |
202 runner:enqueue("two"); | |
203 runner:run(); | |
204 assert.equal(r.state, "ready"); | |
205 assert.spy(runner_func).was.called(3); | |
206 assert.spy(runner.watchers.error).was.called(1); | |
207 assert.spy(runner.watchers.ready).was.called(0); | |
208 assert.spy(runner.watchers.waiting).was.called(0); | |
209 assert.equal(last_item, "two"); | |
210 end); | |
211 | |
212 it("should continue to process work items during resume", function () | |
213 local wait, done, last_item; | |
214 local runner_func = spy.new(function (item) | |
215 if item == "wait-error" then | |
166 wait, done = async.waiter(); | 216 wait, done = async.waiter(); |
167 wait(); | 217 wait(); |
168 error("test error"); | 218 error("test error"); |
169 end | 219 end |
170 last_item = item; | 220 last_item = item; |
171 end); | 221 end); |
172 local runner = async.runner(runner_func, { error = spy.new(function () end) }); | 222 local runner = async.runner(runner_func, mock{ |
173 runner:enqueue("one"); | 223 ready = function () end; |
174 runner:enqueue("error"); | 224 waiting = function () end; |
175 runner:enqueue("two"); | 225 error = function () end; |
176 runner:run(); | 226 }); |
177 assert.equal(r.state, "ready"); | |
178 assert.equal(r.state, r.notified_state); | |
179 assert.spy(runner_func).was.called(3); | |
180 assert.spy(runner.watchers.error).was.called(1); | |
181 assert.equal(last_item, "two"); | |
182 end); | |
183 | |
184 it("should continue to process work items during resume", function () | |
185 local wait, done, last_item; | |
186 local runner_func = spy.new(function (item) | |
187 if item == "error" then | |
188 error("test error"); | |
189 elseif item == "wait-error" then | |
190 wait, done = async.waiter(); | |
191 wait(); | |
192 error("test error"); | |
193 end | |
194 last_item = item; | |
195 end); | |
196 local runner = async.runner(runner_func, { error = spy.new(function () end) }); | |
197 runner:enqueue("one"); | 227 runner:enqueue("one"); |
198 runner:enqueue("wait-error"); | 228 runner:enqueue("wait-error"); |
199 runner:enqueue("two"); | 229 runner:enqueue("two"); |
200 runner:run(); | 230 runner:run(); |
201 done(); | 231 done(); |
202 assert.equal(r.state, "ready"); | 232 assert.equal(r.state, "ready"); |
203 assert.equal(r.state, r.notified_state); | |
204 assert.spy(runner_func).was.called(3); | 233 assert.spy(runner_func).was.called(3); |
205 assert.spy(runner.watchers.error).was.called(1); | 234 assert.spy(runner.watchers.error).was.called(1); |
235 assert.spy(runner.watchers.waiting).was.called(1); | |
236 assert.spy(runner.watchers.ready).was.called(1); | |
206 assert.equal(last_item, "two"); | 237 assert.equal(last_item, "two"); |
207 end); | 238 end); |
208 end); | 239 end); |
209 end); | 240 end); |
210 describe("#waiter", function() | 241 describe("#waiter", function() |