shoryuken 0.0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,62 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Shoryuken::Client do
4
- let(:sqs) { double 'SQS' }
5
- let(:queue_collection) { double 'Queues Collection' }
6
- let(:sqs_queue) { double 'SQS Queue' }
7
- let(:queue) { 'shoryuken' }
4
+ let(:credentials) { Aws::Credentials.new('access_key_id', 'secret_access_key') }
5
+ let(:sqs) { Aws::SQS::Client.new(stub_responses: true, credentials: credentials) }
6
+ let(:queue_name) { 'shoryuken' }
7
+ let(:queue_url) { 'https://eu-west-1.amazonaws.com:6059/123456789012/shoryuken' }
8
8
 
9
9
  before do
10
- allow(described_class).to receive(:sqs).and_return(sqs)
11
- allow(sqs).to receive(:queues).and_return(queue_collection)
12
- allow(queue_collection).to receive(:named).and_return(sqs_queue)
10
+ described_class.sqs = sqs
13
11
  end
14
12
 
15
- describe '.queues' do
13
+ describe '.queue' do
16
14
  it 'memoizes queues' do
17
- expect(queue_collection).to receive(:named).once.with(queue).and_return(sqs_queue)
15
+ sqs.stub_responses(:get_queue_url, { queue_url: queue_url }, { queue_url: 'xyz' })
18
16
 
19
- expect(Shoryuken::Client.queues(queue)).to eq sqs_queue
20
- expect(Shoryuken::Client.queues(queue)).to eq sqs_queue
21
- end
22
- end
23
-
24
- describe '.send_message' do
25
- it 'enqueues a message' do
26
- expect(sqs_queue).to receive(:send_message).with('test', {})
27
-
28
- described_class.send_message(queue, 'test')
29
- end
30
-
31
- it 'enqueues a message with options' do
32
- expect(sqs_queue).to receive(:send_message).with('test2', delay_seconds: 60)
33
-
34
- described_class.send_message(queue, 'test2', delay_seconds: 60)
35
- end
36
-
37
- it 'parsers as JSON by default' do
38
- msg = { field: 'test', other_field: 'other' }
39
-
40
- expect(sqs_queue).to receive(:send_message).with(JSON.dump(msg), {})
41
-
42
- described_class.send_message(queue, msg)
43
- end
44
-
45
- it 'parsers as JSON by default and keep the options' do
46
- msg = { field: 'test', other_field: 'other' }
47
-
48
- expect(sqs_queue).to receive(:send_message).with(JSON.dump(msg), { delay_seconds: 60 })
49
-
50
- described_class.send_message(queue, msg, delay_seconds: 60)
51
- end
52
- end
53
-
54
- describe '.visibility_timeout' do
55
- it 'memoizes visibility_timeout' do
56
- expect(sqs_queue).to receive(:visibility_timeout).once.and_return(30)
57
-
58
- expect(Shoryuken::Client.visibility_timeout(queue)).to eq 30
59
- expect(Shoryuken::Client.visibility_timeout(queue)).to eq 30
17
+ expect(Shoryuken::Client.queues(queue_name).url).to eq queue_url
18
+ expect(Shoryuken::Client.queues(queue_name).url).to eq queue_url
60
19
  end
61
20
  end
62
21
  end
@@ -48,7 +48,7 @@ describe Shoryuken::DefaultWorkerRegistry do
48
48
  string_value: explicit_worker.to_s,
49
49
  data_type: 'String' } if explicit_worker
50
50
 
51
- double AWS::SQS::ReceivedMessage,
51
+ double Aws::SQS::Message,
52
52
  body: 'test',
53
53
  message_attributes: attributes,
54
54
  message_id: SecureRandom.uuid
@@ -3,62 +3,68 @@ require 'shoryuken/manager'
3
3
  require 'shoryuken/fetcher'
4
4
 
5
5
  describe Shoryuken::Fetcher do
