shoryuken 5.0.5 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +17 -0
  3. data/.devcontainer/base.Dockerfile +43 -0
  4. data/.devcontainer/devcontainer.json +35 -0
  5. data/.github/dependabot.yml +6 -0
  6. data/.github/workflows/specs.yml +65 -0
  7. data/.github/workflows/stale.yml +20 -0
  8. data/.gitignore +1 -1
  9. data/.reek.yml +5 -0
  10. data/.rubocop.yml +1 -1
  11. data/Appraisals +42 -0
  12. data/CHANGELOG.md +114 -0
  13. data/Gemfile +8 -3
  14. data/README.md +41 -1
  15. data/Rakefile +15 -1
  16. data/bin/cli/sqs.rb +51 -6
  17. data/gemfiles/.gitignore +1 -0
  18. data/gemfiles/aws_sdk_core_2.gemfile +21 -0
  19. data/gemfiles/rails_4_2.gemfile +20 -0
  20. data/gemfiles/rails_5_2.gemfile +21 -0
  21. data/gemfiles/rails_6_0.gemfile +21 -0
  22. data/gemfiles/rails_6_1.gemfile +21 -0
  23. data/gemfiles/rails_7_0.gemfile +22 -0
  24. data/lib/shoryuken/default_exception_handler.rb +10 -0
  25. data/lib/shoryuken/environment_loader.rb +22 -4
  26. data/lib/shoryuken/extensions/active_job_adapter.rb +30 -20
  27. data/lib/shoryuken/extensions/active_job_extensions.rb +38 -0
  28. data/lib/shoryuken/launcher.rb +26 -3
  29. data/lib/shoryuken/logging.rb +2 -2
  30. data/lib/shoryuken/manager.rb +50 -14
  31. data/lib/shoryuken/message.rb +11 -28
  32. data/lib/shoryuken/options.rb +6 -3
  33. data/lib/shoryuken/polling/base.rb +2 -0
  34. data/lib/shoryuken/polling/strict_priority.rb +8 -0
  35. data/lib/shoryuken/polling/weighted_round_robin.rb +9 -0
  36. data/lib/shoryuken/processor.rb +1 -2
  37. data/lib/shoryuken/queue.rb +5 -3
  38. data/lib/shoryuken/runner.rb +4 -3
  39. data/lib/shoryuken/version.rb +1 -1
  40. data/lib/shoryuken.rb +8 -0
  41. data/shoryuken.gemspec +1 -2
  42. data/spec/integration/launcher_spec.rb +29 -2
  43. data/spec/shared_examples_for_active_job.rb +230 -11
  44. data/spec/shoryuken/default_exception_handler_spec.rb +71 -0
  45. data/spec/shoryuken/environment_loader_spec.rb +62 -9
  46. data/spec/shoryuken/extensions/active_job_adapter_spec.rb +1 -1
  47. data/spec/shoryuken/extensions/active_job_base_spec.rb +84 -0
  48. data/spec/shoryuken/extensions/active_job_concurrent_send_adapter_spec.rb +4 -0
  49. data/spec/shoryuken/extensions/active_job_wrapper_spec.rb +20 -0
  50. data/spec/shoryuken/fetcher_spec.rb +12 -12
  51. data/spec/shoryuken/launcher_spec.rb +105 -0
  52. data/spec/shoryuken/manager_spec.rb +61 -1
  53. data/spec/shoryuken/polling/strict_priority_spec.rb +10 -0
  54. data/spec/shoryuken/polling/weighted_round_robin_spec.rb +35 -0
  55. data/spec/shoryuken/queue_spec.rb +10 -5
  56. data/spec/shoryuken/worker/default_executor_spec.rb +48 -48
  57. data/spec/shoryuken_spec.rb +9 -0
  58. data/spec/spec_helper.rb +7 -9
  59. metadata +32 -24
  60. data/.travis.yml +0 -30
  61. data/Gemfile.aws-sdk-core-v2 +0 -13
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'active_job'
3
+ require 'shoryuken/extensions/active_job_extensions'
4
+ require 'shoryuken/extensions/active_job_adapter'
5
+
6
+ RSpec.describe ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper do
7
+ subject { described_class.new }
8
+
9
+ describe '#perform' do
10
+ it 'sets executions to reflect approximate receive count' do
11
+ attributes = { 'ApproximateReceiveCount' => '42' }
12
+ sqs_msg = double Shoryuken::Message, attributes: attributes
13
+ job_hash = { 'arguments' => [1, 2, 3] }
14
+ job_hash_with_executions = { 'arguments' => [1, 2, 3], 'executions' => 41 }
15
+ expect(ActiveJob::Base).to receive(:execute).with(job_hash_with_executions)
16
+
17
+ subject.perform sqs_msg, job_hash
18
+ end
19
+ end
20
+ end
@@ -28,12 +28,12 @@ RSpec.describe Shoryuken::Fetcher do
28
28
 
