Mercurial > prosody-hg
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 |
| parents | fafb4036771c |
| children | 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() |