6
- let(:manager) { double Shoryuken::Manager }
7
- let(:sqs_queue) { double 'sqs_queue' }
8
- let(:queue) { 'default' }
9
- let(:sqs_msg) { double AWS::SQS::ReceivedMessage, id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e', body: 'test' }
6
+ let(:manager) { double Shoryuken::Manager }
7
+ let(:queue) { double Aws::SQS::Queue }
8
+ let(:queue_name) { 'default' }
9
+
10
+ let(:sqs_msg) do
11
+ double Aws::SQS::Message,
12
+ queue_url: queue_name,
13
+ body: 'test',
14
+ message_id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e'
15
+ end
10
16
 
11
17
  subject { described_class.new(manager) }
12
18
 
13
19
  before do
14
20
  allow(manager).to receive(:async).and_return(manager)
15
- allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
21
+ allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
16
22
  end
17
23
 
18
24
 
19
25
  describe '#fetch' do
20
26
  it 'calls pause when no message' do
21
- allow(sqs_queue).to receive(:receive_message).with(limit: 1, message_attribute_names: ['shoryuken_class']).and_return([])
27
+ allow(queue).to receive(:receive_messages).with(max_number_of_messages: 1, message_attribute_names: ['All']).and_return([])
22
28
 
23
- expect(manager).to receive(:pause_queue!).with(queue)
29
+ expect(manager).to receive(:pause_queue!).with(queue_name)
24
30
  expect(manager).to receive(:dispatch)
25
31
 
26
- subject.fetch(queue, 1)
32
+ subject.fetch(queue_name, 1)
27
33
  end
28
34
 
29
35
  it 'assigns messages' do
30
- allow(sqs_queue).to receive(:receive_message).with(limit: 5, message_attribute_names: ['shoryuken_class']).and_return(sqs_msg)
36
+ allow(queue).to receive(:receive_messages).with(max_number_of_messages: 5, message_attribute_names: ['All']).and_return(sqs_msg)
31
37
 
32
- expect(manager).to receive(:rebalance_queue_weight!).with(queue)
33
- expect(manager).to receive(:assign).with(queue, sqs_msg)
38
+ expect(manager).to receive(:rebalance_queue_weight!).with(queue_name)
39
+ expect(manager).to receive(:assign).with(queue_name, sqs_msg)
34
40
  expect(manager).to receive(:dispatch)
35
41
 
36
- subject.fetch(queue, 5)
42
+ subject.fetch(queue_name, 5)
37
43
  end
38
44
 
39
45
  it 'assigns messages in batch' do
40
46
  TestWorker.get_shoryuken_options['batch'] = true
41
47
 
42
- allow(sqs_queue).to receive(:receive_message).with(limit: described_class::FETCH_LIMIT, message_attribute_names: ['shoryuken_class']).and_return(sqs_msg)
48
+ allow(queue).to receive(:receive_messages).with(max_number_of_messages: described_class::FETCH_LIMIT, message_attribute_names: ['All']).and_return(sqs_msg)
43
49
 
44
- expect(manager).to receive(:rebalance_queue_weight!).with(queue)
45
- expect(manager).to receive(:assign).with(queue, [sqs_msg])
50
+ expect(manager).to receive(:rebalance_queue_weight!).with(queue_name)
51
+ expect(manager).to receive(:assign).with(queue_name, [sqs_msg])
46
52
  expect(manager).to receive(:dispatch)
47
53
 
48
- subject.fetch(queue, 5)
54
+ subject.fetch(queue_name, 5)
49
55
  end
50
56
 
51
57
  context 'when worker not found' do
52
- let(:queue) { 'notfound' }
58
+ let(:queue_name) { 'notfound' }
53
59
 
54
60
  it 'ignores batch' do
55
- allow(sqs_queue).to receive(:receive_message).with(limit: 5, message_attribute_names: ['shoryuken_class']).and_return(sqs_msg)
61
+ allow(queue).to receive(:receive_messages).with(max_number_of_messages: 5, message_attribute_names: ['All']).and_return(sqs_msg)
56
62
 
57
- expect(manager).to receive(:rebalance_queue_weight!).with(queue)
58
- expect(manager).to receive(:assign).with(queue, sqs_msg)
63
+ expect(manager).to receive(:rebalance_queue_weight!).with(queue_name)
64
+ expect(manager).to receive(:assign).with(queue_name, sqs_msg)
59
65
  expect(manager).to receive(:dispatch)
60
66
 
61
- subject.fetch(queue, 5)
67
+ subject.fetch(queue_name, 5)
62
68
  end
63
69
  end
64
70
  end
@@ -1,9 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Shoryuken::Middleware::Server::AutoDelete do
4
- let(:sqs_msg) { double AWS::SQS::ReceivedMessage, id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e', body: 'test' }
5
4
  let(:queue) { 'default' }
6
- let(:sqs_queue) { double AWS::SQS::Queue }
5
+ let(:sqs_queue) { double Aws::SQS::Queue }
6
+
7
+ def build_message
8
+ double Aws::SQS::Message,
9
+ queue_url: queue,
10
+ body: 'test',
11
+ receipt_handle: SecureRandom.uuid
12
+ end
13
+
14
+ let(:sqs_msg) { build_message }
7
15
 
8
16
  before do
9
17
  allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
@@ -12,7 +20,8 @@ describe Shoryuken::Middleware::Server::AutoDelete do
12
20
  it 'deletes a message' do
13
21
  TestWorker.get_shoryuken_options['auto_delete'] = true
14
22
 
15
- expect(sqs_queue).to receive(:batch_delete).with(sqs_msg)
23
+ expect(sqs_queue).to receive(:delete_messages).with(entries: [
24
+ { id: '0', receipt_handle: sqs_msg.receipt_handle }])
16
25
 
17
26
  subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) {}
18
27
  end
@@ -20,12 +29,15 @@ describe Shoryuken::Middleware::Server::AutoDelete do
20
29
  it 'deletes a batch' do
21
30
  TestWorker.get_shoryuken_options['auto_delete'] = true
22
31
 
23
- sqs_msg2 = double 'SQS msg', body: 'test'
24
- sqs_msg3 = double 'SQS msg', body: 'test'
32
+ sqs_msg2 = build_message
33
+ sqs_msg3 = build_message
25
34
 
26
35
  sqs_msgs = [sqs_msg, sqs_msg2, sqs_msg3]
27
36
 
28
- expect(sqs_queue).to receive(:batch_delete).with(*sqs_msgs)
37
+ expect(sqs_queue).to receive(:delete_messages).with(entries: [
38
+ { id: '0', receipt_handle: sqs_msg.receipt_handle },
39
+ { id: '1', receipt_handle: sqs_msg2.receipt_handle },
40
+ { id: '2', receipt_handle: sqs_msg3.receipt_handle }])
29
41
 
30
42
  subject.call(TestWorker.new, queue, sqs_msgs, [sqs_msg.body, sqs_msg2.body, sqs_msg3.body]) {}
31
43
  end
@@ -33,14 +45,14 @@ describe Shoryuken::Middleware::Server::AutoDelete do
33
45
  it 'does not delete a message' do
34
46
  TestWorker.get_shoryuken_options['auto_delete'] = false
35
47
 
36
- expect(sqs_queue).to_not receive(:batch_delete)
48
+ expect(sqs_queue).to_not receive(:delete_messages)
37
49
 
38
50
  subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) {}