29
29
  Shoryuken.sqs_client_receive_message_opts[group] = { wait_time_seconds: 10 }
30
30
 
31
- expect(queue).to receive(:receive_messages).with(
31
+ expect(queue).to receive(:receive_messages).with({
32
32
  wait_time_seconds: 10,
33
33
  max_number_of_messages: limit,
34
34
  message_attribute_names: ['All'],
35
35
  attribute_names: ['All']
36
- ).and_return([])
36
+ }).and_return([])
37
37
 
38
38
  subject.fetch(queue_config, limit)
39
39
  end
@@ -62,11 +62,11 @@ RSpec.describe Shoryuken::Fetcher do
62
62
 
63
63
  Shoryuken.sqs_client_receive_message_opts[queue_name] = { max_number_of_messages: 1 }
64
64
 
65
- expect(queue).to receive(:receive_messages).with(
65
+ expect(queue).to receive(:receive_messages).with({
66
66
  max_number_of_messages: 1,
67
67
  message_attribute_names: ['All'],
68
68
  attribute_names: ['All']
69
- ).and_return([])
69
+ }).and_return([])
70
70
 
71
71
  subject.fetch(queue_config, limit)
72
72
  end
@@ -78,11 +78,11 @@ RSpec.describe Shoryuken::Fetcher do
78
78
 
79
79
  Shoryuken.sqs_client_receive_message_opts[queue_name] = { max_number_of_messages: 20 }
80
80
 
81
- expect(queue).to receive(:receive_messages).with(
81
+ expect(queue).to receive(:receive_messages).with({
82
82
  max_number_of_messages: limit,
83
83
  message_attribute_names: ['All'],
84
84
  attribute_names: ['All']
85
- ).and_return([])
85
+ }).and_return([])
86
86
 
87
87
  subject.fetch(queue_config, limit)
88
88
  end
@@ -93,9 +93,9 @@ RSpec.describe Shoryuken::Fetcher do
93
93
 
94
94
  specify do
95
95
  allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
96
- expect(queue).to receive(:receive_messages).with(
96
+ expect(queue).to receive(:receive_messages).with({
97
97
  max_number_of_messages: described_class::FETCH_LIMIT, attribute_names: ['All'], message_attribute_names: ['All']
98
- ).and_return([])
98
+ }).and_return([])
99
99
 
100
100
  subject.fetch(queue_config, limit)
101
101
  end
@@ -109,9 +109,9 @@ RSpec.describe Shoryuken::Fetcher do
109
109
  # see https://github.com/phstc/shoryuken/pull/530
110
110
 
111
111
  allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
112
- expect(queue).to receive(:receive_messages).with(
112
+ expect(queue).to receive(:receive_messages).with({
113
113
  max_number_of_messages: 1, attribute_names: ['All'], message_attribute_names: ['All']
114
- ).and_return([])
114
+ }).and_return([])
115
115
 
116
116
  subject.fetch(queue_config, limit)
117
117
  end
@@ -123,9 +123,9 @@ RSpec.describe Shoryuken::Fetcher do
123
123
  allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
124
124
  allow(Shoryuken.worker_registry).to receive(:batch_receive_messages?).with(queue.name).and_return(true)
125
125
 
