sidekiq 4.2.4 → 5.2.0
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/.github/issue_template.md +8 -1
- data/.gitignore +1 -0
- data/.travis.yml +5 -3
- data/5.0-Upgrade.md +56 -0
- data/COMM-LICENSE +1 -1
- data/Changes.md +151 -0
- data/Ent-Changes.md +77 -2
- data/Gemfile +10 -25
- data/LICENSE +1 -1
- data/Pro-4.0-Upgrade.md +35 -0
- data/Pro-Changes.md +156 -2
- data/README.md +9 -6
- data/Rakefile +1 -2
- data/bin/sidekiqctl +1 -1
- data/bin/sidekiqload +15 -33
- data/lib/generators/sidekiq/templates/worker_spec.rb.erb +1 -1
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
- data/lib/sidekiq/api.rb +157 -67
- data/lib/sidekiq/cli.rb +71 -26
- data/lib/sidekiq/client.rb +25 -18
- data/lib/sidekiq/core_ext.rb +1 -106
- data/lib/sidekiq/delay.rb +42 -0
- data/lib/sidekiq/exception_handler.rb +2 -4
- data/lib/sidekiq/extensions/generic_proxy.rb +7 -1
- data/lib/sidekiq/fetch.rb +1 -1
- data/lib/sidekiq/job_logger.rb +25 -0
- data/lib/sidekiq/job_retry.rb +241 -0
- data/lib/sidekiq/launcher.rb +45 -37
- data/lib/sidekiq/logging.rb +18 -2
- data/lib/sidekiq/manager.rb +3 -4
- data/lib/sidekiq/middleware/server/active_record.rb +10 -0
- data/lib/sidekiq/processor.rb +91 -34
- data/lib/sidekiq/rails.rb +15 -51
- data/lib/sidekiq/redis_connection.rb +31 -5
- data/lib/sidekiq/scheduled.rb +35 -8
- data/lib/sidekiq/testing.rb +24 -7
- data/lib/sidekiq/util.rb +6 -2
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +2 -6
- data/lib/sidekiq/web/application.rb +28 -21
- data/lib/sidekiq/web/helpers.rb +67 -23
- data/lib/sidekiq/web/router.rb +14 -10
- data/lib/sidekiq/web.rb +4 -4
- data/lib/sidekiq/worker.rb +97 -14
- data/lib/sidekiq.rb +23 -24
- data/sidekiq.gemspec +7 -10
- data/web/assets/javascripts/application.js +0 -0
- data/web/assets/javascripts/dashboard.js +18 -13
- data/web/assets/stylesheets/application-rtl.css +246 -0
- data/web/assets/stylesheets/application.css +336 -4
- data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
- data/web/assets/stylesheets/bootstrap.css +2 -2
- data/web/locales/ar.yml +80 -0
- data/web/locales/en.yml +1 -0
- data/web/locales/es.yml +4 -3
- data/web/locales/fa.yml +80 -0
- data/web/locales/he.yml +79 -0
- data/web/locales/ja.yml +5 -3
- data/web/locales/ur.yml +80 -0
- data/web/views/_footer.erb +5 -2
- data/web/views/_job_info.erb +1 -1
- data/web/views/_nav.erb +1 -1
- data/web/views/_paging.erb +1 -1
- data/web/views/busy.erb +9 -5
- data/web/views/dashboard.erb +3 -3
- data/web/views/layout.erb +11 -2
- data/web/views/morgue.erb +14 -10
- data/web/views/queue.erb +10 -10
- data/web/views/queues.erb +4 -2
- data/web/views/retries.erb +13 -11
- data/web/views/retry.erb +1 -1
- data/web/views/scheduled.erb +2 -2
- metadata +26 -160
- data/lib/sidekiq/middleware/server/logging.rb +0 -40
- data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -205
- 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 -75
- data/test/test_actors.rb +0 -138
- data/test/test_api.rb +0 -528
- 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 -127
- data/test/test_fetch.rb +0 -50
- data/test/test_launcher.rb +0 -95
- 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 -235
- data/test/test_rails.rb +0 -22
- data/test/test_redis_connection.rb +0 -132
- data/test/test_retry.rb +0 -326
- 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 -143
- data/test/test_testing_fake.rb +0 -357
- data/test/test_testing_inline.rb +0 -94
- data/test/test_util.rb +0 -13
- data/test/test_web.rb +0 -726
- 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: <a>hello</a>" )
|
324
|
-
assert !last_response.body.include?( "fail message: <a>hello</a>" )
|
325
|
-
|
326
|
-
assert last_response.body.include?( "args\">"<a>hello</a>"<" )
|
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?( "<a>hello</a>" )
|
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?( "<a>hello</a>" )
|
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
|