39
51
  end
40
52
 
41
53
  context 'when exception' do
42
54
  it 'does not delete a message' do
43
- expect(sqs_queue).to_not receive(:batch_delete)
55
+ expect(sqs_queue).to_not receive(:delete_messages)
44
56
 
45
57
  expect {
46
58
  subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise }
@@ -1,10 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Shoryuken::Middleware::Server::Timing do
4
- let(:sqs_msg) { double AWS::SQS::ReceivedMessage, id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e', body: 'test' }
5
- let(:queue) { 'default' }
4
+ let(:queue) { 'default' }
5
+ let(:sqs_queue) { double Aws::SQS::Queue, visibility_timeout: 60 }
6
+
7
+ let(:sqs_msg) do
8
+ double Aws::SQS::Message,
9
+ queue_url: queue,
10
+ body: 'test',
11
+ message_id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e'
12
+ end
13
+
14
+ before do
15
+ allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
16
+ end
6
17
 
7
- xit 'logs timing' do
18
+ it 'logs timing' do
8
19
  expect(Shoryuken.logger).to receive(:info).with(/started at/)
9
20
  expect(Shoryuken.logger).to receive(:info).with(/completed in/)
10
21
 
@@ -13,7 +24,6 @@ describe Shoryuken::Middleware::Server::Timing do
13
24
 
14
25
  context 'when exceeded the `visibility_timeout`' do
15
26
  it 'logs exceeded' do
16
- allow(Shoryuken::Client).to receive(:visibility_timeout).and_return(60)
17
27
  allow(subject).to receive(:elapsed).and_return(120000)
18
28
 
19
29
  expect(Shoryuken.logger).to receive(:info).with(/started at/)
@@ -4,9 +4,17 @@ require 'shoryuken/manager'
4
4
 
5
5
  describe Shoryuken::Processor do
6
6
  let(:manager) { double Shoryuken::Manager, processor_done: nil }
7
- let(:sqs_queue) { double AWS::SQS::Queue, visibility_timeout: 30 }
7
+ let(:sqs_queue) { double Aws::SQS::Queue, visibility_timeout: 30 }
8
8
  let(:queue) { 'default' }
9
- let(:sqs_msg) { double AWS::SQS::ReceivedMessage, id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e', body: 'test', message_attributes: {} }
9
+
10
+ let(:sqs_msg) do
11
+ double Aws::SQS::Message,
12
+ queue_url: queue,
13
+ body: 'test',
14
+ message_attributes: {},
15
+ message_id: SecureRandom.uuid,
16
+ receipt_handle: SecureRandom.uuid
17
+ end
10
18
 
11
19
  subject { described_class.new(manager) }
12
20
 
@@ -110,29 +118,66 @@ describe Shoryuken::Processor do
110
118
 
111
119
  def perform(sqs_msg, body); end
112
120
  end
121
+ end
113
122
 
114
- Shoryuken.configure_server do |config|
115
- config.server_middleware do |chain|
116
- chain.add WorkerCalledMiddleware
123
+ context 'server' do
124
+ before do
125
+ allow(Shoryuken).to receive(:server?).and_return(true)
126
+ WorkerCalledMiddlewareWorker.instance_variable_set(:@server_chain, nil) # un-memoize middleware
127
+
128
+ Shoryuken.configure_server do |config|
129
+ config.server_middleware do |chain|
130
+ chain.add WorkerCalledMiddleware
131
+ end
117
132
  end
118
133
  end
119
- end
120
134
 
121
- after do
122
- Shoryuken.configure_server do |config|
123
- config.server_middleware do |chain|
124
- chain.remove WorkerCalledMiddleware
135
+ after do
136
+ Shoryuken.configure_server do |config|
137
+ config.server_middleware do |chain|
138
+ chain.remove WorkerCalledMiddleware
139
+ end
125
140
  end
126
141
  end
142
+
143
+ it 'invokes middleware' do
144
+ expect(manager).to receive(:processor_done).with(queue, subject)
145
+
146
+ expect_any_instance_of(WorkerCalledMiddlewareWorker).to receive(:perform).with(sqs_msg, sqs_msg.body)
147
+ expect_any_instance_of(WorkerCalledMiddlewareWorker).to receive(:called).with(sqs_msg, queue)
148
+
149
+ subject.process(queue, sqs_msg)
150
+ end
127
151
  end
128
152
 
129
- it 'invokes middleware' do
130
- expect(manager).to receive(:processor_done).with(queue, subject)
153
+ context 'client' do
154
+ before do
155
+ allow(Shoryuken).to receive(:server?).and_return(false)
156
+ WorkerCalledMiddlewareWorker.instance_variable_set(:@server_chain, nil) # un-memoize middleware
131
157
 
132
- expect_any_instance_of(WorkerCalledMiddlewareWorker).to receive(:perform).with(sqs_msg, sqs_msg.body)
133
- expect_any_instance_of(WorkerCalledMiddlewareWorker).to receive(:called).with(sqs_msg, queue)
158
+ Shoryuken.configure_server do |config|
159
+ config.server_middleware do |chain|
160
+ chain.add WorkerCalledMiddleware
161
+ end
162
+ end
163
+ end
134
164
 
135
- subject.process(queue, sqs_msg)
165
+ after do
166
+ Shoryuken.configure_server do |config|
167
+ config.server_middleware do |chain|
168
+ chain.remove WorkerCalledMiddleware
169
+ end
170
+ end
171
+ end
172
+
173
+ it "doesn't invoke middleware" do
174
+ expect(manager).to receive(:processor_done).with(queue, subject)
175
+
176
+ expect_any_instance_of(WorkerCalledMiddlewareWorker).to receive(:perform).with(sqs_msg, sqs_msg.body)
177
+ expect_any_instance_of(WorkerCalledMiddlewareWorker).to_not receive(:called).with(sqs_msg, queue)
178
+
179
+ subject.process(queue, sqs_msg)
180
+ end
136
181
  end
137
182
  end
138
183
 
@@ -143,7 +188,7 @@ describe Shoryuken::Processor do
143
188
 
144
189
  expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, sqs_msg.body)
145
190
 
146
- expect(sqs_queue).to receive(:batch_delete).with(sqs_msg)
191
+ expect(sqs_queue).to receive(:delete_messages).with(entries: [{ id: '0', receipt_handle: sqs_msg.receipt_handle }])
147
192
 
148
193
  subject.process(queue, sqs_msg)
149
194
  end
@@ -155,18 +200,23 @@ describe Shoryuken::Processor do
155
200
 
156
201
  expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, sqs_msg.body)