126
- expect(queue).to receive(:receive_messages).with(
126
+ expect(queue).to receive(:receive_messages).with({
127
127
  max_number_of_messages: limit, attribute_names: ['All'], message_attribute_names: ['All']
128
- ).and_return([])
128
+ }).and_return([])
129
129
 
130
130
  subject.fetch(queue_config, limit)
131
131
  end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+ require 'shoryuken/launcher'
3
+
4
+ RSpec.describe Shoryuken::Launcher do
5
+ let(:executor) do
6
+ # We can't use Concurrent.global_io_executor in these tests since once you
7
+ # shut down a thread pool, you can't start it back up. Instead, we create
8
+ # one new thread pool executor for each spec. We use a new
9
+ # CachedThreadPool, since that most closely resembles
10
+ # Concurrent.global_io_executor
11
+ Concurrent::CachedThreadPool.new auto_terminate: true
12
+ end
13
+
14
+ let(:first_group_manager) { double(:first_group_manager, group: 'first_group') }
15
+ let(:second_group_manager) { double(:second_group_manager, group: 'second_group') }
16
+ let(:first_queue) { "launcher_spec_#{SecureRandom.uuid}" }
17
+ let(:second_queue) { "launcher_spec_#{SecureRandom.uuid}" }
18
+
19
+ before do
20
+ Shoryuken.add_group('first_group', 1)
21
+ Shoryuken.add_group('second_group', 1)
22
+ Shoryuken.add_queue(first_queue, 1, 'first_group')
23
+ Shoryuken.add_queue(second_queue, 1, 'second_group')
24
+ allow(Shoryuken).to receive(:launcher_executor).and_return(executor)
25
+ allow(Shoryuken::Manager).to receive(:new).with('first_group', any_args).and_return(first_group_manager)
26
+ allow(Shoryuken::Manager).to receive(:new).with('second_group', any_args).and_return(second_group_manager)
27
+ allow(first_group_manager).to receive(:running?).and_return(true)
28
+ allow(second_group_manager).to receive(:running?).and_return(true)
29
+ end
30
+
31
+ describe '#healthy?' do
32
+ context 'when all groups have managers' do
33
+ context 'when all managers are running' do
34
+ it 'returns true' do
35
+ expect(subject.healthy?).to be true
36
+ end
37
+ end
38
+
39
+ context 'when one manager is not running' do
40
+ before do
41
+ allow(second_group_manager).to receive(:running?).and_return(false)
42
+ end
43
+
44
+ it 'returns false' do
45
+ expect(subject.healthy?).to be false
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'when all groups do not have managers' do
51
+ before do
52
+ allow(second_group_manager).to receive(:group).and_return('some_random_group')
53
+ end
54
+
55
+ it 'returns false' do
56
+ expect(subject.healthy?).to be false
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#stop' do
62
+ before do
63
+ allow(first_group_manager).to receive(:stop_new_dispatching)
64
+ allow(first_group_manager).to receive(:await_dispatching_in_progress)
65
+ allow(second_group_manager).to receive(:stop_new_dispatching)
66
+ allow(second_group_manager).to receive(:await_dispatching_in_progress)
67
+ end
68
+
69
+ it 'fires quiet, shutdown and stopped event' do
70
+ allow(subject).to receive(:fire_event)
71
+ subject.stop
72
+ expect(subject).to have_received(:fire_event).with(:quiet, true)
73
+ expect(subject).to have_received(:fire_event).with(:shutdown, true)
74
+ expect(subject).to have_received(:fire_event).with(:stopped)
75
+ end
76
+
77
+ it 'stops the managers' do
78
+ subject.stop
79
+ expect(first_group_manager).to have_received(:stop_new_dispatching)
80
+ expect(second_group_manager).to have_received(:stop_new_dispatching)
81
+ end
82
+ end
83
+
84
+ describe '#stop!' do
85
+ before do
86
+ allow(first_group_manager).to receive(:stop_new_dispatching)
87
+ allow(first_group_manager).to receive(:await_dispatching_in_progress)
88
+ allow(second_group_manager).to receive(:stop_new_dispatching)
89
+ allow(second_group_manager).to receive(:await_dispatching_in_progress)
90
+ end
91
+
92
+ it 'fires shutdown and stopped event' do
93
+ allow(subject).to receive(:fire_event)
94
+ subject.stop!
95
+ expect(subject).to have_received(:fire_event).with(:shutdown, true)
96
+ expect(subject).to have_received(:fire_event).with(:stopped)
97
+ end
98
+
99
+ it 'stops the managers' do
100
+ subject.stop!
101
+ expect(first_group_manager).to have_received(:stop_new_dispatching)
102
+ expect(second_group_manager).to have_received(:stop_new_dispatching)
103
+ end
104
+ end
105
+ end
@@ -15,7 +15,7 @@ RSpec.describe Shoryuken::Manager do
15
15
  let(:concurrency) { 1 }
