sidekiq 4.2.9 → 4.2.10

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/issue_template.md +6 -1
  3. data/.travis.yml +10 -5
  4. data/Changes.md +9 -0
  5. data/Ent-Changes.md +9 -0
  6. data/Pro-Changes.md +29 -0
  7. data/bin/sidekiqload +11 -11
  8. data/lib/sidekiq.rb +1 -1
  9. data/lib/sidekiq/api.rb +20 -12
  10. data/lib/sidekiq/middleware/server/logging.rb +8 -17
  11. data/lib/sidekiq/processor.rb +16 -7
  12. data/lib/sidekiq/testing.rb +6 -0
  13. data/lib/sidekiq/version.rb +1 -1
  14. data/lib/sidekiq/web/application.rb +2 -2
  15. data/lib/sidekiq/web/helpers.rb +2 -1
  16. data/sidekiq.gemspec +8 -2
  17. data/web/assets/javascripts/dashboard.js +1 -1
  18. data/web/locales/fa.yml +79 -0
  19. data/web/views/_job_info.erb +1 -1
  20. data/web/views/dashboard.erb +2 -2
  21. data/web/views/morgue.erb +2 -0
  22. data/web/views/queue.erb +2 -2
  23. data/web/views/queues.erb +2 -2
  24. data/web/views/retry.erb +1 -1
  25. metadata +74 -63
  26. data/test/config.yml +0 -9
  27. data/test/env_based_config.yml +0 -11
  28. data/test/fake_env.rb +0 -1
  29. data/test/fixtures/en.yml +0 -2
  30. data/test/helper.rb +0 -75
  31. data/test/test_actors.rb +0 -138
  32. data/test/test_api.rb +0 -528
  33. data/test/test_cli.rb +0 -418
  34. data/test/test_client.rb +0 -266
  35. data/test/test_exception_handler.rb +0 -56
  36. data/test/test_extensions.rb +0 -129
  37. data/test/test_fetch.rb +0 -50
  38. data/test/test_launcher.rb +0 -92
  39. data/test/test_logging.rb +0 -35
  40. data/test/test_manager.rb +0 -50
  41. data/test/test_middleware.rb +0 -158
  42. data/test/test_processor.rb +0 -249
  43. data/test/test_rails.rb +0 -22
  44. data/test/test_redis_connection.rb +0 -132
  45. data/test/test_retry.rb +0 -326
  46. data/test/test_retry_exhausted.rb +0 -149
  47. data/test/test_scheduled.rb +0 -115
  48. data/test/test_scheduling.rb +0 -58
  49. data/test/test_sidekiq.rb +0 -107
  50. data/test/test_testing.rb +0 -143
  51. data/test/test_testing_fake.rb +0 -359
  52. data/test/test_testing_inline.rb +0 -94
  53. data/test/test_util.rb +0 -13
  54. data/test/test_web.rb +0 -679
  55. data/test/test_web_helpers.rb +0 -54