157
202
 
158
- expect(sqs_queue).to_not receive(:batch_delete)
203
+ expect(sqs_queue).to_not receive(:delete_messages)
159
204
 
160
205
  subject.process(queue, sqs_msg)
161
206
  end
162
207
 
163
208
  context 'when shoryuken_class header' do
164
- let(:sqs_msg) { double AWS::SQS::ReceivedMessage, id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e', body: 'test', message_attributes: {
165
- 'shoryuken_class' => {
166
- string_value: TestWorker.to_s,
167
- data_type: 'String'
168
- }
169
- } }
209
+ let(:sqs_msg) do
210
+ double Aws::SQS::Message,
211
+ queue_url: queue,
212
+ body: 'test',
213
+ message_attributes: {
214
+ 'shoryuken_class' => {
215
+ string_value: TestWorker.to_s,
216
+ data_type: 'String' }},
217
+ message_id: SecureRandom.uuid,
218
+ receipt_handle: SecureRandom.uuid
219
+ end
170
220
 
171
221
  it 'performs without delete' do
172
222
  Shoryuken.worker_registry.clear # unregister TestWorker
@@ -175,7 +225,7 @@ describe Shoryuken::Processor do
175
225
 
176
226
  expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, sqs_msg.body)
177
227
 
178
- expect(sqs_queue).to_not receive(:batch_delete)
228
+ expect(sqs_queue).to_not receive(:delete_messages)
179
229
 