16
16
  let(:executor) { Concurrent::ImmediateExecutor.new }
17
17
 
18
- subject { Shoryuken::Manager.new(fetcher, polling_strategy, concurrency, executor) }
18
+ subject { Shoryuken::Manager.new('default', fetcher, polling_strategy, concurrency, executor) }
19
19
 
20
20
  before do
21
21
  allow(fetcher).to receive(:fetch).and_return([])
@@ -71,6 +71,13 @@ RSpec.describe Shoryuken::Manager do
71
71
 
72
72
  expect(fetcher).to receive(:fetch).with(q, concurrency).and_return(messages)
73
73
  expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
74
+ expect(subject).to receive(:fire_event).with(:utilization_update,
75
+ false,
76
+ {
77
+ group: 'default',
78
+ busy_processors: 1,
79
+ max_processors: 1
80
+ })
74
81
  expect(Shoryuken::Processor).to receive(:process).with(q, message)
75
82
  expect(Shoryuken.logger).to receive(:info).never
76
83
 
@@ -99,6 +106,13 @@ RSpec.describe Shoryuken::Manager do
99
106
  q = Shoryuken::Polling::QueueConfiguration.new(queue, {})
100
107
 
101
108
  expect(fetcher).to receive(:fetch).with(q, described_class::BATCH_LIMIT).and_return(messages)
109
+ expect(subject).to receive(:fire_event).with(:utilization_update,
110
+ false,
111
+ {
112
+ group: 'default',
113
+ busy_processors: 1,
114
+ max_processors: 1
115
+ })
102
116
  expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
103
117
  allow(subject).to receive(:batched_queue?).with(q).and_return(true)
104
118
  expect(Shoryuken::Processor).to receive(:process).with(q, messages)
@@ -139,4 +153,50 @@ RSpec.describe Shoryuken::Manager do
139
153
  subject.send(:dispatch_single_messages, q)
140
154
  end
141
155
  end
156
+
157
+ describe '#processor_done' do
158
+ let(:sqs_queue) { double Shoryuken::Queue }
159
+
160
+ before do
161
+ allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
162
+ end
163
+
164
+ context 'when queue.fifo? is true' do
165
+ it 'calls message_processed on strategy' do
166
+ expect(sqs_queue).to receive(:fifo?).and_return(true)
167
+ expect(polling_strategy).to receive(:message_processed).with(queue)
168
+ subject.send(:processor_done, queue)
169
+ end
170
+ end
171
+
172
+ context 'when queue.fifo? is false' do
173
+ it 'does not call message_processed on strategy' do
174
+ expect(sqs_queue).to receive(:fifo?).and_return(false)
175
+ expect(polling_strategy).to_not receive(:message_processed)
176
+ subject.send(:processor_done, queue)
177
+ end
178
+ end
179
+ end
180
+
181
+ describe '#running?' do
182
+ context 'when the executor is running' do
183
+ before do
184
+ allow(executor).to receive(:running?).and_return(true)
185
+ end
186
+
187
+ it 'returns true' do
188
+ expect(subject.running?).to be true
189
+ end
190
+ end
191
+
192
+ context 'when the executor is not running' do
193
+ before do
194
+ allow(executor).to receive(:running?).and_return(false)
195
+ end
196
+
197
+ it 'returns false' do
198
+ expect(subject.running?).to be false
199
+ end
200
+ end
201
+ end
142
202
  end
