resque-state 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.travis.yml +4 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +102 -0
- data/LICENSE +21 -0
- data/README.rdoc +208 -0
- data/Rakefile +48 -0
- data/examples/sleep_job.rb +36 -0
- data/init.rb +1 -0
- data/lib/resque/job_with_state.rb +5 -0
- data/lib/resque/plugins/state/hash.rb +326 -0
- data/lib/resque/plugins/state.rb +289 -0
- data/lib/resque/server/views/state.erb +91 -0
- data/lib/resque/server/views/state_styles.erb +104 -0
- data/lib/resque/server/views/statuses.erb +79 -0
- data/lib/resque/state.rb +8 -0
- data/lib/resque/state_server.rb +85 -0
- data/lib/resque-state.rb +1 -0
- data/resque-state.gemspec +65 -0
- data/test/test_helper.rb +100 -0
- data/test/test_resque_plugins_state.rb +426 -0
- data/test/test_resque_plugins_state_hash.rb +255 -0
- metadata +99 -0
@@ -0,0 +1,426 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
class TestResquePluginsStatus < Minitest::Test
|
5
|
+
def self.test_order
|
6
|
+
:sorted
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'Resque::Plugins::State' do
|
10
|
+
before do
|
11
|
+
Resque.redis.flushall
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.create' do
|
15
|
+
describe 'not inline' do
|
16
|
+
before do
|
17
|
+
@uuid = WorkingJob.create('num' => 100)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'add the job to the queue' do
|
21
|
+
assert_equal 1, Resque.size(:statused)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'set the queued object to the current class' do
|
25
|
+
job = Resque.pop(:statused)
|
26
|
+
assert_equal @uuid, job['args'].first
|
27
|
+
assert_equal 'WorkingJob', job['class']
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'add the uuid to the statuses' do
|
31
|
+
assert_includes Resque::Plugins::State::Hash.status_ids, @uuid
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'return a UUID' do
|
35
|
+
assert_match(/^\w{32}$/, @uuid)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'inline' do
|
40
|
+
before do
|
41
|
+
Resque.stubs(:inline?).returns(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'not queue a job' do
|
45
|
+
@uuid = WorkingJob.create('num' => 100)
|
46
|
+
assert_equal 0, Resque.size(:statused)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'call perform' do
|
50
|
+
WorkingJob.any_instance.expects(:perform).once
|
51
|
+
@uuid = WorkingJob.create('num' => 100)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '.create with a failing before_enqueue hook' do
|
57
|
+
before do
|
58
|
+
@size = Resque.size(:statused)
|
59
|
+
@status_ids_size = Resque::Plugins::State::Hash.status_ids.length
|
60
|
+
@res = NeverQueuedJob.create(num: 100)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'return nil' do
|
64
|
+
assert_equal nil, @res
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'not create a status' do
|
68
|
+
assert_equal @size, Resque.size(:statused)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'not add the uuid to the statuses' do
|
72
|
+
assert_equal @status_ids_size,
|
73
|
+
Resque::Plugins::State::Hash.status_ids.length
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '.scheduled' do
|
78
|
+
before do
|
79
|
+
@job_args = { 'num' => 100 }
|
80
|
+
@uuid = WorkingJob.scheduled(:queue_name, WorkingJob, @job_args)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'create the job with the provided arguments' do
|
84
|
+
job = Resque.pop(:queue_name)
|
85
|
+
assert_equal @job_args, job['args'].last
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '.enqueue' do
|
90
|
+
it 'delegate to enqueue_to, filling in the queue from the class' do
|
91
|
+
@uuid = BasicJob.enqueue(WorkingJob, num: 100)
|
92
|
+
@payload = Resque.pop(:statused)
|
93
|
+
assert_equal 'WorkingJob', @payload['class']
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.enqueue_to' do
|
98
|
+
before do
|
99
|
+
@uuid = BasicJob.enqueue_to(:new_queue, WorkingJob, num: 100)
|
100
|
+
@payload = Resque.pop(:new_queue)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'add the job with the specific class to the queue' do
|
104
|
+
assert_equal 'WorkingJob', @payload['class']
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'add the arguments to the options hash' do
|
108
|
+
assert_equal @uuid, @payload['args'].first
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'add the uuid to the statuses' do
|
112
|
+
assert_includes Resque::Plugins::State::Hash.status_ids, @uuid
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'return UUID' do
|
116
|
+
assert_match(/^\w{32}$/, @uuid)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '.dequeue' do
|
121
|
+
before do
|
122
|
+
@uuid1 = BasicJob.enqueue(WorkingJob, num: 100)
|
123
|
+
@uuid2 = BasicJob.enqueue(WorkingJob, num: 100)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'dequeue the job with the uuid from the correct queue' do
|
127
|
+
size = Resque.size(:statused)
|
128
|
+
BasicJob.dequeue(WorkingJob, @uuid2)
|
129
|
+
assert_equal size - 1, Resque.size(:statused)
|
130
|
+
end
|
131
|
+
it 'not dequeue any jobs with different uuids for same class name' do
|
132
|
+
BasicJob.dequeue(WorkingJob, @uuid2)
|
133
|
+
assert_equal @uuid1, Resque.pop(:statused)['args'].first
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '.perform' do
|
138
|
+
let(:expectation) {}
|
139
|
+
|
140
|
+
before do
|
141
|
+
expectation
|
142
|
+
@uuid = WorkingJob.create(num: 100)
|
143
|
+
@payload = Resque.pop(:statused)
|
144
|
+
@performed = WorkingJob.perform(*@payload['args'])
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'load load a new instance of the class' do
|
148
|
+
assert @performed.is_a?(WorkingJob)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'set the uuid' do
|
152
|
+
assert_equal @uuid, @performed.uuid
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'set the status' do
|
156
|
+
assert @performed.status.is_a?(Resque::Plugins::State::Hash)
|
157
|
+
assert_equal 'WorkingJob({"num"=>100})', @performed.status.name
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'before' do
|
161
|
+
let(:expectation) { WorkingJob.any_instance.expects(:perform).once }
|
162
|
+
it('call perform on the inherited class') {}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe 'manually failing a job' do
|
167
|
+
before do
|
168
|
+
@uuid = FailureJob.create(num: 100)
|
169
|
+
@payload = Resque.pop(:statused)
|
170
|
+
@performed = FailureJob.perform(*@payload['args'])
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'load load a new instance of the klass' do
|
174
|
+
assert @performed.is_a?(FailureJob)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'set the uuid' do
|
178
|
+
assert_equal @uuid, @performed.uuid
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'set the status' do
|
182
|
+
assert @performed.status.is_a?(Resque::Plugins::State::Hash)
|
183
|
+
assert_equal 'FailureJob({"num"=>100})', @performed.status.name
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'be failed' do
|
187
|
+
assert_match(/failure/, @performed.status.message)
|
188
|
+
assert @performed.status.failed?
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe 'killing a job' do
|
193
|
+
before do
|
194
|
+
@uuid = KillableJob.create(num: 100)
|
195
|
+
@payload = Resque.pop(:statused)
|
196
|
+
Resque::Plugins::State::Hash.kill(@uuid)
|
197
|
+
assert_includes Resque::Plugins::State::Hash.kill_ids, @uuid
|
198
|
+
@performed = KillableJob.perform(*@payload['args'])
|
199
|
+
@status = Resque::Plugins::State::Hash.get(@uuid)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'set the status to killed' do
|
203
|
+
assert @status.killed?
|
204
|
+
assert !@status.completed?
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'only perform iterations up to kill' do
|
208
|
+
assert_equal 1, Resque.redis.get("#{@uuid}:iterations").to_i
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'not persist the kill key' do
|
212
|
+
refute_includes Resque::Plugins::State::Hash.kill_ids, @uuid
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe 'killing all jobs' do
|
217
|
+
before do
|
218
|
+
@uuid1 = KillableJob.create(num: 100)
|
219
|
+
@uuid2 = KillableJob.create(num: 100)
|
220
|
+
|
221
|
+
Resque::Plugins::State::Hash.killall
|
222
|
+
|
223
|
+
assert_includes Resque::Plugins::State::Hash.kill_ids, @uuid1
|
224
|
+
assert_includes Resque::Plugins::State::Hash.kill_ids, @uuid2
|
225
|
+
|
226
|
+
@payload1 = Resque.pop(:statused)
|
227
|
+
@payload2 = Resque.pop(:statused)
|
228
|
+
|
229
|
+
@performed = KillableJob.perform(*@payload1['args'])
|
230
|
+
@performed = KillableJob.perform(*@payload2['args'])
|
231
|
+
|
232
|
+
@status1, @status2 =
|
233
|
+
Resque::Plugins::State::Hash.mget([@uuid1, @uuid2])
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'set the status to killed' do
|
237
|
+
assert @status1.killed?
|
238
|
+
assert !@status1.completed?
|
239
|
+
assert @status2.killed?
|
240
|
+
assert !@status2.completed?
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'only perform iterations up to kill' do
|
244
|
+
assert_equal 1, Resque.redis.get("#{@uuid1}:iterations").to_i
|
245
|
+
assert_equal 1, Resque.redis.get("#{@uuid2}:iterations").to_i
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'not persist the kill key' do
|
249
|
+
refute_includes Resque::Plugins::State::Hash.kill_ids, @uuid1
|
250
|
+
refute_includes Resque::Plugins::State::Hash.kill_ids, @uuid2
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe 'invoking killall jobs to kill a range' do
|
255
|
+
before do
|
256
|
+
@uuid1 = KillableJob.create(num: 100)
|
257
|
+
sleep 1 # Prevent inconsistent test results due to timing issues
|
258
|
+
@uuid2 = KillableJob.create(num: 100)
|
259
|
+
|
260
|
+
Resque::Plugins::State::Hash.killall(0, 0) # only @uuid2 it be killed
|
261
|
+
|
262
|
+
refute_includes Resque::Plugins::State::Hash.kill_ids, @uuid1
|
263
|
+
assert_includes Resque::Plugins::State::Hash.kill_ids, @uuid2
|
264
|
+
|
265
|
+
@payload1 = Resque.pop(:statused)
|
266
|
+
@payload2 = Resque.pop(:statused)
|
267
|
+
|
268
|
+
@performed = KillableJob.perform(*@payload1['args'])
|
269
|
+
@performed = KillableJob.perform(*@payload2['args'])
|
270
|
+
|
271
|
+
@status1, @status2 =
|
272
|
+
Resque::Plugins::State::Hash.mget([@uuid1, @uuid2])
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'set the status to killed' do
|
276
|
+
assert !@status1.killed?
|
277
|
+
assert @status1.completed?
|
278
|
+
assert @status2.killed?
|
279
|
+
assert !@status2.completed?
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'only perform iterations up to kill' do
|
283
|
+
assert_equal 100, Resque.redis.get("#{@uuid1}:iterations").to_i
|
284
|
+
assert_equal 1, Resque.redis.get("#{@uuid2}:iterations").to_i
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'not persist the kill key' do
|
288
|
+
refute_includes Resque::Plugins::State::Hash.kill_ids, @uuid1
|
289
|
+
refute_includes Resque::Plugins::State::Hash.kill_ids, @uuid2
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe 'pausing a job' do
|
294
|
+
before do
|
295
|
+
@uuid = SleeperJob.create(num: 100)
|
296
|
+
@payload = Resque.pop(:statused)
|
297
|
+
Resque::Plugins::State::Hash.pause(@uuid)
|
298
|
+
assert_includes Resque::Plugins::State::Hash.pause_ids, @uuid
|
299
|
+
@performed = SleeperJob.perform(*@payload['args'])
|
300
|
+
@status = Resque::Plugins::State::Hash.get(@uuid)
|
301
|
+
end
|
302
|
+
|
303
|
+
after do
|
304
|
+
Resque::Plugins::State::Hash.kill(@uuid)
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'set the status to paused' do
|
308
|
+
assert @status.paused?
|
309
|
+
assert !@status.completed?
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'only perform iterations up to pause' do
|
313
|
+
assert_equal 1, Resque.redis.get("#{@uuid}:iterations").to_i
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'persist the pause key' do
|
317
|
+
assert_includes Resque::Plugins::State::Hash.pause_ids, @uuid
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
describe 'unpausing a job' do
|
322
|
+
before do
|
323
|
+
@uuid = KillableJob.create(num: 100)
|
324
|
+
@payload = Resque.pop(:statused)
|
325
|
+
Resque::Plugins::State::Hash.pause(@uuid)
|
326
|
+
assert_includes Resque::Plugins::State::Hash.pause_ids, @uuid
|
327
|
+
Resque::Plugins::State::Hash.unpause(@uuid)
|
328
|
+
@performed = KillableJob.perform(*@payload['args'])
|
329
|
+
@status = Resque::Plugins::State::Hash.get(@uuid)
|
330
|
+
end
|
331
|
+
|
332
|
+
after do
|
333
|
+
Resque::Plugins::State::Hash.kill(@uuid)
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'set the status to completed' do
|
337
|
+
assert @status.completed?
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'perform all repetitions' do
|
341
|
+
assert_equal 100, Resque.redis.get("#{@uuid}:iterations").to_i
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'not persist the pause key' do
|
345
|
+
refute_includes Resque::Plugins::State::Hash.pause_ids, @uuid
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
describe 'with an invoked job' do
|
350
|
+
before do
|
351
|
+
@job = WorkingJob.new('123', 'num' => 100)
|
352
|
+
end
|
353
|
+
|
354
|
+
describe '#at' do
|
355
|
+
before do
|
356
|
+
@job.at(50, 100, 'At 50%')
|
357
|
+
end
|
358
|
+
|
359
|
+
it 'calculate percent' do
|
360
|
+
assert_equal 50, @job.status.pct_complete
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'set status' do
|
364
|
+
assert @job.status.working?
|
365
|
+
end
|
366
|
+
|
367
|
+
it 'save message' do
|
368
|
+
assert_equal 'At 50%', @job.status.message
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe '#failed' do
|
373
|
+
before do
|
374
|
+
@job.failed('OOOOPS!')
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'set status' do
|
378
|
+
assert @job.status.failed?
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'set message' do
|
382
|
+
assert_equal 'OOOOPS!', @job.status.message
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
describe '#completed' do
|
387
|
+
before do
|
388
|
+
@job.completed
|
389
|
+
end
|
390
|
+
|
391
|
+
it 'set status' do
|
392
|
+
assert @job.status.completed?
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'set message' do
|
396
|
+
assert_match(/complete/i, @job.status.message)
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'raises NaN for non-numbers' do
|
400
|
+
assert_raises Resque::Plugins::State::NotANumber do
|
401
|
+
@job.at('NaN', 'NaN', 'Nan')
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
describe '#safe_perform!' do
|
407
|
+
before do
|
408
|
+
@job = ErrorJob.new('123')
|
409
|
+
assert_raises(RuntimeError) do
|
410
|
+
@job.safe_perform!
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
it 'set status as failed' do
|
415
|
+
assert @job.status.failed?
|
416
|
+
end
|
417
|
+
it 'runs the on_failure hook' do
|
418
|
+
@job2 = ErrorJobOnFailure.new('123')
|
419
|
+
@job2.safe_perform!
|
420
|
+
assert @job2.status.failed?
|
421
|
+
assert_equal @job2.status['message'], "I'm such a terrible failure"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
class TestResquePluginsStatusHash < Minitest::Test
|
5
|
+
describe 'Resque::Plugins::State::Hash' do
|
6
|
+
before do
|
7
|
+
Resque.redis.flushall
|
8
|
+
Resque::Plugins::State::Hash.expire_in = nil
|
9
|
+
@uuid = Resque::Plugins::State::Hash.create(
|
10
|
+
Resque::Plugins::State::Hash.generate_uuid
|
11
|
+
)
|
12
|
+
Resque::Plugins::State::Hash.set(@uuid, 'my status')
|
13
|
+
@uuid_with_json = Resque::Plugins::State::Hash.create(
|
14
|
+
Resque::Plugins::State::Hash.generate_uuid, 'im' => 'json'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.get' do
|
19
|
+
it 'return the status as a Resque::Plugins::State::Hash for the uuid' do
|
20
|
+
status = Resque::Plugins::State::Hash.get(@uuid)
|
21
|
+
assert status.is_a?(Resque::Plugins::State::Hash)
|
22
|
+
assert_equal 'my status', status.message
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'return nil if the status is not set' do
|
26
|
+
assert_nil Resque::Plugins::State::Hash.get('invalid_uuid')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'decode encoded json' do
|
30
|
+
assert_equal('json',
|
31
|
+
Resque::Plugins::State::Hash.get(@uuid_with_json)['im'])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.mget' do
|
36
|
+
it 'return statuses array of Resque::Plugins::State::Hash for uuids' do
|
37
|
+
uuid2 = Resque::Plugins::State::Hash.create(
|
38
|
+
Resque::Plugins::State::Hash.generate_uuid
|
39
|
+
)
|
40
|
+
Resque::Plugins::State::Hash.set(uuid2, 'my status2')
|
41
|
+
statuses = Resque::Plugins::State::Hash.mget([@uuid, uuid2])
|
42
|
+
assert_equal 2, statuses.size
|
43
|
+
assert statuses.all? { |s| s.is_a?(Resque::Plugins::State::Hash) }
|
44
|
+
assert_equal ['my status', 'my status2'], statuses.map(&:message)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'return nil if a status is not set' do
|
48
|
+
statuses = Resque::Plugins::State::Hash.mget(['invalid_uuid', @uuid])
|
49
|
+
assert_equal 2, statuses.size
|
50
|
+
assert_nil statuses[0]
|
51
|
+
assert statuses[1].is_a?(Resque::Plugins::State::Hash)
|
52
|
+
assert_equal 'my status', statuses[1].message
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'decode encoded json' do
|
56
|
+
assert_equal ['json'],
|
57
|
+
Resque::Plugins::State::Hash.mget(
|
58
|
+
[@uuid_with_json]
|
59
|
+
).map { |h| h['im'] }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '.set' do
|
64
|
+
it 'set the status for the uuid' do
|
65
|
+
assert Resque::Plugins::State::Hash.set(@uuid, 'updated')
|
66
|
+
assert_equal 'updated', Resque::Plugins::State::Hash.get(@uuid).message
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'return the status' do
|
70
|
+
assert Resque::Plugins::State::Hash.set(
|
71
|
+
@uuid, 'updated'
|
72
|
+
).is_a?(Resque::Plugins::State::Hash)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '.create' do
|
77
|
+
it 'add an item to a key set' do
|
78
|
+
before = Resque::Plugins::State::Hash.status_ids.length
|
79
|
+
Resque::Plugins::State::Hash.create(
|
80
|
+
Resque::Plugins::State::Hash.generate_uuid
|
81
|
+
)
|
82
|
+
after = Resque::Plugins::State::Hash.status_ids.length
|
83
|
+
assert_equal 1, after - before
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'return a uuid' do
|
87
|
+
assert_match(/^\w{32}$/, Resque::Plugins::State::Hash.create(
|
88
|
+
Resque::Plugins::State::Hash.generate_uuid
|
89
|
+
))
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'store any status passed' do
|
93
|
+
uuid = Resque::Plugins::State::Hash.create(
|
94
|
+
Resque::Plugins::State::Hash.generate_uuid, 'initial status'
|
95
|
+
)
|
96
|
+
status = Resque::Plugins::State::Hash.get(uuid)
|
97
|
+
assert status.is_a?(Resque::Plugins::State::Hash)
|
98
|
+
assert_equal 'initial status', status.message
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'expire keys if expire_in is set' do
|
102
|
+
Resque::Plugins::State::Hash.expire_in = 1
|
103
|
+
uuid = Resque::Plugins::State::Hash.create(
|
104
|
+
Resque::Plugins::State::Hash.generate_uuid, 'new status'
|
105
|
+
)
|
106
|
+
assert_includes Resque::Plugins::State::Hash.status_ids, uuid
|
107
|
+
assert_equal 'new status',
|
108
|
+
Resque::Plugins::State::Hash.get(uuid).message
|
109
|
+
sleep 2
|
110
|
+
Resque::Plugins::State::Hash.create(
|
111
|
+
Resque::Plugins::State::Hash.generate_uuid
|
112
|
+
)
|
113
|
+
refute_includes Resque::Plugins::State::Hash.status_ids, uuid
|
114
|
+
assert_nil Resque::Plugins::State::Hash.get(uuid)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'store the options for the job created' do
|
118
|
+
uuid = Resque::Plugins::State::Hash.create(
|
119
|
+
Resque::Plugins::State::Hash.generate_uuid,
|
120
|
+
'new', options: { 'test' => '123' }
|
121
|
+
)
|
122
|
+
assert uuid
|
123
|
+
status = Resque::Plugins::State::Hash.get(uuid)
|
124
|
+
assert status.is_a?(Resque::Plugins::State::Hash)
|
125
|
+
assert_equal '123', status.options['test']
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '.clear' do
|
130
|
+
before do
|
131
|
+
Resque::Plugins::State::Hash.clear
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'clear any statuses' do
|
135
|
+
assert_nil Resque::Plugins::State::Hash.get(@uuid)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'clear any recent statuses' do
|
139
|
+
assert Resque::Plugins::State::Hash.status_ids.empty?
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '.clear_completed' do
|
144
|
+
before do
|
145
|
+
@completed_status_id = Resque::Plugins::State::Hash.create(
|
146
|
+
Resque::Plugins::State::Hash.generate_uuid, 'status' => 'completed'
|
147
|
+
)
|
148
|
+
@not_completed_status_id = Resque::Plugins::State::Hash.create(
|
149
|
+
Resque::Plugins::State::Hash.generate_uuid
|
150
|
+
)
|
151
|
+
Resque::Plugins::State::Hash.clear_completed
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'clear completed status' do
|
155
|
+
assert_nil Resque::Plugins::State::Hash.get(@completed_status_id)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'not clear not-completed status' do
|
159
|
+
status = Resque::Plugins::State::Hash.get(@not_completed_status_id)
|
160
|
+
assert status.is_a?(Resque::Plugins::State::Hash)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '.clear_failed' do
|
165
|
+
before do
|
166
|
+
@failed_status_id = Resque::Plugins::State::Hash.create(
|
167
|
+
Resque::Plugins::State::Hash.generate_uuid, 'status' => 'failed'
|
168
|
+
)
|
169
|
+
@not_failed_status_id = Resque::Plugins::State::Hash.create(
|
170
|
+
Resque::Plugins::State::Hash.generate_uuid
|
171
|
+
)
|
172
|
+
Resque::Plugins::State::Hash.clear_failed
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'clear failed status' do
|
176
|
+
assert_nil Resque::Plugins::State::Hash.get(@failed_status_id)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'not clear not-failed status' do
|
180
|
+
status = Resque::Plugins::State::Hash.get(@not_failed_status_id)
|
181
|
+
assert status.is_a?(Resque::Plugins::State::Hash)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '.remove' do
|
186
|
+
before do
|
187
|
+
Resque::Plugins::State::Hash.remove(@uuid)
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'clear specify status' do
|
191
|
+
assert_nil Resque::Plugins::State::Hash.get(@uuid)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '.status_ids' do
|
196
|
+
before do
|
197
|
+
@uuids = []
|
198
|
+
30.times do
|
199
|
+
Resque::Plugins::State::Hash.create(
|
200
|
+
Resque::Plugins::State::Hash.generate_uuid
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'return an array of job ids' do
|
206
|
+
assert Resque::Plugins::State::Hash.status_ids.is_a?(Array)
|
207
|
+
assert_equal 32, Resque::Plugins::State::Hash.status_ids.size # 30 + 2
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'let you paginate through the statuses' do
|
211
|
+
assert_equal Resque::Plugins::State::Hash.status_ids[0, 10],
|
212
|
+
Resque::Plugins::State::Hash.status_ids(0, 9)
|
213
|
+
assert_equal Resque::Plugins::State::Hash.status_ids[10, 10],
|
214
|
+
Resque::Plugins::State::Hash.status_ids(10, 19)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe '.statuses' do
|
219
|
+
it 'return an array status objects' do
|
220
|
+
statuses = Resque::Plugins::State::Hash.statuses
|
221
|
+
assert statuses.is_a?(Array)
|
222
|
+
assert_equal [@uuid_with_json, @uuid].sort, statuses.map(&:uuid).sort
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'return an empty array when no statuses are available' do
|
226
|
+
Resque.redis.flushall
|
227
|
+
statuses = Resque::Plugins::State::Hash.statuses
|
228
|
+
assert_equal [], statuses
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
Resque::Plugins::State::STATUSES.each do |status_code|
|
233
|
+
describe ".#{status_code}?" do
|
234
|
+
before do
|
235
|
+
uuid = Resque::Plugins::State::Hash.create(
|
236
|
+
Resque::Plugins::State::Hash.generate_uuid,
|
237
|
+
'status' => status_code
|
238
|
+
)
|
239
|
+
@status = Resque::Plugins::State::Hash.get(uuid)
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'return true for the current status' do
|
243
|
+
assert @status.send("#{status_code}?"), status_code
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'return false for other statuses' do
|
247
|
+
other_codes = Resque::Plugins::State::STATUSES - [status_code]
|
248
|
+
other_codes.each do |other_status_code|
|
249
|
+
assert !@status.send("#{other_status_code}?"), other_status_code
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|