180
230
  subject.process(queue, sqs_msg)
181
231
  end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoryuken::SnsArn do
4
+ let(:account_id) { '1234567890' }
5
+ let(:region) { 'eu-west-1' }
6
+ let(:topic) { 'topic-x' }
7
+
8
+ before do
9
+ Shoryuken::Client.account_id = account_id
10
+ Aws.config = { region: region }
11
+ end
12
+
13
+ subject { described_class.new(topic).to_s }
14
+
15
+ describe '#to_s' do
16
+ context 'when the Aws config includes all the information necessary' do
17
+ it 'generates an SNS arn' do
18
+ expect(subject).to eq('arn:aws:sns:eu-west-1:1234567890:topic-x')
19
+ end
20
+ end
21
+
22
+ context 'when the Aws config does not include the account id' do
23
+ before do
24
+ Shoryuken::Client.account_id = nil
25
+ end
26
+
27
+ it 'fails' do
28
+ expect { subject }.to raise_error(/an :account_id/)
29
+ end
30
+ end
31
+
32
+ context 'when the Aws config does not include the region' do
33
+ before do
34
+ Aws.config.delete :region
35
+ end
36
+
37
+ it 'fails' do
38
+ expect { subject }.to raise_error(/a :region/)
39
+ end
40
+ end
41
+ end
42
+ end