@@ -145,4 +145,14 @@ RSpec.describe Shoryuken::Polling::StrictPriority do
145
145
  expect(subject.next_queue).to eq(queue3)
146
146
  end
147
147
  end
148
+
149
+ describe '#message_processed' do
150
+ it 'removes paused queue, adds to active queues' do
151
+ strategy = Shoryuken::Polling::StrictPriority.new([queue1, queue2])
152
+ strategy.send(:pause, queue1)
153
+ expect(strategy.active_queues).to eq([[queue2, 1]])
154
+ strategy.message_processed(queue1)
155
+ expect(strategy.active_queues).to eq([[queue1, 2], [queue2, 1]])
156
+ end
157
+ end
148
158
  end
@@ -104,4 +104,39 @@ RSpec.describe Shoryuken::Polling::WeightedRoundRobin do
104
104
  expect(subject.delay).to eq(1.0)
105
105
  end
106
106
  end
107
+
108
+ describe '#message_processed' do
109
+ it 'removes delay from paused queue' do
110
+ queues << queue1
111
+ queues << queue2
112
+
113
+ expect(subject.next_queue).to eq(queue1)
114
+ subject.messages_found(queue1, 0) # pauses queue1
115
+
116
+ expect(subject.active_queues).to eq([[queue2, 1]])
117
+
118
+ subject.message_processed(queue1) # marks queue1 to be unpaused
119
+
120
+ expect(subject.next_queue).to eq(queue2) # implicitly unpauses queue1
121
+ expect(subject.active_queues).to eq([[queue1, 1], [queue2, 1]])
122
+ end
123
+
124
+ it 'preserves weight of queues when unpausing' do
125
+ queues << queue1
126
+ queues << queue1
127
+ queues << queue2
128
+
129
+ expect(subject.next_queue).to eq(queue1)
130
+ subject.messages_found(queue1, 1)
131
+
132
+ expect(subject.next_queue).to eq(queue2)
133
+ subject.messages_found(queue2, 0) # pauses queue2
134
+
135
+ expect(subject.active_queues).to eq([[queue1, 2]])
136
+ subject.message_processed(queue2) # marks queue2 to be unpaused
137
+
138
+ expect(subject.next_queue).to eq(queue1) # implicitly unpauses queue2
139
+ expect(subject.active_queues).to eq([[queue1, 2], [queue2, 1]])
140
+ end
141
+ end
107
142
  end
@@ -80,7 +80,8 @@ RSpec.describe Shoryuken::Queue do
80
80
  end
81
81
 
82
82
  it 'deletes' do
83
- expect(sqs).to receive(:delete_message_batch).with(entries: entries, queue_url: queue_url).and_return(double(failed: []))
83
+ expect(sqs).to receive(:delete_message_batch).with({ entries: entries,
84
+ queue_url: queue_url }).and_return(double(failed: []))
84
85
 
85
86
  subject.delete_messages(entries: entries)
86
87
  end
@@ -91,7 +92,8 @@ RSpec.describe Shoryuken::Queue do
91
92
  logger = double 'Logger'
92
93
 
93
94
  expect(sqs).to(
94
- receive(:delete_message_batch).with(entries: entries, queue_url: queue_url).and_return(double(failed: [failure]))
95
+ receive(:delete_message_batch).with({ entries: entries,
96
+ queue_url: queue_url }).and_return(double(failed: [failure]))
95
97
  )
96
98
  expect(subject).to receive(:logger).and_return(logger)
97
99
  expect(logger).to receive(:error)
@@ -157,7 +159,8 @@ RSpec.describe Shoryuken::Queue do
157
159
  it 'accepts SQS request parameters' do
158
160
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#send_message_batch-instance_method
159
161
  expect(sqs).to(
160
- receive(:send_message_batch).with(hash_including(entries: [{ id: '0', message_body: 'msg1' }, { id: '1', message_body: 'msg2' }]))
162
+ receive(:send_message_batch).with(hash_including(entries: [{ id: '0', message_body: 'msg1' },
163
+ { id: '1', message_body: 'msg2' }]))
161
164
  )
