sidekiq 5.0.0.beta1 → 5.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sidekiq might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Changes.md +6 -0
- data/Pro-Changes.md +3 -2
- data/bin/sidekiqload +11 -11
- data/lib/sidekiq/api.rb +15 -8
- data/lib/sidekiq/job_retry.rb +15 -12
- data/lib/sidekiq/processor.rb +3 -2
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/application.rb +1 -1
- data/lib/sidekiq/web/helpers.rb +2 -1
- data/sidekiq.gemspec +2 -2
- data/web/views/retry.erb +1 -1
- metadata +3 -67
- data/test/config.yml +0 -9
- data/test/env_based_config.yml +0 -11
- data/test/fake_env.rb +0 -1
- data/test/fixtures/en.yml +0 -2
- data/test/helper.rb +0 -98
- data/test/test_actors.rb +0 -138
- data/test/test_api.rb +0 -529
- data/test/test_cli.rb +0 -418
- data/test/test_client.rb +0 -266
- data/test/test_exception_handler.rb +0 -56
- data/test/test_extensions.rb +0 -115
- data/test/test_fetch.rb +0 -50
- data/test/test_launcher.rb +0 -92
- data/test/test_logging.rb +0 -35
- data/test/test_manager.rb +0 -50
- data/test/test_middleware.rb +0 -158
- data/test/test_processor.rb +0 -266
- data/test/test_rails.rb +0 -22
- data/test/test_redis_connection.rb +0 -132
- data/test/test_retry.rb +0 -335
- data/test/test_retry_exhausted.rb +0 -149
- data/test/test_scheduled.rb +0 -115
- data/test/test_scheduling.rb +0 -58
- data/test/test_sidekiq.rb +0 -107
- data/test/test_testing.rb +0 -135
- data/test/test_testing_fake.rb +0 -352
- data/test/test_testing_inline.rb +0 -93
- data/test/test_util.rb +0 -13
- data/test/test_web.rb +0 -638
- data/test/test_web_auth.rb +0 -54
- data/test/test_web_helpers.rb +0 -54
- data/test/test_web_sessions.rb +0 -67
data/test/test_web.rb
DELETED
@@ -1,638 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
require_relative 'helper'
|
4
|
-
require 'sidekiq/web'
|
5
|
-
require 'rack/test'
|
6
|
-
require 'timecop'
|
7
|
-
require 'mocha/mini_test'
|
8
|
-
|
9
|
-
# Tests in this file are a combination of:
|
10
|
-
# - Capybara tests (using visit) which render the web ui and check elements.
|
11
|
-
# The Capybara tests use Percy.io for visual regression testing.
|
12
|
-
# - Rack::Tests (using get & post) for increased speed and simplicity,
|
13
|
-
# when we're testing actions rather than UI presentation.
|
14
|
-
|
15
|
-
class TestWeb < Sidekiq::Test
|
16
|
-
describe 'sidekiq web' do
|
17
|
-
|
18
|
-
include Rack::Test::Methods
|
19
|
-
include Capybara::DSL
|
20
|
-
|
21
|
-
def app
|
22
|
-
Sidekiq::Web
|
23
|
-
end
|
24
|
-
|
25
|
-
def job_params(job, score)
|
26
|
-
"#{score}-#{job['jid']}"
|
27
|
-
end
|
28
|
-
|
29
|
-
before do
|
30
|
-
Sidekiq.redis {|c| c.flushdb }
|
31
|
-
|
32
|
-
Capybara.current_driver = :poltergeist
|
33
|
-
Capybara.app = app
|
34
|
-
|
35
|
-
# Freeze time so the time doesn't change in subsequent UI snapshots
|
36
|
-
Timecop.freeze(Time.utc(2016, 9, 1, 10, 5, 0))
|
37
|
-
# Stub redis_info so memory usage doesn't change in subsequent UI snapshots
|
38
|
-
Sidekiq.stubs(:redis_info).returns(Sidekiq::FAKE_INFO)
|
39
|
-
end
|
40
|
-
|
41
|
-
after do
|
42
|
-
Sidekiq.unstub(:redis_info)
|
43
|
-
Timecop.return
|
44
|
-
Capybara.use_default_driver
|
45
|
-
end
|
46
|
-
|
47
|
-
class WebWorker
|
48
|
-
include Sidekiq::Worker
|
49
|
-
|
50
|
-
def perform(a, b)
|
51
|
-
a + b
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'can configure via set() syntax' do
|
56
|
-
app.set(:session_secret, "foo")
|
57
|
-
assert_equal "foo", app.session_secret
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'can show text with any locales' do
|
61
|
-
page.driver.headers = { 'Accept-Language' => 'ru,en' }
|
62
|
-
visit '/'
|
63
|
-
assert_text('Панель управления')
|
64
|
-
snapshot(page, name: 'Dashboard (Russian)')
|
65
|
-
|
66
|
-
page.driver.headers = { 'Accept-Language' => 'es,en' }
|
67
|
-
visit '/'
|
68
|
-
assert_text('Panel de Control')
|
69
|
-
snapshot(page, name: 'Dashboard (Spanish)')
|
70
|
-
|
71
|
-
page.driver.headers = { 'Accept-Language' => 'en-us' }
|
72
|
-
visit '/'
|
73
|
-
assert_text('Dashboard')
|
74
|
-
snapshot(page, name: 'Dashboard (English)')
|
75
|
-
|
76
|
-
page.driver.headers = { 'Accept-Language' => 'zh-cn' }
|
77
|
-
visit '/'
|
78
|
-
assert_text('信息板')
|
79
|
-
snapshot(page, name: 'Dashboard (Chinese)')
|
80
|
-
|
81
|
-
page.driver.headers = { 'Accept-Language' => 'zh-tw' }
|
82
|
-
visit '/'
|
83
|
-
assert_text('資訊主頁')
|
84
|
-
snapshot(page, name: 'Dashboard (Taiwanese)')
|
85
|
-
|
86
|
-
page.driver.headers = { 'Accept-Language' => 'nb' }
|
87
|
-
visit '/'
|
88
|
-
assert_text('Oversikt')
|
89
|
-
snapshot(page, name: 'Dashboard (Norwegian)')
|
90
|
-
|
91
|
-
page.driver.headers = { 'Accept-Language' => 'en-us' }
|
92
|
-
end
|
93
|
-
|
94
|
-
describe 'busy' do
|
95
|
-
|
96
|
-
it 'can display workers' do
|
97
|
-
Sidekiq.redis do |conn|
|
98
|
-
conn.incr('busy')
|
99
|
-
conn.sadd('processes', 'foo:1234')
|
100
|
-
conn.hmset('foo:1234', 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
|
101
|
-
identity = 'foo:1234:workers'
|
102
|
-
hash = {:queue => 'critical', :payload => { 'class' => WebWorker.name, 'args' => [1,'abc'] }, :run_at => Time.now.to_i }
|
103
|
-
conn.hmset(identity, 1001, Sidekiq.dump_json(hash))
|
104
|
-
end
|
105
|
-
assert_equal ['1001'], Sidekiq::Workers.new.map { |pid, tid, data| tid }
|
106
|
-
|
107
|
-
visit '/busy'
|
108
|
-
assert_equal 200, page.status_code
|
109
|
-
assert_selector('.status-active')
|
110
|
-
assert_text('critical')
|
111
|
-
assert_text('WebWorker')
|
112
|
-
|
113
|
-
assert has_button?('Quiet All')
|
114
|
-
assert has_button?('Stop All')
|
115
|
-
|
116
|
-
# Check the processes table has 2 rows - the header and process row
|
117
|
-
assert_equal 2, page.all('table.processes tr').count
|
118
|
-
assert has_button?('Quiet')
|
119
|
-
assert has_button?('Stop')
|
120
|
-
|
121
|
-
snapshot(page, name: 'Busy Page')
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'can quiet a process' do
|
125
|
-
identity = 'identity'
|
126
|
-
signals_key = "#{identity}-signals"
|
127
|
-
|
128
|
-
assert_nil Sidekiq.redis { |c| c.lpop signals_key }
|
129
|
-
post '/busy', 'quiet' => '1', 'identity' => identity
|
130
|
-
assert_equal 302, last_response.status
|
131
|
-
assert_equal 'TSTP', Sidekiq.redis { |c| c.lpop signals_key }
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'can stop a process' do
|
135
|
-
identity = 'identity'
|
136
|
-
signals_key = "#{identity}-signals"
|
137
|
-
|
138
|
-
assert_nil Sidekiq.redis { |c| c.lpop signals_key }
|
139
|
-
post '/busy', 'stop' => '1', 'identity' => identity
|
140
|
-
assert_equal 302, last_response.status
|
141
|
-
assert_equal 'TERM', Sidekiq.redis { |c| c.lpop signals_key }
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe 'queues' do
|
146
|
-
it 'can display queues' do
|
147
|
-
assert Sidekiq::Client.push('queue' => :foo, 'class' => WebWorker, 'args' => [1, 3])
|
148
|
-
|
149
|
-
visit '/queues'
|
150
|
-
assert_equal 200, page.status_code
|
151
|
-
assert_text('foo')
|
152
|
-
assert_no_text('HardWorker')
|
153
|
-
snapshot(page, name: 'Queues Page')
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'handles queue view' do
|
157
|
-
visit '/queues/default'
|
158
|
-
assert_equal 200, page.status_code
|
159
|
-
snapshot(page, name: 'Queue Page')
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'can delete a queue' do
|
163
|
-
Sidekiq.redis do |conn|
|
164
|
-
conn.rpush('queue:foo', '{}')
|
165
|
-
conn.sadd('queues', 'foo')
|
166
|
-
end
|
167
|
-
|
168
|
-
get '/queues/foo'
|
169
|
-
assert_equal 200, last_response.status
|
170
|
-
|
171
|
-
post '/queues/foo'
|
172
|
-
assert_equal 302, last_response.status
|
173
|
-
|
174
|
-
Sidekiq.redis do |conn|
|
175
|
-
refute conn.smembers('queues').include?('foo')
|
176
|
-
refute conn.exists('queue:foo')
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
it 'can delete a job' do
|
181
|
-
Sidekiq.redis do |conn|
|
182
|
-
conn.rpush('queue:foo', "{}")
|
183
|
-
conn.rpush('queue:foo', "{\"foo\":\"bar\"}")
|
184
|
-
conn.rpush('queue:foo', "{\"foo2\":\"bar2\"}")
|
185
|
-
end
|
186
|
-
|
187
|
-
get '/queues/foo'
|
188
|
-
assert_equal 200, last_response.status
|
189
|
-
|
190
|
-
post '/queues/foo/delete', key_val: "{\"foo\":\"bar\"}"
|
191
|
-
assert_equal 302, last_response.status
|
192
|
-
|
193
|
-
Sidekiq.redis do |conn|
|
194
|
-
refute conn.lrange('queue:foo', 0, -1).include?("{\"foo\":\"bar\"}")
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
|
200
|
-
describe 'retries' do
|
201
|
-
it 'can display retries' do
|
202
|
-
visit '/retries'
|
203
|
-
assert_equal 200, page.status_code
|
204
|
-
assert_text('No retries were found')
|
205
|
-
assert_no_text('HardWorker')
|
206
|
-
snapshot(page, name: 'Retries Page - No Retries')
|
207
|
-
|
208
|
-
add_retry
|
209
|
-
|
210
|
-
visit '/retries'
|
211
|
-
assert_equal 200, page.status_code
|
212
|
-
assert_no_text('No retries were found')
|
213
|
-
assert_text('HardWorker')
|
214
|
-
snapshot(page, name: 'Retries Page - With Retry')
|
215
|
-
end
|
216
|
-
|
217
|
-
it 'can display a single retry' do
|
218
|
-
params = add_retry 'abc'
|
219
|
-
visit "/retries/#{job_params(*params)}"
|
220
|
-
assert_equal 200, page.status_code
|
221
|
-
assert_text('HardWorker')
|
222
|
-
snapshot(page, name: 'Single Retry Page')
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'will redirect to retries when viewing a non-existant retry' do
|
226
|
-
get '/retries/0-shouldntexist'
|
227
|
-
assert_equal 302, last_response.status
|
228
|
-
assert_equal 'http://example.org/retries', last_response.header['Location']
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'can delete a single retry' do
|
232
|
-
params = add_retry
|
233
|
-
post "/retries/#{job_params(*params)}", 'delete' => 'Delete'
|
234
|
-
assert_equal 302, last_response.status
|
235
|
-
assert_equal 'http://example.org/retries', last_response.header['Location']
|
236
|
-
|
237
|
-
get "/retries"
|
238
|
-
assert_equal 200, last_response.status
|
239
|
-
refute_match(/#{params.first['args'][2]}/, last_response.body)
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'can delete all retries' do
|
243
|
-
3.times { add_retry }
|
244
|
-
|
245
|
-
post "/retries/all/delete", 'delete' => 'Delete'
|
246
|
-
assert_equal 0, Sidekiq::RetrySet.new.size
|
247
|
-
assert_equal 302, last_response.status
|
248
|
-
assert_equal 'http://example.org/retries', last_response.header['Location']
|
249
|
-
end
|
250
|
-
|
251
|
-
it 'can retry a single retry now' do
|
252
|
-
params = add_retry
|
253
|
-
post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
|
254
|
-
assert_equal 302, last_response.status
|
255
|
-
assert_equal 'http://example.org/retries', last_response.header['Location']
|
256
|
-
|
257
|
-
get '/queues/default'
|
258
|
-
assert_equal 200, last_response.status
|
259
|
-
assert_match(/#{params.first['args'][2]}/, last_response.body)
|
260
|
-
end
|
261
|
-
|
262
|
-
it 'can kill a single retry now' do
|
263
|
-
params = add_retry
|
264
|
-
post "/retries/#{job_params(*params)}", 'kill' => 'Kill'
|
265
|
-
assert_equal 302, last_response.status
|
266
|
-
assert_equal 'http://example.org/retries', last_response.header['Location']
|
267
|
-
|
268
|
-
get '/morgue'
|
269
|
-
assert_equal 200, last_response.status
|
270
|
-
assert_match(/#{params.first['args'][2]}/, last_response.body)
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'can retry all retries' do
|
274
|
-
msg = add_retry.first
|
275
|
-
add_retry
|
276
|
-
|
277
|
-
post "/retries/all/retry", 'retry' => 'Retry'
|
278
|
-
assert_equal 302, last_response.status
|
279
|
-
assert_equal 'http://example.org/retries', last_response.header['Location']
|
280
|
-
assert_equal 2, Sidekiq::Queue.new("default").size
|
281
|
-
|
282
|
-
get '/queues/default'
|
283
|
-
assert_equal 200, last_response.status
|
284
|
-
assert_match(/#{msg['args'][2]}/, last_response.body)
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
describe 'scheduled' do
|
289
|
-
it 'can display scheduled' do
|
290
|
-
visit '/scheduled'
|
291
|
-
assert_equal 200, page.status_code
|
292
|
-
assert_text('found')
|
293
|
-
assert_no_text('HardWorker')
|
294
|
-
snapshot(page, name: 'Scheduled Jobs Page - Nothing Scheduled')
|
295
|
-
|
296
|
-
add_scheduled
|
297
|
-
|
298
|
-
visit '/scheduled'
|
299
|
-
assert_equal 200, page.status_code
|
300
|
-
assert_no_text('found')
|
301
|
-
assert_text('HardWorker')
|
302
|
-
snapshot(page, name: 'Scheduled Jobs Page - Job Scheduled')
|
303
|
-
end
|
304
|
-
|
305
|
-
it 'can display a single scheduled job' do
|
306
|
-
params = add_scheduled 'abc'
|
307
|
-
visit "/scheduled/#{job_params(*params)}"
|
308
|
-
assert_equal 200, page.status_code
|
309
|
-
assert_text 'HardWorker'
|
310
|
-
snapshot(page, name: 'Scheduled Job Page')
|
311
|
-
end
|
312
|
-
|
313
|
-
it 'handles missing scheduled job' do
|
314
|
-
get "/scheduled/0-shouldntexist"
|
315
|
-
assert_equal 302, last_response.status
|
316
|
-
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
317
|
-
end
|
318
|
-
|
319
|
-
it 'can add to queue a single scheduled job' do
|
320
|
-
params = add_scheduled
|
321
|
-
post "/scheduled/#{job_params(*params)}", 'add_to_queue' => true
|
322
|
-
assert_equal 302, last_response.status
|
323
|
-
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
324
|
-
|
325
|
-
get '/queues/default'
|
326
|
-
assert_equal 200, last_response.status
|
327
|
-
assert_match(/#{params.first['args'][2]}/, last_response.body)
|
328
|
-
end
|
329
|
-
|
330
|
-
it 'can delete a single scheduled job' do
|
331
|
-
params = add_scheduled
|
332
|
-
post "/scheduled/#{job_params(*params)}", 'delete' => 'Delete'
|
333
|
-
assert_equal 302, last_response.status
|
334
|
-
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
335
|
-
|
336
|
-
get "/scheduled"
|
337
|
-
assert_equal 200, last_response.status
|
338
|
-
refute_match(/#{params.first['args'][2]}/, last_response.body)
|
339
|
-
end
|
340
|
-
|
341
|
-
it 'can delete scheduled' do
|
342
|
-
params = add_scheduled
|
343
|
-
Sidekiq.redis do |conn|
|
344
|
-
assert_equal 1, conn.zcard('schedule')
|
345
|
-
post '/scheduled', 'key' => [job_params(*params)], 'delete' => 'Delete'
|
346
|
-
assert_equal 302, last_response.status
|
347
|
-
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
348
|
-
assert_equal 0, conn.zcard('schedule')
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
it "can move scheduled to default queue" do
|
353
|
-
q = Sidekiq::Queue.new
|
354
|
-
params = add_scheduled
|
355
|
-
Sidekiq.redis do |conn|
|
356
|
-
assert_equal 1, conn.zcard('schedule')
|
357
|
-
assert_equal 0, q.size
|
358
|
-
post '/scheduled', 'key' => [job_params(*params)], 'add_to_queue' => 'AddToQueue'
|
359
|
-
assert_equal 302, last_response.status
|
360
|
-
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
361
|
-
assert_equal 0, conn.zcard('schedule')
|
362
|
-
assert_equal 1, q.size
|
363
|
-
get '/queues/default'
|
364
|
-
assert_equal 200, last_response.status
|
365
|
-
assert_match(/#{params[0]['args'][2]}/, last_response.body)
|
366
|
-
end
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
it 'calls updatePage() once when polling' do
|
371
|
-
get '/busy?poll=true'
|
372
|
-
assert_equal 200, last_response.status
|
373
|
-
assert_equal 1, last_response.body.scan('data-poll-path="/busy').count
|
374
|
-
end
|
375
|
-
|
376
|
-
it 'escape job args and error messages' do
|
377
|
-
# on /retries page
|
378
|
-
params = add_xss_retry
|
379
|
-
get '/retries'
|
380
|
-
assert_equal 200, last_response.status
|
381
|
-
assert_match(/FailWorker/, last_response.body)
|
382
|
-
|
383
|
-
assert last_response.body.include?( "fail message: <a>hello</a>" )
|
384
|
-
assert !last_response.body.include?( "fail message: <a>hello</a>" )
|
385
|
-
|
386
|
-
assert last_response.body.include?( "args\">"<a>hello</a>"<" )
|
387
|
-
assert !last_response.body.include?( "args\"><a>hello</a><" )
|
388
|
-
|
389
|
-
# on /workers page
|
390
|
-
Sidekiq.redis do |conn|
|
391
|
-
pro = 'foo:1234'
|
392
|
-
conn.sadd('processes', pro)
|
393
|
-
conn.hmset(pro, 'info', Sidekiq.dump_json('started_at' => Time.now.to_f, 'labels' => ['frumduz'], 'queues' =>[]), 'busy', 1, 'beat', Time.now.to_f)
|
394
|
-
identity = "#{pro}:workers"
|
395
|
-
hash = {:queue => 'critical', :payload => { 'class' => "FailWorker", 'args' => ["<a>hello</a>"] }, :run_at => Time.now.to_i }
|
396
|
-
conn.hmset(identity, 100001, Sidekiq.dump_json(hash))
|
397
|
-
conn.incr('busy')
|
398
|
-
end
|
399
|
-
|
400
|
-
get '/busy'
|
401
|
-
assert_equal 200, last_response.status
|
402
|
-
assert_match(/FailWorker/, last_response.body)
|
403
|
-
assert_match(/frumduz/, last_response.body)
|
404
|
-
assert last_response.body.include?( "<a>hello</a>" )
|
405
|
-
assert !last_response.body.include?( "<a>hello</a>" )
|
406
|
-
|
407
|
-
# on /queues page
|
408
|
-
params = add_xss_retry # sorry, don't know how to easily make this show up on queues page otherwise.
|
409
|
-
post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
|
410
|
-
assert_equal 302, last_response.status
|
411
|
-
|
412
|
-
get '/queues/foo'
|
413
|
-
assert_equal 200, last_response.status
|
414
|
-
assert last_response.body.include?( "<a>hello</a>" )
|
415
|
-
assert !last_response.body.include?( "<a>hello</a>" )
|
416
|
-
end
|
417
|
-
|
418
|
-
it 'can show user defined tab' do
|
419
|
-
begin
|
420
|
-
Sidekiq::Web.tabs['Custom Tab'] = '/custom'
|
421
|
-
|
422
|
-
get '/'
|
423
|
-
assert_match 'Custom Tab', last_response.body
|
424
|
-
|
425
|
-
ensure
|
426
|
-
Sidekiq::Web.tabs.delete 'Custom Tab'
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
it 'can display home' do
|
431
|
-
get '/'
|
432
|
-
assert_equal 200, last_response.status
|
433
|
-
end
|
434
|
-
|
435
|
-
describe 'custom locales' do
|
436
|
-
before do
|
437
|
-
Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "fixtures")
|
438
|
-
Sidekiq::Web.tabs['Custom Tab'] = '/custom'
|
439
|
-
Sidekiq::WebApplication.get('/custom') do
|
440
|
-
clear_caches # ugly hack since I can't figure out how to access WebHelpers outside of this context
|
441
|
-
t('translated_text')
|
442
|
-
end
|
443
|
-
end
|
444
|
-
|
445
|
-
after do
|
446
|
-
Sidekiq::Web.tabs.delete 'Custom Tab'
|
447
|
-
Sidekiq::Web.settings.locales.pop
|
448
|
-
end
|
449
|
-
|
450
|
-
it 'can show user defined tab with custom locales' do
|
451
|
-
get '/custom'
|
452
|
-
|
453
|
-
assert_match(/Changed text/, last_response.body)
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
describe 'dashboard/stats' do
|
458
|
-
it 'redirects to stats' do
|
459
|
-
get '/dashboard/stats'
|
460
|
-
assert_equal 302, last_response.status
|
461
|
-
assert_equal 'http://example.org/stats', last_response.header['Location']
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
describe 'stats' do
|
466
|
-
include Sidekiq::Util
|
467
|
-
|
468
|
-
before do
|
469
|
-
Sidekiq.redis do |conn|
|
470
|
-
conn.set("stat:processed", 5)
|
471
|
-
conn.set("stat:failed", 2)
|
472
|
-
conn.sadd("queues", "default")
|
473
|
-
end
|
474
|
-
2.times { add_retry }
|
475
|
-
3.times { add_scheduled }
|
476
|
-
4.times { add_worker }
|
477
|
-
end
|
478
|
-
|
479
|
-
it 'works' do
|
480
|
-
get '/stats'
|
481
|
-
@response = Sidekiq.load_json(last_response.body)
|
482
|
-
assert_equal 200, last_response.status
|
483
|
-
assert_includes @response.keys, "sidekiq"
|
484
|
-
assert_equal 5, @response["sidekiq"]["processed"]
|
485
|
-
assert_equal 2, @response["sidekiq"]["failed"]
|
486
|
-
assert_equal 4, @response["sidekiq"]["busy"]
|
487
|
-
assert_equal 1, @response["sidekiq"]["processes"]
|
488
|
-
assert_equal 2, @response["sidekiq"]["retries"]
|
489
|
-
assert_equal 3, @response["sidekiq"]["scheduled"]
|
490
|
-
assert_equal 0, @response["sidekiq"]["default_latency"]
|
491
|
-
assert_includes @response.keys, "redis"
|
492
|
-
assert_includes @response["redis"].keys, "redis_version"
|
493
|
-
assert_includes @response["redis"].keys, "uptime_in_days"
|
494
|
-
assert_includes @response["redis"].keys, "connected_clients"
|
495
|
-
assert_includes @response["redis"].keys, "used_memory_human"
|
496
|
-
assert_includes @response["redis"].keys, "used_memory_peak_human"
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
describe 'stats/queues' do
|
501
|
-
include Sidekiq::Util
|
502
|
-
|
503
|
-
before do
|
504
|
-
Sidekiq.redis do |conn|
|
505
|
-
conn.set("stat:processed", 5)
|
506
|
-
conn.set("stat:failed", 2)
|
507
|
-
conn.sadd("queues", "default")
|
508
|
-
conn.sadd("queues", "queue2")
|
509
|
-
end
|
510
|
-
2.times { add_retry }
|
511
|
-
3.times { add_scheduled }
|
512
|
-
4.times { add_worker }
|
513
|
-
|
514
|
-
get '/stats/queues'
|
515
|
-
@response = Sidekiq.load_json(last_response.body)
|
516
|
-
end
|
517
|
-
|
518
|
-
it 'reports the queue depth' do
|
519
|
-
assert_equal 0, @response["default"]
|
520
|
-
assert_equal 0, @response["queue2"]
|
521
|
-
end
|
522
|
-
end
|
523
|
-
|
524
|
-
describe 'dead jobs' do
|
525
|
-
it 'shows empty index' do
|
526
|
-
visit '/morgue'
|
527
|
-
assert_equal 200, page.status_code
|
528
|
-
snapshot(page, name: 'Dead Jobs Page - Empty')
|
529
|
-
end
|
530
|
-
|
531
|
-
it 'shows index with jobs' do
|
532
|
-
(_, score) = add_dead
|
533
|
-
visit '/morgue'
|
534
|
-
assert_equal 200, page.status_code
|
535
|
-
assert_text(score.to_i)
|
536
|
-
snapshot(page, name: 'Dead Jobs Page - With Job')
|
537
|
-
end
|
538
|
-
|
539
|
-
it 'can delete all dead' do
|
540
|
-
3.times { add_dead }
|
541
|
-
|
542
|
-
assert_equal 3, Sidekiq::DeadSet.new.size
|
543
|
-
post "/morgue/all/delete", 'delete' => 'Delete'
|
544
|
-
assert_equal 0, Sidekiq::DeadSet.new.size
|
545
|
-
assert_equal 302, last_response.status
|
546
|
-
assert_equal 'http://example.org/morgue', last_response.header['Location']
|
547
|
-
end
|
548
|
-
|
549
|
-
it 'can retry a dead job' do
|
550
|
-
params = add_dead
|
551
|
-
post "/morgue/#{job_params(*params)}", 'retry' => 'Retry'
|
552
|
-
assert_equal 302, last_response.status
|
553
|
-
assert_equal 'http://example.org/morgue', last_response.header['Location']
|
554
|
-
|
555
|
-
get '/queues/foo'
|
556
|
-
assert_equal 200, last_response.status
|
557
|
-
assert_match(/#{params.first['args'][2]}/, last_response.body)
|
558
|
-
end
|
559
|
-
end
|
560
|
-
|
561
|
-
def add_scheduled(job_id=SecureRandom.hex(12))
|
562
|
-
score = Time.now.to_f
|
563
|
-
msg = { 'class' => 'HardWorker',
|
564
|
-
'args' => ['bob', 1, Time.now.to_f],
|
565
|
-
'jid' => job_id }
|
566
|
-
Sidekiq.redis do |conn|
|
567
|
-
conn.zadd('schedule', score, Sidekiq.dump_json(msg))
|
568
|
-
end
|
569
|
-
[msg, score]
|
570
|
-
end
|
571
|
-
|
572
|
-
def add_retry(job_id=SecureRandom.hex(12))
|
573
|
-
msg = { 'class' => 'HardWorker',
|
574
|
-
'args' => ['bob', 1, Time.now.to_f],
|
575
|
-
'queue' => 'default',
|
576
|
-
'error_message' => 'Some fake message',
|
577
|
-
'error_class' => 'RuntimeError',
|
578
|
-
'retry_count' => 0,
|
579
|
-
'failed_at' => Time.now.to_f,
|
580
|
-
'jid' => job_id }
|
581
|
-
score = Time.now.to_f
|
582
|
-
Sidekiq.redis do |conn|
|
583
|
-
conn.zadd('retry', score, Sidekiq.dump_json(msg))
|
584
|
-
end
|
585
|
-
|
586
|
-
[msg, score]
|
587
|
-
end
|
588
|
-
|
589
|
-
def add_dead(job_id=SecureRandom.hex(12))
|
590
|
-
msg = { 'class' => 'HardWorker',
|
591
|
-
'args' => ['bob', 1, Time.now.to_f],
|
592
|
-
'queue' => 'foo',
|
593
|
-
'error_message' => 'Some fake message',
|
594
|
-
'error_class' => 'RuntimeError',
|
595
|
-
'retry_count' => 0,
|
596
|
-
'failed_at' => Time.now.utc,
|
597
|
-
'jid' => job_id }
|
598
|
-
score = Time.now.to_f
|
599
|
-
Sidekiq.redis do |conn|
|
600
|
-
conn.zadd('dead', score, Sidekiq.dump_json(msg))
|
601
|
-
end
|
602
|
-
[msg, score]
|
603
|
-
end
|
604
|
-
|
605
|
-
def add_xss_retry(job_id=SecureRandom.hex(12))
|
606
|
-
msg = { 'class' => 'FailWorker',
|
607
|
-
'args' => ['<a>hello</a>'],
|
608
|
-
'queue' => 'foo',
|
609
|
-
'error_message' => 'fail message: <a>hello</a>',
|
610
|
-
'error_class' => 'RuntimeError',
|
611
|
-
'retry_count' => 0,
|
612
|
-
'failed_at' => Time.now.to_f,
|
613
|
-
'jid' => job_id }
|
614
|
-
score = Time.now.to_f
|
615
|
-
Sidekiq.redis do |conn|
|
616
|
-
conn.zadd('retry', score, Sidekiq.dump_json(msg))
|
617
|
-
end
|
618
|
-
|
619
|
-
[msg, score]
|
620
|
-
end
|
621
|
-
|
622
|
-
def add_worker
|
623
|
-
key = "#{hostname}:#{$$}"
|
624
|
-
msg = "{\"queue\":\"default\",\"payload\":{\"retry\":true,\"queue\":\"default\",\"timeout\":20,\"backtrace\":5,\"class\":\"HardWorker\",\"args\":[\"bob\",10,5],\"jid\":\"2b5ad2b016f5e063a1c62872\"},\"run_at\":1361208995}"
|
625
|
-
Sidekiq.redis do |conn|
|
626
|
-
conn.multi do
|
627
|
-
conn.sadd("processes", key)
|
628
|
-
conn.hmset(key, 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
|
629
|
-
conn.hmset("#{key}:workers", Time.now.to_f, msg)
|
630
|
-
end
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
|
-
def snapshot(page, options)
|
635
|
-
Percy::Capybara.snapshot(page, options) if percy_enabled?
|
636
|
-
end
|
637
|
-
end
|
638
|
-
end
|