sidekiq 4.2.4 → 6.2.1

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.

Files changed (134) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +445 -0
  3. data/LICENSE +1 -1
  4. data/README.md +21 -34
  5. data/bin/sidekiq +26 -2
  6. data/bin/sidekiqload +28 -38
  7. data/bin/sidekiqmon +8 -0
  8. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +1 -1
  9. data/lib/generators/sidekiq/templates/worker_test.rb.erb +2 -2
  10. data/lib/generators/sidekiq/worker_generator.rb +21 -13
  11. data/lib/sidekiq/api.rb +347 -213
  12. data/lib/sidekiq/cli.rb +221 -212
  13. data/lib/sidekiq/client.rb +75 -52
  14. data/lib/sidekiq/delay.rb +41 -0
  15. data/lib/sidekiq/exception_handler.rb +12 -16
  16. data/lib/sidekiq/extensions/action_mailer.rb +13 -22
  17. data/lib/sidekiq/extensions/active_record.rb +13 -10
  18. data/lib/sidekiq/extensions/class_methods.rb +14 -11
  19. data/lib/sidekiq/extensions/generic_proxy.rb +10 -4
  20. data/lib/sidekiq/fetch.rb +38 -31
  21. data/lib/sidekiq/job_logger.rb +63 -0
  22. data/lib/sidekiq/job_retry.rb +263 -0
  23. data/lib/sidekiq/launcher.rb +169 -70
  24. data/lib/sidekiq/logger.rb +166 -0
  25. data/lib/sidekiq/manager.rb +17 -20
  26. data/lib/sidekiq/middleware/chain.rb +15 -5
  27. data/lib/sidekiq/middleware/i18n.rb +5 -7
  28. data/lib/sidekiq/monitor.rb +133 -0
  29. data/lib/sidekiq/paginator.rb +18 -14
  30. data/lib/sidekiq/processor.rb +161 -70
  31. data/lib/sidekiq/rails.rb +30 -73
  32. data/lib/sidekiq/redis_connection.rb +67 -20
  33. data/lib/sidekiq/scheduled.rb +61 -35
  34. data/lib/sidekiq/sd_notify.rb +149 -0
  35. data/lib/sidekiq/systemd.rb +24 -0
  36. data/lib/sidekiq/testing/inline.rb +2 -1
  37. data/lib/sidekiq/testing.rb +54 -26
  38. data/lib/sidekiq/util.rb +48 -15
  39. data/lib/sidekiq/version.rb +2 -1
  40. data/lib/sidekiq/web/action.rb +15 -15
  41. data/lib/sidekiq/web/application.rb +112 -89
  42. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  43. data/lib/sidekiq/web/helpers.rb +153 -73
  44. data/lib/sidekiq/web/router.rb +27 -19
  45. data/lib/sidekiq/web.rb +64 -109
  46. data/lib/sidekiq/worker.rb +164 -41
  47. data/lib/sidekiq.rb +86 -60
  48. data/sidekiq.gemspec +24 -22
  49. data/web/assets/images/apple-touch-icon.png +0 -0
  50. data/web/assets/javascripts/application.js +25 -27
  51. data/web/assets/javascripts/dashboard.js +34 -38
  52. data/web/assets/stylesheets/application-dark.css +160 -0
  53. data/web/assets/stylesheets/application-rtl.css +246 -0
  54. data/web/assets/stylesheets/application.css +402 -12
  55. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  56. data/web/assets/stylesheets/bootstrap.css +2 -2
  57. data/web/locales/ar.yml +81 -0
  58. data/web/locales/de.yml +14 -2
  59. data/web/locales/en.yml +4 -0
  60. data/web/locales/es.yml +4 -3
  61. data/web/locales/fa.yml +80 -0
  62. data/web/locales/fr.yml +3 -3
  63. data/web/locales/he.yml +79 -0
  64. data/web/locales/ja.yml +9 -4
  65. data/web/locales/lt.yml +83 -0
  66. data/web/locales/pl.yml +4 -4
  67. data/web/locales/ru.yml +4 -0
  68. data/web/locales/ur.yml +80 -0
  69. data/web/locales/vi.yml +83 -0
  70. data/web/views/_footer.erb +5 -2
  71. data/web/views/_job_info.erb +3 -2
  72. data/web/views/_nav.erb +4 -18
  73. data/web/views/_paging.erb +1 -1
  74. data/web/views/busy.erb +57 -19
  75. data/web/views/dashboard.erb +3 -3
  76. data/web/views/dead.erb +2 -2
  77. data/web/views/layout.erb +13 -2
  78. data/web/views/morgue.erb +19 -12
  79. data/web/views/queue.erb +22 -12
  80. data/web/views/queues.erb +13 -3
  81. data/web/views/retries.erb +22 -13
  82. data/web/views/retry.erb +3 -3
  83. data/web/views/scheduled.erb +7 -4
  84. metadata +42 -194
  85. data/.github/contributing.md +0 -32
  86. data/.github/issue_template.md +0 -4
  87. data/.gitignore +0 -12
  88. data/.travis.yml +0 -12
  89. data/3.0-Upgrade.md +0 -70
  90. data/4.0-Upgrade.md +0 -53
  91. data/COMM-LICENSE +0 -95
  92. data/Ent-Changes.md +0 -146
  93. data/Gemfile +0 -29
  94. data/Pro-2.0-Upgrade.md +0 -138
  95. data/Pro-3.0-Upgrade.md +0 -44
  96. data/Pro-Changes.md +0 -585
  97. data/Rakefile +0 -9
  98. data/bin/sidekiqctl +0 -99
  99. data/code_of_conduct.md +0 -50
  100. data/lib/sidekiq/core_ext.rb +0 -106
  101. data/lib/sidekiq/logging.rb +0 -106
  102. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  103. data/lib/sidekiq/middleware/server/logging.rb +0 -40
  104. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -205
  105. data/test/config.yml +0 -9
  106. data/test/env_based_config.yml +0 -11
  107. data/test/fake_env.rb +0 -1
  108. data/test/fixtures/en.yml +0 -2
  109. data/test/helper.rb +0 -75
  110. data/test/test_actors.rb +0 -138
  111. data/test/test_api.rb +0 -528
  112. data/test/test_cli.rb +0 -418
  113. data/test/test_client.rb +0 -266
  114. data/test/test_exception_handler.rb +0 -56
  115. data/test/test_extensions.rb +0 -127
  116. data/test/test_fetch.rb +0 -50
  117. data/test/test_launcher.rb +0 -95
  118. data/test/test_logging.rb +0 -35
  119. data/test/test_manager.rb +0 -50
  120. data/test/test_middleware.rb +0 -158
  121. data/test/test_processor.rb +0 -235
  122. data/test/test_rails.rb +0 -22
  123. data/test/test_redis_connection.rb +0 -132
  124. data/test/test_retry.rb +0 -326
  125. data/test/test_retry_exhausted.rb +0 -149
  126. data/test/test_scheduled.rb +0 -115
  127. data/test/test_scheduling.rb +0 -58
  128. data/test/test_sidekiq.rb +0 -107
  129. data/test/test_testing.rb +0 -143
  130. data/test/test_testing_fake.rb +0 -357
  131. data/test/test_testing_inline.rb +0 -94
  132. data/test/test_util.rb +0 -13
  133. data/test/test_web.rb +0 -726
  134. data/test/test_web_helpers.rb +0 -54