162
165
 
163
166
  subject.send_messages(entries: [{ id: '0', message_body: 'msg1' }, { id: '1', message_body: 'msg2' }])
@@ -286,7 +289,8 @@ RSpec.describe Shoryuken::Queue do
286
289
  Shoryuken.cache_visibility_timeout = false
287
290
 
288
291
  expect(sqs).to(
289
- receive(:get_queue_attributes).with(queue_url: queue_url, attribute_names: ['All']).and_return(attribute_response).exactly(3).times
292
+ receive(:get_queue_attributes).with(queue_url: queue_url,
293
+ attribute_names: ['All']).and_return(attribute_response).exactly(3).times
290
294
  )
291
295
  expect(subject.visibility_timeout).to eq(30)
292
296
  expect(subject.visibility_timeout).to eq(30)
@@ -299,7 +303,8 @@ RSpec.describe Shoryuken::Queue do
299
303
  Shoryuken.cache_visibility_timeout = true
300
304
 
301
305
  expect(sqs).to(
302
- receive(:get_queue_attributes).with(queue_url: queue_url, attribute_names: ['All']).and_return(attribute_response).once
306
+ receive(:get_queue_attributes).with({ queue_url: queue_url,
307
+ attribute_names: ['All'] }).and_return(attribute_response).once
303
308
  )
304
309
  expect(subject.visibility_timeout).to eq(30)
305
310
  expect(subject.visibility_timeout).to eq(30)
@@ -10,16 +10,16 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
10
10
 
11
11
  describe '.perform_in' do
12
12
  it 'delays a message' do
13
- expect(sqs_queue).to receive(:send_message).with(
14
- message_attributes: {
15
- 'shoryuken_class' => {
16
- string_value: TestWorker.to_s,
17
- data_type: 'String'
18
- }
19
- },
20
- message_body: 'message',
21
- delay_seconds: 60
22
- )
13
+ expect(sqs_queue).to receive(:send_message).with({
14
+ message_attributes: {
15
+ 'shoryuken_class' => {
16
+ string_value: TestWorker.to_s,
17
+ data_type: 'String'
18
+ }
19
+ },
20
+ message_body: 'message',
21
+ delay_seconds: 60
22
+ })
23
23
 
24
24
  TestWorker.perform_in(60, 'message')
25
25
  end
@@ -33,16 +33,16 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
33
33
 
34
34
  describe '.perform_at' do
35
35
  it 'delays a message' do
36
- expect(sqs_queue).to receive(:send_message).with(
37
- message_attributes: {
38
- 'shoryuken_class' => {
39
- string_value: TestWorker.to_s,
40
- data_type: 'String'
41
- }
42
- },
43
- message_body: 'message',
44
- delay_seconds: 60
45
- )
36
+ expect(sqs_queue).to receive(:send_message).with({
37
+ message_attributes: {
38
+ 'shoryuken_class' => {
39
+ string_value: TestWorker.to_s,
40
+ data_type: 'String'
41
+ }
42
+ },
43
+ message_body: 'message',
44
+ delay_seconds: 60
45
+ })
46
46
 
47
47
  TestWorker.perform_in(Time.now + 60, 'message')
48
48
  end
@@ -56,30 +56,30 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
56
56
 
57
57
  describe '.perform_async' do
58
58
  it 'enqueues a message' do
59
- expect(sqs_queue).to receive(:send_message).with(
60
- message_attributes: {
61
- 'shoryuken_class' => {
62
- string_value: TestWorker.to_s,
63
- data_type: 'String'
64
- }
65
- },
66
- message_body: 'message'
67
- )
59
+ expect(sqs_queue).to receive(:send_message).with({
60
+ message_attributes: {
61
+ 'shoryuken_class' => {
62
+ string_value: TestWorker.to_s,
63
+ data_type: 'String'
64
+ }
65
+ },
66
+ message_body: 'message'
67
+ })
68
68
 
69
69
  TestWorker.perform_async('message')