@@ -1,249 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'sidekiq/fetch'
4
- require 'sidekiq/cli'
5
- require 'sidekiq/processor'
6
-
7
- class TestProcessor < Sidekiq::Test
8
- TestException = Class.new(StandardError)
9
- TEST_EXCEPTION = TestException.new("kerboom!")
10
-
11
- describe 'processor' do
12
- before do
13
- $invokes = 0
14
- @mgr = Minitest::Mock.new
15
- @mgr.expect(:options, {:queues => ['default']})
16
- @mgr.expect(:options, {:queues => ['default']})
17
- @processor = ::Sidekiq::Processor.new(@mgr)
18
- end
19
-
20
- class MockWorker
21
- include Sidekiq::Worker
22
- def perform(args)
23
- raise TEST_EXCEPTION if args == 'boom'
24
- args.pop if args.is_a? Array
25
- $invokes += 1
26
- end
27
- end
28
-
29
- def work(msg, queue='queue:default')
30
- Sidekiq::BasicFetch::UnitOfWork.new(queue, msg)
31
- end
32
-
33
- it 'processes as expected' do
34
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['myarg'] })
35
- @processor.process(work(msg))
36
- assert_equal 1, $invokes
37
- end
38
-
39
- it 'executes a worker as expected' do
40
- worker = Minitest::Mock.new
41
- worker.expect(:perform, nil, [1, 2, 3])
42
- @processor.execute_job(worker, [1, 2, 3])
43
- end
44
-
45
- it 're-raises exceptions after handling' do
46
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
47
- re_raise = false
48
-
49
- begin
50
- @processor.process(work(msg))
51
- flunk "Expected exception"
52
- rescue TestException
53
- re_raise = true
54
- end
55
-
56
- assert_equal 0, $invokes
57
- assert re_raise, "does not re-raise exceptions after handling"
58
- end
59
-
60
- it 'does not modify original arguments' do
61
- msg = { 'class' => MockWorker.to_s, 'args' => [['myarg']] }
62
- msgstr = Sidekiq.dump_json(msg)
63
- @mgr.expect(:processor_done, nil, [@processor])
64
- @processor.process(work(msgstr))
65
- assert_equal [['myarg']], msg['args']
66
- end
67
-
68
- describe 'exception handling' do
69
- let(:errors) { [] }
70
- let(:error_handler) do
71
- proc do |exception, context|
72
- errors << { exception: exception, context: context }
73
- end
74
- end
75
-
76
- before do
77
- Sidekiq.error_handlers << error_handler
78
- end
79
-
80
- after do
81
- Sidekiq.error_handlers.pop
82
- end
83
-
84
- it 'handles exceptions raised by the job' do
85
- job_hash = { 'class' => MockWorker.to_s, 'args' => ['boom'] }
86
- msg = Sidekiq.dump_json(job_hash)
87
- job = work(msg)
88
- begin
89
- @processor.instance_variable_set(:'@job', job)
90
- @processor.process(job)
91
- rescue TestException
92
- end
93
- assert_equal 1, errors.count
94
- assert_instance_of TestException, errors.first[:exception]
95
- assert_equal msg, errors.first[:context][:jobstr]
96
- assert_equal job_hash, errors.first[:context][:job]
97
- end
98
-
99
- it 'handles exceptions raised by the reloader' do
100
- job_hash = { 'class' => MockWorker.to_s, 'args' => ['boom'] }
101
- msg = Sidekiq.dump_json(job_hash)
102
- @processor.instance_variable_set(:'@reloader', proc { raise TEST_EXCEPTION })
103
- job = work(msg)
104
- begin
105
- @processor.instance_variable_set(:'@job', job)
106
- @processor.process(job)
107
- rescue TestException
108
- end
109
- assert_equal 1, errors.count
110
- assert_instance_of TestException, errors.first[:exception]
111
- assert_equal msg, errors.first[:context][:jobstr]
112
- assert_equal job_hash, errors.first[:context][:job]
113
- end
114
- end
115
-
116
- describe 'acknowledgement' do
117
- class ExceptionRaisingMiddleware
118
- def initialize(raise_before_yield, raise_after_yield, skip)
119
- @raise_before_yield = raise_before_yield
120
- @raise_after_yield = raise_after_yield
121
- @skip = skip
122
- end
123
-
124
- def call(worker, item, queue)
125
- raise TEST_EXCEPTION if @raise_before_yield
126
- yield unless @skip
127
- raise TEST_EXCEPTION if @raise_after_yield
128
- end
129
- end
130
-
131
- let(:raise_before_yield) { false }
132
- let(:raise_after_yield) { false }
133
- let(:skip_job) { false }
134
- let(:worker_args) { ['myarg'] }
135
- let(:work) { MiniTest::Mock.new }
136
-
137
- before do
138
- work.expect(:queue_name, 'queue:default')
139
- work.expect(:job, Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => worker_args }))
140
- Sidekiq.server_middleware do |chain|
141
- chain.prepend ExceptionRaisingMiddleware, raise_before_yield, raise_after_yield, skip_job
142
- end
143
- end
144
-
145
- after do
146
- Sidekiq.server_middleware do |chain|
147
- chain.remove ExceptionRaisingMiddleware
148
- end
149
- work.verify
150
- end
151
-
152
- describe 'middleware throws an exception before processing the work' do
153
- let(:raise_before_yield) { true }
154
-
155
- it 'does not ack' do
156
- begin
157
- @processor.process(work)
158
- flunk "Expected #process to raise exception"
159
- rescue TestException
160
- end
161
- end
162
- end
163
-
164
- describe 'middleware throws an exception after processing the work' do
165
- let(:raise_after_yield) { true }
166
-
167
- it 'acks the job' do
168
- work.expect(:acknowledge, nil)
169
- begin
170
- @processor.process(work)
171
- flunk "Expected #process to raise exception"
172
- rescue TestException
173
- end
174
- end
175
- end
176
-
177
- describe 'middleware decides to skip work' do
178
- let(:skip_job) { true }
179
-
180
- it 'acks the job' do
181
- work.expect(:acknowledge, nil)
182
- @mgr.expect(:processor_done, nil, [@processor])
183
- @processor.process(work)
184
- end
185
- end
186
-
187
- describe 'worker raises an exception' do
188
- let(:worker_args) { ['boom'] }
189
-
190
- it 'acks the job' do
191
- work.expect(:acknowledge, nil)
192
- begin
193
- @processor.process(work)
194
- flunk "Expected #process to raise exception"
195
- rescue TestException
196
- end
197
- end
198
- end
199
-
200
- describe 'everything goes well' do
201
- it 'acks the job' do
202
- work.expect(:acknowledge, nil)
203
- @mgr.expect(:processor_done, nil, [@processor])
204
- @processor.process(work)
205
- end
206
- end
207
- end
208
-
209
- describe 'stats' do
210
- before do
211
- Sidekiq.redis {|c| c.flushdb }
212
- end
213
-
214
- describe 'when successful' do
215
- let(:processed_today_key) { "stat:processed:#{Time.now.utc.strftime("%Y-%m-%d")}" }
216
-
217
- def successful_job
218
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['myarg'] })
219
- @mgr.expect(:processor_done, nil, [@processor])
220
- @processor.process(work(msg))
221
- end
222
-
223
- it 'increments processed stat' do
224
- Sidekiq::Processor::PROCESSED.value = 0
225
- successful_job
226
- assert_equal 1, Sidekiq::Processor::PROCESSED.value
227
- end
228
- end
229
-
230
- describe 'when failed' do
231
- let(:failed_today_key) { "stat:failed:#{Time.now.utc.strftime("%Y-%m-%d")}" }
232
-
233
- def failed_job
234
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
235
- begin
236
- @processor.process(work(msg))
237
- rescue TestException
238
- end
239
- end
240
-
241
- it 'increments failed stat' do
242
- Sidekiq::Processor::FAILURE.value = 0
243
- failed_job
244
- assert_equal 1, Sidekiq::Processor::FAILURE.value
245
- end
246
- end
247
- end
248
- end
249
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
-
4
- $HAS_AJ = true
5
- begin
6
- require 'active_job'
7
- rescue LoadError
8
- $HAS_AJ = false
9
- end
10
-
11
- class TestRails < Sidekiq::Test
12
-
13
- describe 'ActiveJob' do
14
- it 'does not allow Sidekiq::Worker in AJ::Base classes' do
15
- ex = assert_raises ArgumentError do
16
- c = Class.new(ActiveJob::Base)
17
- c.send(:include, Sidekiq::Worker)
18
- end
19
- assert_includes ex.message, "cannot include"
20
- end if $HAS_AJ
21
- end
22
- end
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
-
4
- class TestRedisConnection < Sidekiq::Test
5
-
6
- describe ".create" do
7
-
8
- it "creates a pooled redis connection" do
9
- pool = Sidekiq::RedisConnection.create
10
- assert_equal Redis, pool.checkout.class
11
- end
12
-
13
- describe "network_timeout" do
14
- it "sets a custom network_timeout if specified" do
15
- pool = Sidekiq::RedisConnection.create(:network_timeout => 8)
16
- redis = pool.checkout
17
-
18
- assert_equal 8, redis.client.timeout
19
- end
20
-
21
- it "uses the default network_timeout if none specified" do
22
- pool = Sidekiq::RedisConnection.create
23
- redis = pool.checkout
24
-
25
- assert_equal 5, redis.client.timeout
26
- end
27
- end
28
-
29
- describe "namespace" do
30
- it "uses a given :namespace set by a symbol key" do
31
- pool = Sidekiq::RedisConnection.create(:namespace => "xxx")
32
- assert_equal "xxx", pool.checkout.namespace
33
- end
34
-
35
- it "uses a given :namespace set by a string key" do
36
- pool = Sidekiq::RedisConnection.create("namespace" => "xxx")
37
- assert_equal "xxx", pool.checkout.namespace
38
- end
39
-
40
- it "uses given :namespace over :namespace from Sidekiq.options" do
41
- Sidekiq.options[:namespace] = "xxx"
42
- pool = Sidekiq::RedisConnection.create(:namespace => "yyy")
43
- assert_equal "yyy", pool.checkout.namespace
44
- end
45
- end
46
-
47
- describe "socket path" do
48
- it "uses a given :path" do
49
- pool = Sidekiq::RedisConnection.create(:path => "/var/run/redis.sock")
50
- assert_equal "unix", pool.checkout.client.scheme
51
- assert_equal "redis:///var/run/redis.sock/0", pool.checkout.client.id
52
- end
53
-
54
- it "uses a given :path and :db" do
55
- pool = Sidekiq::RedisConnection.create(:path => "/var/run/redis.sock", :db => 8)
56
- assert_equal "unix", pool.checkout.client.scheme
57
- assert_equal "redis:///var/run/redis.sock/8", pool.checkout.client.id
58
- end
59
- end
60
-
61
- describe "pool_timeout" do
62
- it "uses a given :timeout over the default of 1" do
63
- pool = Sidekiq::RedisConnection.create(:pool_timeout => 5)
64
-
65
- assert_equal 5, pool.instance_eval{ @timeout }
66
- end
67
-
68
- it "uses the default timeout of 1 if no override" do
69
- pool = Sidekiq::RedisConnection.create
70
-
71
- assert_equal 1, pool.instance_eval{ @timeout }
72
- end
73
- end
74
- end
75
-
76
- describe ".determine_redis_provider" do
77
-
78
- before do
79
- @old_env = ENV.to_hash
80
- end
81
-
82
- after do
83
- ENV.update(@old_env)
84
- end
85
-
86
- def with_env_var(var, uri, skip_provider=false)
87
- vars = ['REDISTOGO_URL', 'REDIS_PROVIDER', 'REDIS_URL'] - [var]
88
- vars.each do |v|
89
- next if skip_provider
90
- ENV[v] = nil
91
- end
92
- ENV[var] = uri
93
- assert_equal uri, Sidekiq::RedisConnection.__send__(:determine_redis_provider)
94
- ENV[var] = nil
95
- end
96
-
97
- describe "with REDISTOGO_URL and a parallel REDIS_PROVIDER set" do
98
- it "sets connection URI to the provider" do
99
- uri = 'redis://sidekiq-redis-provider:6379/0'
100
- provider = 'SIDEKIQ_REDIS_PROVIDER'
101
-
102
- ENV['REDIS_PROVIDER'] = provider
103
- ENV[provider] = uri
104
- ENV['REDISTOGO_URL'] = 'redis://redis-to-go:6379/0'
105
- with_env_var provider, uri, true
106
-
107
- ENV[provider] = nil
108
- end
109
- end
110
-
111
- describe "with REDIS_PROVIDER set" do
112
- it "sets connection URI to the provider" do
113
- uri = 'redis://sidekiq-redis-provider:6379/0'
114
- provider = 'SIDEKIQ_REDIS_PROVIDER'
115
-
116
- ENV['REDIS_PROVIDER'] = provider
117
- ENV[provider] = uri
118
-
119
- with_env_var provider, uri, true
120
-
121
- ENV[provider] = nil
122
- end
123
- end
124
-
125
- describe "with REDIS_URL set" do
126
- it "sets connection URI to custom uri" do
127
- with_env_var 'REDIS_URL', 'redis://redis-uri:6379/0'
128
- end
129
- end
130
-
131
- end
132
- end
@@ -1,326 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
- require_relative 'helper'
4
- require 'sidekiq/scheduled'
5
- require 'sidekiq/middleware/server/retry_jobs'
6
-
7
- class TestRetry < Sidekiq::Test
8
- describe 'middleware' do
9
- class SomeWorker
10
- include Sidekiq::Worker
11
- end
12
-
13
- before do
14
- Sidekiq.redis {|c| c.flushdb }
15
- end
16
-
17
- def worker
18
- @worker ||= SomeWorker.new
19
- end
20
-
21
- def handler(options={})
22
- @handler ||= Sidekiq::Middleware::Server::RetryJobs.new(options)
23
- end
24
-
25
- def job(options={})
26
- @job ||= { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }.merge(options)
27
- end
28
-
29
- it 'allows disabling retry' do
30
- assert_raises RuntimeError do
31
- handler.call(worker, job('retry' => false), 'default') do
32
- raise "kerblammo!"
33
- end
34
- end
35
- assert_equal 0, Sidekiq::RetrySet.new.size
36
- end
37
-
38
- it 'allows a numeric retry' do
39
- assert_raises RuntimeError do
40
- handler.call(worker, job('retry' => 2), 'default') do
41
- raise "kerblammo!"
42
- end
43
- end
44
- assert_equal 1, Sidekiq::RetrySet.new.size
45
- assert_equal 0, Sidekiq::DeadSet.new.size
46
- end
47
-
48
- it 'allows 0 retry => no retry and dead queue' do
49
- assert_raises RuntimeError do
50
- handler.call(worker, job('retry' => 0), 'default') do
51
- raise "kerblammo!"
52
- end
53
- end
54
- assert_equal 0, Sidekiq::RetrySet.new.size
55
- assert_equal 1, Sidekiq::DeadSet.new.size
56
- end
57
-
58
- it 'handles zany characters in error message, #1705' do
59
- skip 'skipped! test requires ruby 2.1+' if RUBY_VERSION <= '2.1.0'
60
-
61
- assert_raises RuntimeError do
62
- handler.call(worker, job, 'default') do
63
- raise "kerblammo! #{195.chr}"
64
- end
65
- end
66
- assert_equal "kerblammo! �", job["error_message"]
67
- end
68
-
69
-
70
- it 'allows a max_retries option in initializer' do
71
- max_retries = 7
72
- 1.upto(max_retries + 1) do
73
- assert_raises RuntimeError do
74
- handler(:max_retries => max_retries).call(worker, job, 'default') do
75
- raise "kerblammo!"
76
- end
77
- end
78
- end
79
-
80
- assert_equal max_retries, Sidekiq::RetrySet.new.size
81
- assert_equal 1, Sidekiq::DeadSet.new.size
82
- end
83
-
84
- it 'saves backtraces' do
85
- c = nil
86
- assert_raises RuntimeError do
87
- handler.call(worker, job('backtrace' => true), 'default') do
88
- c = caller(0); raise "kerblammo!"
89
- end
90
- end
91
- assert job["error_backtrace"]
92
- assert_equal c[0], job["error_backtrace"][0]
93
- end
94
-
95
- it 'saves partial backtraces' do
96
- c = nil
97
- assert_raises RuntimeError do
98
- handler.call(worker, job('backtrace' => 3), 'default') do
99
- c = caller(0)[0...3]; raise "kerblammo!"
100
- end
101
- end
102
- assert job["error_backtrace"]
103
- assert_equal c, job["error_backtrace"]
104
- assert_equal 3, c.size
105
- end
106
-
107
- it 'handles a new failed message' do
108
- assert_raises RuntimeError do
109
- handler.call(worker, job, 'default') do
110
- raise "kerblammo!"
111
- end
112
- end
113
- assert_equal 'default', job["queue"]
114
- assert_equal 'kerblammo!', job["error_message"]
115
- assert_equal 'RuntimeError', job["error_class"]
116
- assert_equal 0, job["retry_count"]
117
- refute job["error_backtrace"]
118
- assert job["failed_at"]
119
- end
120
-
121
- it 'shuts down without retrying work-in-progress, which will resume' do
122
- rs = Sidekiq::RetrySet.new
123
- assert_equal 0, rs.size
124
- msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
125
- assert_raises Sidekiq::Shutdown do
126
- handler.call(worker, msg, 'default') do
127
- raise Sidekiq::Shutdown
128
- end
129
- end
130
- assert_equal 0, rs.size
131
- end
132
-
133
- it 'shuts down cleanly when shutdown causes exception' do
134
- skip('Not supported in Ruby < 2.1.0') if RUBY_VERSION < '2.1.0'
135
-
136
- rs = Sidekiq::RetrySet.new
137
- assert_equal 0, rs.size
138
- msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
139
- assert_raises Sidekiq::Shutdown do
140
- handler.call(worker, msg, 'default') do
141
- begin
142
- raise Sidekiq::Shutdown
143
- rescue Interrupt
144
- raise "kerblammo!"
145
- end
146
- end
147
- end
148
- assert_equal 0, rs.size
149
- end
150
-
151
- it 'shuts down cleanly when shutdown causes chained exceptions' do
152
- skip('Not supported in Ruby < 2.1.0') if RUBY_VERSION < '2.1.0'
153
-
154
- rs = Sidekiq::RetrySet.new
155
- assert_equal 0, rs.size
156
- assert_raises Sidekiq::Shutdown do
157
- handler.call(worker, job, 'default') do
158
- begin
159
- raise Sidekiq::Shutdown
160
- rescue Interrupt
161
- begin
162
- raise "kerblammo!"
163
- rescue
164
- raise "kablooie!"
165
- end
166
- end
167
- end
168
- end
169
- assert_equal 0, rs.size
170
- end
171
-
172
- it 'allows a retry queue' do
173
- assert_raises RuntimeError do
174
- handler.call(worker, job("retry_queue" => 'retryx'), 'default') do
175
- raise "kerblammo!"
176
- end
177
- end
178
- assert_equal 'retryx', job["queue"]
179
- assert_equal 'kerblammo!', job["error_message"]
180
- assert_equal 'RuntimeError', job["error_class"]
181
- assert_equal 0, job["retry_count"]
182
- refute job["error_backtrace"]
183
- assert job["failed_at"]
184
- end
185
-
186
- it 'handles a recurring failed message' do
187
- now = Time.now.to_f
188
- msg = {"queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>10}
189
- assert_raises RuntimeError do
190
- handler.call(worker, job(msg), 'default') do
191
- raise "kerblammo!"
192
- end
193
- end
194
- assert_equal 'default', job["queue"]
195
- assert_equal 'kerblammo!', job["error_message"]
196
- assert_equal 'RuntimeError', job["error_class"]
197
- assert_equal 11, job["retry_count"]
198
- assert job["failed_at"]
199
- end
200
-
201
- it 'throws away old messages after too many retries (using the default)' do
202
- q = Sidekiq::Queue.new
203
- rs = Sidekiq::RetrySet.new
204
- ds = Sidekiq::DeadSet.new
205
- assert_equal 0, q.size
206
- assert_equal 0, rs.size
207
- assert_equal 0, ds.size
208
- now = Time.now.to_f
209
- msg = {"queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>25}
210
- assert_raises RuntimeError do
211
- handler.call(worker, job(msg), 'default') do
212
- raise "kerblammo!"
213
- end
214
- end
215
- assert_equal 0, q.size
216
- assert_equal 0, rs.size
217
- assert_equal 1, ds.size
218
- end
219
-
220
- describe "custom retry delay" do
221
- before do
222
- @old_logger = Sidekiq.logger
223
- @tmp_log_path = '/tmp/sidekiq-retries.log'
224
- Sidekiq.logger = Logger.new(@tmp_log_path)
225
- end
226
-
227
- after do
228
- Sidekiq.logger = @old_logger
229
- Sidekiq.options.delete(:logfile)
230
- File.unlink @tmp_log_path if File.exist?(@tmp_log_path)
231
- end
232
-
233
- class CustomWorkerWithoutException
234
- include Sidekiq::Worker
235
-
236
- sidekiq_retry_in do |count|
237
- count * 2
238
- end
239
- end
240
-
241
- class CustomWorkerWithException
242
- include Sidekiq::Worker
243
-
244
- sidekiq_retry_in do |count, exception|
245
- case exception
246
- when ArgumentError
247
- count * 4
248
- else
249
- count * 2
250
- end
251
- end
252
- end
253
-
254
- class ErrorWorker
255
- include Sidekiq::Worker
256
-
257
- sidekiq_retry_in do |count|
258
- count / 0
259
- end
260
- end
261
-
262
- it "retries with a default delay" do
263
- refute_equal 4, handler.__send__(:delay_for, worker, 2, StandardError.new)
264
- end
265
-
266
- it "retries with a custom delay and exception 1" do
267
- assert_equal 8, handler.__send__(:delay_for, CustomWorkerWithException, 2, ArgumentError.new)
268
- end
269
-
270
- it "retries with a custom delay and exception 2" do
271
- assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithException, 2, StandardError.new)
272
- end
273
-
274
- it "retries with a custom delay without exception" do
275
- assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithoutException, 2, StandardError.new)
276
- end
277
-
278
- it "falls back to the default retry on exception" do
279
- refute_equal 4, handler.__send__(:delay_for, ErrorWorker, 2, StandardError.new)
280
- assert_match(/Failure scheduling retry using the defined `sidekiq_retry_in`/,
281
- File.read(@tmp_log_path), 'Log entry missing for sidekiq_retry_in')
282
- end
283
- end
284
-
285
- describe 'handles errors withouth cause' do
286
- before do
287
- @error = nil
288
- begin
289
- raise ::StandardError, 'Error'
290
- rescue ::StandardError => e
291
- @error = e
292
- end
293
- end
294
-
295
- it "does not recurse infinitely checking if it's a shutdown" do
296
- assert(!Sidekiq::Middleware::Server::RetryJobs.new.send(
297
- :exception_caused_by_shutdown?, @error))
298
- end
299
- end
300
-
301
- describe 'handles errors with circular causes' do
302
- before do
303
- @error = nil
304
- begin
305
- begin
306
- raise ::StandardError, 'Error 1'
307
- rescue ::StandardError => e1
308
- begin
309
- raise ::StandardError, 'Error 2'
310
- rescue ::StandardError
311
- raise e1
312
- end
313
- end
314
- rescue ::StandardError => e
315
- @error = e
316
- end
317
- end
318
-
319
- it "does not recurse infinitely checking if it's a shutdown" do
320
- assert(!Sidekiq::Middleware::Server::RetryJobs.new.send(
321
- :exception_caused_by_shutdown?, @error))
322
- end
323
- end
324
- end
325
-
326
- end