data/test/test_web.rb DELETED
@@ -1,726 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
- require_relative 'helper'
4
- require 'sidekiq/web'
5
- require 'rack/test'
6
-
7
- class TestWeb < Sidekiq::Test
8
- describe 'sidekiq web' do
9
- include Rack::Test::Methods
10
-
11
- def app
12
- Sidekiq::Web
13
- end
14
-
15
- def job_params(job, score)
16
- "#{score}-#{job['jid']}"
17
- end
18
-
19
- before do
20
- Sidekiq.redis {|c| c.flushdb }
21
- end
22
-
23
- class WebWorker
24
- include Sidekiq::Worker
25
-
26
- def perform(a, b)
27
- a + b
28
- end
29
- end
30
-
31
- it 'can configure via set() syntax' do
32
- app.set(:session_secret, "foo")
33
- assert_equal "foo", app.session_secret
34
- end
35
-
36
- it 'can show text with any locales' do
37
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'ru,en'}
38
- get '/', {}, rackenv
39
- assert_match(/Панель управления/, last_response.body)
40
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'es,en'}
41
- get '/', {}, rackenv
42
- assert_match(/Panel de Control/, last_response.body)
43
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'en-us'}
44
- get '/', {}, rackenv
45
- assert_match(/Dashboard/, last_response.body)
46
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'zh-cn'}
47
- get '/', {}, rackenv
48
- assert_match(/信息板/, last_response.body)
49
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'zh-tw'}
50
- get '/', {}, rackenv
51
- assert_match(/資訊主頁/, last_response.body)
52
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'nb'}
53
- get '/', {}, rackenv
54
- assert_match(/Oversikt/, last_response.body)
55
- end
56
-
57
- describe 'busy' do
58
-
59
- it 'can display workers' do
60
- Sidekiq.redis do |conn|
61
- conn.incr('busy')
62
- conn.sadd('processes', 'foo:1234')
63
- conn.hmset('foo:1234', 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
64
- identity = 'foo:1234:workers'
65
- hash = {:queue => 'critical', :payload => { 'class' => WebWorker.name, 'args' => [1,'abc'] }, :run_at => Time.now.to_i }
66
- conn.hmset(identity, 1001, Sidekiq.dump_json(hash))
67
- end
68
- assert_equal ['1001'], Sidekiq::Workers.new.map { |pid, tid, data| tid }
69
-
70
- get '/busy'
71
- assert_equal 200, last_response.status
72
- assert_match(/status-active/, last_response.body)
73
- assert_match(/critical/, last_response.body)
74
- assert_match(/WebWorker/, last_response.body)
75
- end
76
-
77
- it 'can quiet a process' do
78
- identity = 'identity'
79
- signals_key = "#{identity}-signals"
80
-
81
- assert_nil Sidekiq.redis { |c| c.lpop signals_key }
82
- post '/busy', 'quiet' => '1', 'identity' => identity
83
- assert_equal 302, last_response.status
84
- assert_equal 'USR1', Sidekiq.redis { |c| c.lpop signals_key }
85
- end
86
-
87
- it 'can stop a process' do
88
- identity = 'identity'
89
- signals_key = "#{identity}-signals"
90
-
91
- assert_nil Sidekiq.redis { |c| c.lpop signals_key }
92
- post '/busy', 'stop' => '1', 'identity' => identity
93
- assert_equal 302, last_response.status
94
- assert_equal 'TERM', Sidekiq.redis { |c| c.lpop signals_key }
95
- end
96
- end
97
-
98
- it 'can display queues' do
99
- assert Sidekiq::Client.push('queue' => :foo, 'class' => WebWorker, 'args' => [1, 3])
100
-
101
- get '/queues'
102
- assert_equal 200, last_response.status
103
- assert_match(/foo/, last_response.body)
104
- refute_match(/HardWorker/, last_response.body)
105
- end
106
-
107
- it 'handles queue view' do
108
- get '/queues/default'
109
- assert_equal 200, last_response.status
110
- end
111
-
112
- it 'can delete a queue' do
113
- Sidekiq.redis do |conn|
114
- conn.rpush('queue:foo', '{}')
115
- conn.sadd('queues', 'foo')
116
- end
117
-
118
- get '/queues/foo'
119
- assert_equal 200, last_response.status
120
-
121
- post '/queues/foo'
122
- assert_equal 302, last_response.status
123
-
124
- Sidekiq.redis do |conn|
125
- refute conn.smembers('queues').include?('foo')
126
- refute conn.exists('queue:foo')
127
- end
128
- end
129
-
130
- it 'can delete a job' do
131
- Sidekiq.redis do |conn|
132
- conn.rpush('queue:foo', "{}")
133
- conn.rpush('queue:foo', "{\"foo\":\"bar\"}")
134
- conn.rpush('queue:foo', "{\"foo2\":\"bar2\"}")
135
- end
136
-
137
- get '/queues/foo'
138
- assert_equal 200, last_response.status
139
-
140
- post '/queues/foo/delete', key_val: "{\"foo\":\"bar\"}"
141
- assert_equal 302, last_response.status
142
-
143
- Sidekiq.redis do |conn|
144
- refute conn.lrange('queue:foo', 0, -1).include?("{\"foo\":\"bar\"}")
145
- end
146
- end
147
-
148
- it 'can display retries' do
149
- get '/retries'
150
- assert_equal 200, last_response.status
151
- assert_match(/found/, last_response.body)
152
- refute_match(/HardWorker/, last_response.body)
153
-
154
- add_retry
155
-
156
- get '/retries'
157
- assert_equal 200, last_response.status
158
- refute_match(/found/, last_response.body)
159
- assert_match(/HardWorker/, last_response.body)
160
- end
161
-
162
- it 'can display a single retry' do
163
- params = add_retry
164
- get '/retries/0-shouldntexist'
165
- assert_equal 302, last_response.status
166
- get "/retries/#{job_params(*params)}"
167
- assert_equal 200, last_response.status
168
- assert_match(/HardWorker/, last_response.body)
169
- end
170
-
171
- it 'handles missing retry' do
172
- get "/retries/0-shouldntexist"
173
- assert_equal 302, last_response.status
174
- end
175
-
176
- it 'can delete a single retry' do
177
- params = add_retry
178
- post "/retries/#{job_params(*params)}", 'delete' => 'Delete'
179
- assert_equal 302, last_response.status
180
- assert_equal 'http://example.org/retries', last_response.header['Location']
181
-
182
- get "/retries"
183
- assert_equal 200, last_response.status
184
- refute_match(/#{params.first['args'][2]}/, last_response.body)
185
- end
186
-
187
- it 'can delete all retries' do
188
- 3.times { add_retry }
189
-
190
- post "/retries/all/delete", 'delete' => 'Delete'
191
- assert_equal 0, Sidekiq::RetrySet.new.size
192
- assert_equal 302, last_response.status
193
- assert_equal 'http://example.org/retries', last_response.header['Location']
194
- end
195
-
196
- it 'can retry a single retry now' do
197
- params = add_retry
198
- post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
199
- assert_equal 302, last_response.status
200
- assert_equal 'http://example.org/retries', last_response.header['Location']
201
-
202
- get '/queues/default'
203
- assert_equal 200, last_response.status
204
- assert_match(/#{params.first['args'][2]}/, last_response.body)
205
- end
206
-
207
- it 'can kill a single retry now' do
208
- params = add_retry
209
- post "/retries/#{job_params(*params)}", 'kill' => 'Kill'
210
- assert_equal 302, last_response.status
211
- assert_equal 'http://example.org/retries', last_response.header['Location']
212
-
213
- get '/morgue'
214
- assert_equal 200, last_response.status
215
- assert_match(/#{params.first['args'][2]}/, last_response.body)
216
- end
217
-
218
- it 'can display scheduled' do
219
- get '/scheduled'
220
- assert_equal 200, last_response.status
221
- assert_match(/found/, last_response.body)
222
- refute_match(/HardWorker/, last_response.body)
223
-
224
- add_scheduled
225
-
226
- get '/scheduled'
227
- assert_equal 200, last_response.status
228
- refute_match(/found/, last_response.body)
229
- assert_match(/HardWorker/, last_response.body)
230
- end
231
-
232
- it 'can display a single scheduled job' do
233
- params = add_scheduled
234
- get '/scheduled/0-shouldntexist'
235
- assert_equal 302, last_response.status
236
- get "/scheduled/#{job_params(*params)}"
237
- assert_equal 200, last_response.status
238
- assert_match(/HardWorker/, last_response.body)
239
- end
240
-
241
- it 'handles missing scheduled job' do
242
- get "/scheduled/0-shouldntexist"
243
- assert_equal 302, last_response.status
244
- end
245
-
246
- it 'can add to queue a single scheduled job' do
247
- params = add_scheduled
248
- post "/scheduled/#{job_params(*params)}", 'add_to_queue' => true
249
- assert_equal 302, last_response.status
250
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
251
-
252
- get '/queues/default'
253
- assert_equal 200, last_response.status
254
- assert_match(/#{params.first['args'][2]}/, last_response.body)
255
- end
256
-
257
- it 'can delete a single scheduled job' do
258
- params = add_scheduled
259
- post "/scheduled/#{job_params(*params)}", 'delete' => 'Delete'
260
- assert_equal 302, last_response.status
261
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
262
-
263
- get "/scheduled"
264
- assert_equal 200, last_response.status
265
- refute_match(/#{params.first['args'][2]}/, last_response.body)
266
- end
267
-
268
- it 'can delete scheduled' do
269
- params = add_scheduled
270
- Sidekiq.redis do |conn|
271
- assert_equal 1, conn.zcard('schedule')
272
- post '/scheduled', 'key' => [job_params(*params)], 'delete' => 'Delete'
273
- assert_equal 302, last_response.status
274
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
275
- assert_equal 0, conn.zcard('schedule')
276
- end
277
- end
278
-
279
- it "can move scheduled to default queue" do
280
- q = Sidekiq::Queue.new
281
- params = add_scheduled
282
- Sidekiq.redis do |conn|
283
- assert_equal 1, conn.zcard('schedule')
284
- assert_equal 0, q.size
285
- post '/scheduled', 'key' => [job_params(*params)], 'add_to_queue' => 'AddToQueue'
286
- assert_equal 302, last_response.status
287
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
288
- assert_equal 0, conn.zcard('schedule')
289
- assert_equal 1, q.size
290
- get '/queues/default'
291
- assert_equal 200, last_response.status
292
- assert_match(/#{params[0]['args'][2]}/, last_response.body)
293
- end
294
- end
295
-
296
- it 'can retry all retries' do
297
- msg = add_retry.first
298
- add_retry
299
-
300
- post "/retries/all/retry", 'retry' => 'Retry'
301
- assert_equal 302, last_response.status
302
- assert_equal 'http://example.org/retries', last_response.header['Location']
303
- assert_equal 2, Sidekiq::Queue.new("default").size
304
-
305
- get '/queues/default'
306
- assert_equal 200, last_response.status
307
- assert_match(/#{msg['args'][2]}/, last_response.body)
308
- end
309
-
310
- it 'calls updatePage() once when polling' do
311
- get '/busy?poll=true'
312
- assert_equal 200, last_response.status
313
- assert_equal 1, last_response.body.scan('data-poll-path="/busy').count
314
- end
315
-
316
- it 'escape job args and error messages' do
317
- # on /retries page
318
- params = add_xss_retry
319
- get '/retries'
320
- assert_equal 200, last_response.status
321
- assert_match(/FailWorker/, last_response.body)
322
-
323
- assert last_response.body.include?( "fail message: &lt;a&gt;hello&lt;&#x2F;a&gt;" )
324
- assert !last_response.body.include?( "fail message: <a>hello</a>" )
325
-
326
- assert last_response.body.include?( "args\">&quot;&lt;a&gt;hello&lt;&#x2F;a&gt;&quot;<" )
327
- assert !last_response.body.include?( "args\"><a>hello</a><" )
328
-
329
- # on /workers page
330
- Sidekiq.redis do |conn|
331
- pro = 'foo:1234'
332
- conn.sadd('processes', pro)
333
- conn.hmset(pro, 'info', Sidekiq.dump_json('started_at' => Time.now.to_f, 'labels' => ['frumduz'], 'queues' =>[]), 'busy', 1, 'beat', Time.now.to_f)
334
- identity = "#{pro}:workers"
335
- hash = {:queue => 'critical', :payload => { 'class' => "FailWorker", 'args' => ["<a>hello</a>"] }, :run_at => Time.now.to_i }
336
- conn.hmset(identity, 100001, Sidekiq.dump_json(hash))
337
- conn.incr('busy')
338
- end
339
-
340
- get '/busy'
341
- assert_equal 200, last_response.status
342
- assert_match(/FailWorker/, last_response.body)
343
- assert_match(/frumduz/, last_response.body)
344
- assert last_response.body.include?( "&lt;a&gt;hello&lt;&#x2F;a&gt;" )
345
- assert !last_response.body.include?( "<a>hello</a>" )
346
-
347
- # on /queues page
348
- params = add_xss_retry # sorry, don't know how to easily make this show up on queues page otherwise.
349
- post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
350
- assert_equal 302, last_response.status
351
-
352
- get '/queues/foo'
353
- assert_equal 200, last_response.status
354
- assert last_response.body.include?( "&lt;a&gt;hello&lt;&#x2F;a&gt;" )
355
- assert !last_response.body.include?( "<a>hello</a>" )
356
- end
357
-
358
- it 'can show user defined tab' do
359
- begin
360
- Sidekiq::Web.tabs['Custom Tab'] = '/custom'
361
-
362
- get '/'
363
- assert_match 'Custom Tab', last_response.body
364
-
365
- ensure
366
- Sidekiq::Web.tabs.delete 'Custom Tab'
367
- end
368
- end
369
-
370
- it 'can display home' do
371
- get '/'
372
- assert_equal 200, last_response.status
373
- end
374
-
375
- describe 'custom locales' do
376
- before do
377
- Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "fixtures")
378
- Sidekiq::Web.tabs['Custom Tab'] = '/custom'
379
- Sidekiq::WebApplication.get('/custom') do
380
- clear_caches # ugly hack since I can't figure out how to access WebHelpers outside of this context
381
- t('translated_text')
382
- end
383
- end
384
-
385
- after do
386
- Sidekiq::Web.tabs.delete 'Custom Tab'
387
- Sidekiq::Web.settings.locales.pop
388
- end
389
-
390
- it 'can show user defined tab with custom locales' do
391
- get '/custom'
392
-
393
- assert_match(/Changed text/, last_response.body)
394
- end
395
- end
396
-
397
- describe 'dashboard/stats' do
398
- it 'redirects to stats' do
399
- get '/dashboard/stats'
400
- assert_equal 302, last_response.status
401
- assert_equal 'http://example.org/stats', last_response.header['Location']
402
- end
403
- end
404
-
405
- describe 'stats' do
406
- include Sidekiq::Util
407
-
408
- before do
409
- Sidekiq.redis do |conn|
410
- conn.set("stat:processed", 5)
411
- conn.set("stat:failed", 2)
412
- conn.sadd("queues", "default")
413
- end
414
- 2.times { add_retry }
415
- 3.times { add_scheduled }
416
- 4.times { add_worker }
417
-
418
- get '/stats'
419
- @response = Sidekiq.load_json(last_response.body)
420
- end
421
-
422
- it 'can refresh dashboard stats' do
423
- assert_equal 200, last_response.status
424
- end
425
-
426
- describe "for sidekiq" do
427
- it 'are namespaced' do
428
- assert_includes @response.keys, "sidekiq"
429
- end
430
-
431
- it 'reports processed' do
432
- assert_equal 5, @response["sidekiq"]["processed"]
433
- end
434
-
435
- it 'reports failed' do
436
- assert_equal 2, @response["sidekiq"]["failed"]
437
- end
438
-
439
- it 'reports busy' do
440
- assert_equal 4, @response["sidekiq"]["busy"]
441
- end
442
-
443
- it 'reports processes' do
444
- assert_equal 1, @response["sidekiq"]["processes"]
445
- end
446
-
447
- it 'reports retries' do
448
- assert_equal 2, @response["sidekiq"]["retries"]
449
- end
450
-
451
- it 'reports scheduled' do
452
- assert_equal 3, @response["sidekiq"]["scheduled"]
453
- end
454
-
455
- it 'reports latency' do
456
- assert_equal 0, @response["sidekiq"]["default_latency"]
457
- end
458
- end
459
-
460
- describe "for redis" do
461
- it 'are namespaced' do
462
- assert_includes @response.keys, "redis"
463
- end
464
-
465
- it 'reports version' do
466
- assert_includes @response["redis"].keys, "redis_version"
467
- end
468
-
469
- it 'reports uptime' do
470
- assert_includes @response["redis"].keys, "uptime_in_days"
471
- end
472
-
473
- it 'reports connected clients' do
474
- assert_includes @response["redis"].keys, "connected_clients"
475
- end
476
-
477
- it 'reports user memory' do
478
- assert_includes @response["redis"].keys, "used_memory_human"
479
- end
480
-
481
- it 'reports memory peak' do
482
- assert_includes @response["redis"].keys, "used_memory_peak_human"
483
- end
484
- end
485
- end
486
-
487
- describe 'stats/queues' do
488
- include Sidekiq::Util
489
-
490
- before do
491
- Sidekiq.redis do |conn|
492
- conn.set("stat:processed", 5)
493
- conn.set("stat:failed", 2)
494
- conn.sadd("queues", "default")
495
- conn.sadd("queues", "queue2")
496
- end
497
- 2.times { add_retry }
498
- 3.times { add_scheduled }
499
- 4.times { add_worker }
500
-
501
- get '/stats/queues'
502
- @response = Sidekiq.load_json(last_response.body)
503
- end
504
-
505
- it 'reports the queue depth' do
506
- assert_equal 0, @response["default"]
507
- assert_equal 0, @response["queue2"]
508
- end
509
- end
510
-
511
- describe 'dead jobs' do
512
- it 'shows empty index' do
513
- get 'morgue'
514
- assert_equal 200, last_response.status
515
- end
516
-
517
- it 'shows index with jobs' do
518
- (_, score) = add_dead
519
- get 'morgue'
520
- assert_equal 200, last_response.status
521
- assert_match(/#{score}/, last_response.body)
522
- end
523
-
524
- it 'can delete all dead' do
525
- 3.times { add_dead }
526
-
527
- assert_equal 3, Sidekiq::DeadSet.new.size
528
- post "/morgue/all/delete", 'delete' => 'Delete'
529
- assert_equal 0, Sidekiq::DeadSet.new.size
530
- assert_equal 302, last_response.status
531
- assert_equal 'http://example.org/morgue', last_response.header['Location']
532
- end
533
-
534
- it 'can retry a dead job' do
535
- params = add_dead
536
- post "/morgue/#{job_params(*params)}", 'retry' => 'Retry'
537
- assert_equal 302, last_response.status
538
- assert_equal 'http://example.org/morgue', last_response.header['Location']
539
-
540
- get '/queues/foo'
541
- assert_equal 200, last_response.status
542
- assert_match(/#{params.first['args'][2]}/, last_response.body)
543
- end
544
- end
545
-
546
- def add_scheduled
547
- score = Time.now.to_f
548
- msg = { 'class' => 'HardWorker',
549
- 'args' => ['bob', 1, Time.now.to_f],
550
- 'jid' => SecureRandom.hex(12) }
551
- Sidekiq.redis do |conn|
552
- conn.zadd('schedule', score, Sidekiq.dump_json(msg))
553
- end
554
- [msg, score]
555
- end
556
-
557
- def add_retry
558
- msg = { 'class' => 'HardWorker',
559
- 'args' => ['bob', 1, Time.now.to_f],
560
- 'queue' => 'default',
561
- 'error_message' => 'Some fake message',
562
- 'error_class' => 'RuntimeError',
563
- 'retry_count' => 0,
564
- 'failed_at' => Time.now.to_f,
565
- 'jid' => SecureRandom.hex(12) }
566
- score = Time.now.to_f
567
- Sidekiq.redis do |conn|
568
- conn.zadd('retry', score, Sidekiq.dump_json(msg))
569
- end
570
-
571
- [msg, score]
572
- end
573
-
574
- def add_dead
575
- msg = { 'class' => 'HardWorker',
576
- 'args' => ['bob', 1, Time.now.to_f],
577
- 'queue' => 'foo',
578
- 'error_message' => 'Some fake message',
579
- 'error_class' => 'RuntimeError',
580
- 'retry_count' => 0,
581
- 'failed_at' => Time.now.utc,
582
- 'jid' => SecureRandom.hex(12) }
583
- score = Time.now.to_f
584
- Sidekiq.redis do |conn|
585
- conn.zadd('dead', score, Sidekiq.dump_json(msg))
586
- end
587
- [msg, score]
588
- end
589
-
590
- def add_xss_retry
591
- msg = { 'class' => 'FailWorker',
592
- 'args' => ['<a>hello</a>'],
593
- 'queue' => 'foo',
594
- 'error_message' => 'fail message: <a>hello</a>',
595
- 'error_class' => 'RuntimeError',
596
- 'retry_count' => 0,
597
- 'failed_at' => Time.now.to_f,
598
- 'jid' => SecureRandom.hex(12) }
599
- score = Time.now.to_f
600
- Sidekiq.redis do |conn|
601
- conn.zadd('retry', score, Sidekiq.dump_json(msg))
602
- end
603
-
604
- [msg, score]
605
- end
606
-
607
- def add_worker
608
- key = "#{hostname}:#{$$}"
609
- msg = "{\"queue\":\"default\",\"payload\":{\"retry\":true,\"queue\":\"default\",\"timeout\":20,\"backtrace\":5,\"class\":\"HardWorker\",\"args\":[\"bob\",10,5],\"jid\":\"2b5ad2b016f5e063a1c62872\"},\"run_at\":1361208995}"
610
- Sidekiq.redis do |conn|
611
- conn.multi do
612
- conn.sadd("processes", key)
613
- conn.hmset(key, 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
614
- conn.hmset("#{key}:workers", Time.now.to_f, msg)
615
- end
616
- end
617
- end
618
- end
619
-
620
- describe 'sidekiq web with basic auth' do
621
- include Rack::Test::Methods
622
-
623
- def app
624
- app = Sidekiq::Web.new
625
- app.use(Rack::Auth::Basic) { |user, pass| user == "a" && pass == "b" }
626
-
627
- app
628
- end
629
-
630
- it 'requires basic authentication' do
631
- get '/'
632
-
633
- assert_equal 401, last_response.status
634
- refute_nil last_response.header["WWW-Authenticate"]
635
- end
636
-
637
- it 'authenticates successfuly' do
638
- basic_authorize 'a', 'b'
639
-
640
- get '/'
641
-
642
- assert_equal 200, last_response.status
643
- end
644
- end
645
-
646
- describe 'sidekiq web with custom session' do
647
- include Rack::Test::Methods
648
-
649
- def app
650
- app = Sidekiq::Web.new
651
-
652
- app.use Rack::Session::Cookie, secret: 'v3rys3cr31', host: 'nicehost.org'
653
-
654
- app
655
- end
656
-
657
- it 'requires basic authentication' do
658
- get '/'
659
-
660
- session_options = last_request.env['rack.session'].options
661
-
662
- assert_equal 'v3rys3cr31', session_options[:secret]
663
- assert_equal 'nicehost.org', session_options[:host]
664
- end
665
- end
666
-
667
- describe 'sidekiq web sessions options' do
668
- include Rack::Test::Methods
669
-
670
- describe 'using #disable' do
671
- def app
672
- app = Sidekiq::Web.new
673
- app.disable(:sessions)
674
- app
675
- end
676
-
677
- it "doesn't create sessions" do
678
- get '/'
679
- assert_nil last_request.env['rack.session']
680
- end
681
- end
682
-
683
- describe 'using #set with false argument' do
684
- def app
685
- app = Sidekiq::Web.new
686
- app.set(:sessions, false)
687
- app
688
- end
689
-
690
- it "doesn't create sessions" do
691
- get '/'
692
- assert_nil last_request.env['rack.session']
693
- end
694
- end
695
-
696
- describe 'using #set with an hash' do
697
- def app
698
- app = Sidekiq::Web.new
699
- app.set(:sessions, { domain: :all })
700
- app
701
- end
702
-
703
- it "creates sessions" do
704
- get '/'
705
- refute_nil last_request.env['rack.session']
706
- refute_empty last_request.env['rack.session'].options
707
- assert_equal :all, last_request.env['rack.session'].options[:domain]
708
- end
709
- end
710
-
711
- describe 'using #enable' do
712
- def app
713
- app = Sidekiq::Web.new
714
- app.enable(:sessions)
715
- app
716
- end
717
-
718
- it "creates sessions" do
719
- get '/'
720
- refute_nil last_request.env['rack.session']
721
- refute_empty last_request.env['rack.session'].options
722
- refute_nil last_request.env['rack.session'].options[:secret]
723
- end
724
- end
725
- end
726
- end