70
70
  end
71
71
 
72
72
  it 'enqueues a message with options' do
73
- expect(sqs_queue).to receive(:send_message).with(
74
- delay_seconds: 60,
75
- message_attributes: {
76
- 'shoryuken_class' => {
77
- string_value: TestWorker.to_s,
78
- data_type: 'String'
79
- }
80
- },
81
- message_body: 'delayed message'
82
- )
73
+ expect(sqs_queue).to receive(:send_message).with({
74
+ delay_seconds: 60,
75
+ message_attributes: {
76
+ 'shoryuken_class' => {
77
+ string_value: TestWorker.to_s,
78
+ data_type: 'String'
79
+ }
80
+ },
81
+ message_body: 'delayed message'
82
+ })
83
83
 
84
84
  TestWorker.perform_async('delayed message', delay_seconds: 60)
85
85
  end
@@ -89,15 +89,15 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
89
89
 
90
90
  expect(Shoryuken::Client).to receive(:queues).with(new_queue).and_return(sqs_queue)
91
91
 
92
- expect(sqs_queue).to receive(:send_message).with(
93
- message_attributes: {
94
- 'shoryuken_class' => {
95
- string_value: TestWorker.to_s,
96
- data_type: 'String'
97
- }
98
- },
99
- message_body: 'delayed message'
100
- )
92
+ expect(sqs_queue).to receive(:send_message).with({
93
+ message_attributes: {
94
+ 'shoryuken_class' => {
95
+ string_value: TestWorker.to_s,
96
+ data_type: 'String'
97
+ }
98
+ },
99
+ message_body: 'delayed message'
100
+ })
101
101
 
102
102
  TestWorker.perform_async('delayed message', queue: new_queue)
103
103
  end
@@ -1,4 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe Shoryuken do
4
+ describe '.healthy?' do
5
+ before do
6
+ allow(Shoryuken::Runner).to receive(:instance).and_return(double(:instance, healthy?: :some_result))
7
+ end
8
+
9
+ it 'delegates to the runner instance' do
10
+ expect(described_class.healthy?).to eq(:some_result)
11
+ end
12
+ end
4
13
  end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,11 @@
1
1
  require 'bundler/setup'
2
2
  Bundler.setup
3
3
 
4
- require 'pry-byebug'
4
+ begin
5
+ require 'pry-byebug'
6
+ rescue LoadError
7
+ end
8
+
5
9
  require 'shoryuken'
6
10
  require 'json'
7
11
  require 'dotenv'
@@ -28,13 +32,6 @@ class TestWorker
28
32
  end
29
33
 
30
34
  RSpec.configure do |config|
31
- # Only run slow tests if SPEC_ALL=true and AWS_ACCESS_KEY_ID is present
32
- # The AWS_ACCESS_KEY_ID checker is because Travis CI
33
- # does not expose ENV variables to pull requests from forked repositories
34
- # http://docs.travis-ci.com/user/pull-requests/
35
- # config.filter_run_excluding slow: true if ENV['SPEC_ALL'] != 'true' || ENV['AWS_ACCESS_KEY_ID'].nil?
36
- config.filter_run_excluding slow: true
37
-
38
35
  config.before do
39
36
  Shoryuken::Client.class_variable_set :@@queues, {}
40
37
 
@@ -49,6 +46,8 @@ RSpec.configure do |config|
49
46
  Shoryuken.options[:logfile] = nil
50
47
  Shoryuken.options[:queues] = nil
51
48
 
49
+ Shoryuken.options[:exception_handlers] = []
50
+
52
51
  TestWorker.get_shoryuken_options.clear
53
52
  TestWorker.get_shoryuken_options['queue'] = 'default'
54
53
 
@@ -63,7 +62,6 @@ RSpec.configure do |config|
63
62
 
64
63
  Shoryuken.cache_visibility_timeout = false
65
64
 
66
- allow(Concurrent).to receive(:global_io_executor).and_return(Concurrent::ImmediateExecutor.new)
67
65
  allow(Shoryuken).to receive(:active_job?).and_return(false)
68
66
  end
69
67
  end