message-driver 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +160 -0
- data/.travis.yml +5 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +9 -8
- data/Guardfile +14 -7
- data/README.md +2 -0
- data/Rakefile +16 -10
- data/examples/basic_producer_and_consumer/Gemfile +2 -2
- data/examples/basic_producer_and_consumer/common.rb +3 -3
- data/examples/basic_producer_and_consumer/consumer.rb +5 -5
- data/examples/basic_producer_and_consumer/producer.rb +7 -7
- data/features/CHANGELOG.md +5 -0
- data/features/message_consumers/transactional_ack_consumers.feature +1 -0
- data/features/rabbitmq_specific_features/publisher_acknowledgements.feature +51 -0
- data/features/step_definitions/error_handling_steps.rb +2 -2
- data/features/step_definitions/logging_steps.rb +4 -4
- data/features/step_definitions/message_consumers_steps.rb +8 -8
- data/features/step_definitions/rabbitmq_specific_steps.rb +10 -0
- data/features/step_definitions/steps.rb +15 -15
- data/features/support/env.rb +3 -0
- data/features/support/firewall_helper.rb +5 -6
- data/features/support/message_table_matcher.rb +3 -4
- data/features/support/no_error_matcher.rb +3 -3
- data/features/support/test_runner.rb +11 -3
- data/features/support/transforms.rb +1 -1
- data/lib/message-driver.rb +1 -1
- data/lib/message_driver.rb +0 -1
- data/lib/message_driver/adapters/base.rb +10 -10
- data/lib/message_driver/adapters/bunny_adapter.rb +57 -30
- data/lib/message_driver/adapters/in_memory_adapter.rb +4 -5
- data/lib/message_driver/adapters/stomp_adapter.rb +4 -6
- data/lib/message_driver/broker.rb +5 -4
- data/lib/message_driver/client.rb +6 -6
- data/lib/message_driver/destination.rb +2 -2
- data/lib/message_driver/errors.rb +1 -4
- data/lib/message_driver/logging.rb +1 -1
- data/lib/message_driver/message.rb +2 -2
- data/lib/message_driver/subscription.rb +1 -1
- data/lib/message_driver/version.rb +1 -1
- data/lib/{message_driver/vendor → vendor}/.document +0 -0
- data/lib/vendor/nesty.rb +1 -0
- data/lib/vendor/nesty/nested_error.rb +28 -0
- data/message-driver.gemspec +15 -14
- data/spec/integration/bunny/amqp_integration_spec.rb +43 -43
- data/spec/integration/bunny/bunny_adapter_spec.rb +117 -101
- data/spec/integration/in_memory/in_memory_adapter_spec.rb +35 -35
- data/spec/integration/stomp/stomp_adapter_spec.rb +42 -42
- data/spec/spec_helper.rb +4 -1
- data/spec/support/shared/adapter_examples.rb +7 -7
- data/spec/support/shared/client_ack_examples.rb +6 -6
- data/spec/support/shared/context_examples.rb +4 -4
- data/spec/support/shared/destination_examples.rb +10 -10
- data/spec/support/shared/subscription_examples.rb +29 -29
- data/spec/support/shared/transaction_examples.rb +10 -10
- data/spec/units/message_driver/adapters/base_spec.rb +19 -19
- data/spec/units/message_driver/broker_spec.rb +57 -58
- data/spec/units/message_driver/client_spec.rb +84 -84
- data/spec/units/message_driver/destination_spec.rb +4 -4
- data/spec/units/message_driver/message_spec.rb +19 -19
- data/spec/units/message_driver/subscription_spec.rb +4 -4
- data/test_lib/broker_config.rb +2 -2
- metadata +27 -6
- data/lib/message_driver/vendor/nesty.rb +0 -1
- data/lib/message_driver/vendor/nesty/nested_error.rb +0 -26
@@ -7,33 +7,33 @@ module MessageDriver::Adapters
|
|
7
7
|
|
8
8
|
let(:valid_connection_attrs) { BrokerConfig.config }
|
9
9
|
|
10
|
-
describe
|
11
|
-
context
|
12
|
-
let(:broker) { double(
|
13
|
-
shared_examples
|
14
|
-
it
|
15
|
-
stub_const(
|
10
|
+
describe '#initialize' do
|
11
|
+
context 'differing bunny versions' do
|
12
|
+
let(:broker) { double('broker') }
|
13
|
+
shared_examples 'raises an error' do
|
14
|
+
it 'raises an error' do
|
15
|
+
stub_const('Bunny::VERSION', version)
|
16
16
|
expect {
|
17
17
|
described_class.new(broker, valid_connection_attrs)
|
18
|
-
}.to raise_error MessageDriver::Error,
|
18
|
+
}.to raise_error MessageDriver::Error, 'bunny 1.2.2 or later is required for the bunny adapter'
|
19
19
|
end
|
20
20
|
end
|
21
21
|
shared_examples "doesn't raise an error" do
|
22
22
|
it "doesn't raise an an error" do
|
23
|
-
stub_const(
|
23
|
+
stub_const('Bunny::VERSION', version)
|
24
24
|
adapter = nil
|
25
25
|
expect {
|
26
26
|
adapter = described_class.new(broker, valid_connection_attrs)
|
27
27
|
}.to_not raise_error
|
28
28
|
end
|
29
29
|
end
|
30
|
-
%w(0.8.0
|
30
|
+
%w(0.8.0 0.9.0 0.9.8 0.10.7 1.0.3 1.1.2 1.2.1).each do |v|
|
31
31
|
context "bunny version #{v}" do
|
32
32
|
let(:version) { v }
|
33
|
-
include_examples
|
33
|
+
include_examples 'raises an error'
|
34
34
|
end
|
35
35
|
end
|
36
|
-
%w(1.1.3 1.
|
36
|
+
%w(1.2.2 1.3.2 1.4.0).each do |v|
|
37
37
|
context "bunny version #{v}" do
|
38
38
|
let(:version) { v }
|
39
39
|
include_examples "doesn't raise an error"
|
@@ -41,7 +41,7 @@ module MessageDriver::Adapters
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
it
|
44
|
+
it 'connects to the rabbit broker' do
|
45
45
|
broker = double(:broker)
|
46
46
|
adapter = described_class.new(broker, valid_connection_attrs)
|
47
47
|
|
@@ -49,7 +49,7 @@ module MessageDriver::Adapters
|
|
49
49
|
expect(adapter.connection).to be_open
|
50
50
|
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it 'connects to the rabbit broker lazily' do
|
53
53
|
broker = double(:broker)
|
54
54
|
adapter = described_class.new(broker, valid_connection_attrs)
|
55
55
|
|
@@ -57,7 +57,7 @@ module MessageDriver::Adapters
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
shared_context
|
60
|
+
shared_context 'a connected bunny adapter' do
|
61
61
|
let(:broker) { MessageDriver::Broker.configure(valid_connection_attrs) }
|
62
62
|
subject(:adapter) { broker.adapter }
|
63
63
|
let(:connection) { adapter.connection }
|
@@ -67,43 +67,47 @@ module MessageDriver::Adapters
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
shared_context
|
71
|
-
include_context
|
70
|
+
shared_context 'with a queue' do
|
71
|
+
include_context 'a connected bunny adapter'
|
72
72
|
|
73
73
|
let(:channel) { connection.create_channel }
|
74
|
-
let(:tmp_queue_name) {
|
74
|
+
let(:tmp_queue_name) { 'my_temp_queue' }
|
75
75
|
let(:tmp_queue) { channel.queue(tmp_queue_name, exclusive: true) }
|
76
76
|
end
|
77
77
|
|
78
|
-
it_behaves_like
|
79
|
-
include_context
|
78
|
+
it_behaves_like 'an adapter' do
|
79
|
+
include_context 'a connected bunny adapter'
|
80
80
|
end
|
81
81
|
|
82
|
-
describe
|
83
|
-
include_context
|
82
|
+
describe '#new_context' do
|
83
|
+
include_context 'a connected bunny adapter'
|
84
84
|
|
85
|
-
it
|
85
|
+
it 'returns a BunnyAdapter::BunnyContext' do
|
86
86
|
expect(subject.new_context).to be_a BunnyAdapter::BunnyContext
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
describe BunnyAdapter::BunnyContext do
|
91
|
-
include_context
|
91
|
+
include_context 'a connected bunny adapter'
|
92
92
|
subject(:adapter_context) { adapter.new_context }
|
93
|
+
around(:each) do |ex|
|
94
|
+
MessageDriver::Client.with_adapter_context(adapter_context) do
|
95
|
+
ex.run
|
96
|
+
end
|
97
|
+
end
|
93
98
|
|
94
|
-
it_behaves_like
|
95
|
-
it_behaves_like
|
96
|
-
it_behaves_like
|
97
|
-
it_behaves_like
|
99
|
+
it_behaves_like 'an adapter context'
|
100
|
+
it_behaves_like 'transactions are supported'
|
101
|
+
it_behaves_like 'client acks are supported'
|
102
|
+
it_behaves_like 'subscriptions are supported', BunnyAdapter::Subscription
|
98
103
|
|
99
|
-
describe
|
100
|
-
include_context
|
101
|
-
it
|
104
|
+
describe '#pop_message' do
|
105
|
+
include_context 'with a queue'
|
106
|
+
it 'needs some real tests'
|
102
107
|
end
|
103
108
|
|
104
|
-
|
105
|
-
|
106
|
-
it "closes the channel" do
|
109
|
+
describe '#invalidate' do
|
110
|
+
it 'closes the channel' do
|
107
111
|
subject.with_channel(false) do |ch|
|
108
112
|
expect(ch).to be_open
|
109
113
|
end
|
@@ -112,26 +116,36 @@ module MessageDriver::Adapters
|
|
112
116
|
end
|
113
117
|
end
|
114
118
|
|
115
|
-
describe
|
119
|
+
describe '#create_destination' do
|
116
120
|
|
117
|
-
context
|
118
|
-
context
|
119
|
-
let(:dest_name) {
|
121
|
+
context 'with defaults' do
|
122
|
+
context 'the resulting destination' do
|
123
|
+
let(:dest_name) { 'my_dest' }
|
120
124
|
subject(:result) { adapter_context.create_destination(dest_name, exclusive: true) }
|
121
125
|
|
122
126
|
it { should be_a BunnyAdapter::QueueDestination }
|
123
127
|
end
|
124
128
|
end
|
125
129
|
|
126
|
-
|
127
|
-
|
128
|
-
|
130
|
+
shared_examples 'supports publisher confirmations' do
|
131
|
+
let(:properties) { {persistent: false, confirm: true} }
|
132
|
+
it 'switches the channel to confirms mode' do
|
133
|
+
expect(adapter_context.channel.using_publisher_confirms?).to eq(true)
|
134
|
+
end
|
135
|
+
it 'waits until the confirm comes in' do
|
136
|
+
expect(adapter_context.channel.unconfirmed_set).to be_empty
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'the type is queue' do
|
141
|
+
context 'and there is no destination name given' do
|
142
|
+
subject(:destination) { adapter_context.create_destination('', type: :queue, exclusive: true) }
|
129
143
|
it { should be_a BunnyAdapter::QueueDestination }
|
130
144
|
its(:name) { should be_a String }
|
131
145
|
its(:name) { should_not be_empty }
|
132
146
|
end
|
133
|
-
context
|
134
|
-
let(:dest_name) {
|
147
|
+
context 'the resulting destination' do
|
148
|
+
let(:dest_name) { 'my_dest' }
|
135
149
|
subject(:destination) { adapter_context.create_destination(dest_name, type: :queue, exclusive: true) }
|
136
150
|
before do
|
137
151
|
destination
|
@@ -141,83 +155,84 @@ module MessageDriver::Adapters
|
|
141
155
|
its(:name) { should be_a String }
|
142
156
|
its(:name) { should eq(dest_name) }
|
143
157
|
|
144
|
-
include_examples
|
158
|
+
include_examples 'supports #message_count'
|
145
159
|
|
146
160
|
it "strips off the type so it isn't set on the destination" do
|
147
161
|
expect(subject.dest_options).to_not have_key :type
|
148
162
|
end
|
149
|
-
it
|
163
|
+
it 'ensures the queue is declared' do
|
150
164
|
expect {
|
151
165
|
connection.with_channel do |ch|
|
152
166
|
ch.queue(dest_name, passive: true)
|
153
167
|
end
|
154
168
|
}.to_not raise_error
|
155
169
|
end
|
156
|
-
context
|
157
|
-
let(:body) {
|
158
|
-
let(:headers) { {
|
170
|
+
context 'publishing a message' do
|
171
|
+
let(:body) { 'Testing the QueueDestination' }
|
172
|
+
let(:headers) { {'foo' => 'bar'} }
|
159
173
|
let(:properties) { {persistent: false} }
|
160
174
|
before do
|
161
175
|
subject.publish(body, headers, properties)
|
162
176
|
end
|
163
|
-
it
|
177
|
+
it 'publishes via the default exchange' do
|
164
178
|
msg = subject.pop_message
|
165
179
|
expect(msg.body).to eq(body)
|
166
180
|
expect(msg.headers).to eq(headers)
|
167
181
|
expect(msg.properties[:delivery_mode]).to eq(1)
|
168
|
-
expect(msg.delivery_info.exchange).to eq(
|
182
|
+
expect(msg.delivery_info.exchange).to eq('')
|
169
183
|
expect(msg.delivery_info.routing_key).to eq(subject.name)
|
170
184
|
end
|
185
|
+
include_examples 'supports publisher confirmations'
|
171
186
|
end
|
172
|
-
it_behaves_like
|
187
|
+
it_behaves_like 'a destination'
|
173
188
|
end
|
174
|
-
context
|
175
|
-
let(:dest_name) {
|
176
|
-
let(:exchange) { adapter_context.create_destination(
|
189
|
+
context 'and bindings are provided' do
|
190
|
+
let(:dest_name) { 'binding_test_queue' }
|
191
|
+
let(:exchange) { adapter_context.create_destination('amq.direct', type: :exchange) }
|
177
192
|
|
178
193
|
it "raises an exception if you don't provide a source" do
|
179
194
|
expect {
|
180
|
-
adapter_context.create_destination(
|
195
|
+
adapter_context.create_destination('bad_bind_queue', type: :queue, exclusive: true, bindings: [{args: {routing_key: 'test_exchange_bind'}}])
|
181
196
|
}.to raise_error MessageDriver::Error, /must provide a source/
|
182
197
|
end
|
183
198
|
|
184
|
-
it
|
185
|
-
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source:
|
186
|
-
exchange.publish(
|
199
|
+
it 'routes message to the queue through the exchange' do
|
200
|
+
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source: 'amq.direct', args: {routing_key: 'test_queue_bind'}}])
|
201
|
+
exchange.publish('test queue bindings', {}, routing_key: 'test_queue_bind')
|
187
202
|
message = destination.pop_message
|
188
203
|
expect(message).to_not be_nil
|
189
|
-
expect(message.body).to eq(
|
204
|
+
expect(message.body).to eq('test queue bindings')
|
190
205
|
end
|
191
206
|
end
|
192
207
|
|
193
|
-
context
|
208
|
+
context 'we are not yet connected to the broker and :no_declare is provided' do
|
194
209
|
it "doesn't cause a connection to the broker" do
|
195
210
|
connection.stop
|
196
|
-
adapter_context.create_destination(
|
211
|
+
adapter_context.create_destination('test_queue', no_declare: true, type: :queue, exclusive: true)
|
197
212
|
expect(adapter.connection(false)).to_not be_open
|
198
213
|
end
|
199
214
|
|
200
|
-
context
|
201
|
-
it
|
215
|
+
context 'with a server-named queue' do
|
216
|
+
it 'raises an error' do
|
202
217
|
expect {
|
203
|
-
adapter_context.create_destination(
|
204
|
-
}.to raise_error MessageDriver::Error,
|
218
|
+
adapter_context.create_destination('', no_declare: true, type: :queue, exclusive: true)
|
219
|
+
}.to raise_error MessageDriver::Error, 'server-named queues must be declared, but you provided :no_declare => true'
|
205
220
|
end
|
206
221
|
end
|
207
222
|
|
208
|
-
context
|
209
|
-
it
|
223
|
+
context 'with bindings' do
|
224
|
+
it 'raises an error' do
|
210
225
|
expect {
|
211
|
-
adapter_context.create_destination(
|
212
|
-
}.to raise_error MessageDriver::Error,
|
226
|
+
adapter_context.create_destination('tmp_queue', no_declare: true, bindings: [{source: 'amq.fanout'}], type: :queue, exclusive: true)
|
227
|
+
}.to raise_error MessageDriver::Error, 'queues with bindings must be declared, but you provided :no_declare => true'
|
213
228
|
end
|
214
229
|
end
|
215
230
|
end
|
216
231
|
end
|
217
232
|
|
218
|
-
context
|
219
|
-
context
|
220
|
-
let(:dest_name) {
|
233
|
+
context 'the type is exchange' do
|
234
|
+
context 'the resulting destination' do
|
235
|
+
let(:dest_name) { 'my_dest' }
|
221
236
|
subject(:destination) { adapter_context.create_destination(dest_name, type: :exchange) }
|
222
237
|
|
223
238
|
it { should be_a BunnyAdapter::ExchangeDestination }
|
@@ -227,21 +242,21 @@ module MessageDriver::Adapters
|
|
227
242
|
expect(subject.dest_options).to_not have_key :type
|
228
243
|
end
|
229
244
|
|
230
|
-
it
|
245
|
+
it 'raises an error when pop_message is called' do
|
231
246
|
expect {
|
232
247
|
subject.pop_message(dest_name)
|
233
248
|
}.to raise_error MessageDriver::Error, "You can't pop a message off an exchange"
|
234
249
|
end
|
235
250
|
|
236
|
-
context
|
237
|
-
let(:body) {
|
238
|
-
let(:headers) { {
|
251
|
+
context 'publishing a message' do
|
252
|
+
let(:body) { 'Testing the ExchangeDestination' }
|
253
|
+
let(:headers) { {'foo' => 'bar'} }
|
239
254
|
let(:properties) { {persistent: false} }
|
240
255
|
before { connection.with_channel { |ch| ch.fanout(dest_name, auto_delete: true) } }
|
241
256
|
let!(:queue) do
|
242
257
|
q = nil
|
243
258
|
connection.with_channel do |ch|
|
244
|
-
q = ch.queue(
|
259
|
+
q = ch.queue('', exclusive: true)
|
245
260
|
q.bind(dest_name)
|
246
261
|
end
|
247
262
|
q
|
@@ -250,7 +265,7 @@ module MessageDriver::Adapters
|
|
250
265
|
subject.publish(body, headers, properties)
|
251
266
|
end
|
252
267
|
|
253
|
-
it
|
268
|
+
it 'publishes to the specified exchange' do
|
254
269
|
connection.with_channel do |ch|
|
255
270
|
q = ch.queue(queue.name, passive: true)
|
256
271
|
msg = q.pop
|
@@ -260,19 +275,20 @@ module MessageDriver::Adapters
|
|
260
275
|
expect(msg[1][:delivery_mode]).to eq(1)
|
261
276
|
end
|
262
277
|
end
|
278
|
+
include_examples 'supports publisher confirmations'
|
263
279
|
end
|
264
280
|
end
|
265
281
|
|
266
|
-
context
|
267
|
-
let(:dest_name) {
|
282
|
+
context 'declaring an exchange on the broker' do
|
283
|
+
let(:dest_name) { 'my.cool.exchange' }
|
268
284
|
|
269
285
|
it "creates the exchange if you include 'declare' in the options" do
|
270
286
|
exchange = adapter_context.create_destination(dest_name, type: :exchange, declare: {type: :fanout, auto_delete: true})
|
271
|
-
queue = adapter_context.create_destination(
|
272
|
-
exchange.publish(
|
287
|
+
queue = adapter_context.create_destination('', type: :queue, exclusive: true, bindings: [{source: dest_name}])
|
288
|
+
exchange.publish('test declaring exchange')
|
273
289
|
message = queue.pop_message
|
274
290
|
expect(message).to_not be_nil
|
275
|
-
expect(message.body).to eq(
|
291
|
+
expect(message.body).to eq('test declaring exchange')
|
276
292
|
end
|
277
293
|
|
278
294
|
it "raises an error if you don't provide a type" do
|
@@ -283,51 +299,51 @@ module MessageDriver::Adapters
|
|
283
299
|
|
284
300
|
end
|
285
301
|
|
286
|
-
context
|
287
|
-
let(:dest_name) {
|
288
|
-
let(:exchange) { adapter_context.create_destination(
|
302
|
+
context 'and bindings are provided' do
|
303
|
+
let(:dest_name) { 'binding_exchange_queue' }
|
304
|
+
let(:exchange) { adapter_context.create_destination('amq.direct', type: :exchange) }
|
289
305
|
|
290
306
|
it "raises an exception if you don't provide a source" do
|
291
307
|
expect {
|
292
|
-
adapter_context.create_destination(
|
308
|
+
adapter_context.create_destination('amq.fanout', type: :exchange, bindings: [{args: {routing_key: 'test_exchange_bind'}}])
|
293
309
|
}.to raise_error MessageDriver::Error, /must provide a source/
|
294
310
|
end
|
295
311
|
|
296
|
-
it
|
297
|
-
adapter_context.create_destination(
|
298
|
-
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source:
|
299
|
-
exchange.publish(
|
312
|
+
it 'routes message to the queue through the exchange' do
|
313
|
+
adapter_context.create_destination('amq.fanout', type: :exchange, bindings: [{source: 'amq.direct', args: {routing_key: 'test_exchange_bind'}}])
|
314
|
+
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source: 'amq.fanout'}])
|
315
|
+
exchange.publish('test exchange bindings', {}, routing_key: 'test_exchange_bind')
|
300
316
|
message = destination.pop_message
|
301
317
|
expect(message).to_not be_nil
|
302
|
-
expect(message.body).to eq(
|
318
|
+
expect(message.body).to eq('test exchange bindings')
|
303
319
|
end
|
304
320
|
end
|
305
321
|
|
306
|
-
context
|
322
|
+
context 'we are not yet connected to the broker' do
|
307
323
|
it "doesn't cause a connection to the broker" do
|
308
324
|
connection.stop
|
309
|
-
adapter_context.create_destination(
|
325
|
+
adapter_context.create_destination('amq.fanout', type: :exchange)
|
310
326
|
expect(adapter.connection(false)).to_not be_open
|
311
327
|
end
|
312
328
|
end
|
313
329
|
end
|
314
330
|
|
315
|
-
context
|
316
|
-
it
|
331
|
+
context 'the type is invalid' do
|
332
|
+
it 'raises in an error' do
|
317
333
|
expect {
|
318
|
-
adapter_context.create_destination(
|
334
|
+
adapter_context.create_destination('my_dest', type: :foo_bar)
|
319
335
|
}.to raise_error MessageDriver::Error, "invalid destination type #{:foo_bar}"
|
320
336
|
end
|
321
337
|
end
|
322
338
|
end
|
323
339
|
|
324
|
-
describe
|
325
|
-
context
|
326
|
-
let(:dest_name) {
|
340
|
+
describe '#subscribe' do
|
341
|
+
context 'the destination is an ExchangeDestination' do
|
342
|
+
let(:dest_name) { 'my_dest' }
|
327
343
|
let(:destination) { adapter_context.create_destination(dest_name, type: :exchange) }
|
328
|
-
let(:consumer) { lambda do |
|
344
|
+
let(:consumer) { lambda do |_|; end }
|
329
345
|
|
330
|
-
it
|
346
|
+
it 'raises an error' do
|
331
347
|
expect {
|
332
348
|
adapter_context.subscribe(destination, &consumer)
|
333
349
|
}.to raise_error MessageDriver::Error, /QueueDestination/
|
@@ -4,39 +4,39 @@ require 'message_driver/adapters/in_memory_adapter'
|
|
4
4
|
|
5
5
|
module MessageDriver::Adapters
|
6
6
|
describe InMemoryAdapter, :in_memory, type: :integration do
|
7
|
-
let(:broker) { double(
|
7
|
+
let(:broker) { double('broker') }
|
8
8
|
subject(:adapter) { described_class.new(broker) }
|
9
9
|
|
10
|
-
describe
|
11
|
-
it
|
10
|
+
describe '#new_context' do
|
11
|
+
it 'returns a InMemoryAdapter::InMemoryContext' do
|
12
12
|
expect(subject.new_context).to be_a InMemoryAdapter::InMemoryContext
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
it_behaves_like
|
16
|
+
it_behaves_like 'an adapter'
|
17
17
|
|
18
18
|
describe InMemoryAdapter::InMemoryContext do
|
19
19
|
subject(:adapter_context) { adapter.new_context }
|
20
20
|
|
21
|
-
it_behaves_like
|
22
|
-
it_behaves_like
|
23
|
-
it_behaves_like
|
24
|
-
it_behaves_like
|
21
|
+
it_behaves_like 'an adapter context'
|
22
|
+
it_behaves_like 'transactions are not supported'
|
23
|
+
it_behaves_like 'client acks are not supported'
|
24
|
+
it_behaves_like 'subscriptions are supported', InMemoryAdapter::Subscription
|
25
25
|
end
|
26
26
|
|
27
|
-
describe
|
28
|
-
describe
|
29
|
-
subject(:destination) { adapter.create_destination(
|
27
|
+
describe '#create_destination' do
|
28
|
+
describe 'the resulting destination' do
|
29
|
+
subject(:destination) { adapter.create_destination('my_test_dest') }
|
30
30
|
|
31
31
|
it { should be_a InMemoryAdapter::Destination }
|
32
32
|
|
33
|
-
it_behaves_like
|
34
|
-
include_examples
|
33
|
+
it_behaves_like 'a destination'
|
34
|
+
include_examples 'supports #message_count'
|
35
35
|
end
|
36
36
|
|
37
|
-
context
|
38
|
-
it
|
39
|
-
queue_name =
|
37
|
+
context 'when creating two destinations for the same queue' do
|
38
|
+
it 'creates seperate destination instances' do
|
39
|
+
queue_name = 'my_queue'
|
40
40
|
dest1 = adapter.create_destination(queue_name)
|
41
41
|
dest2 = adapter.create_destination(queue_name)
|
42
42
|
expect(dest1).to_not be(dest2)
|
@@ -44,8 +44,8 @@ module MessageDriver::Adapters
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
describe
|
48
|
-
it
|
47
|
+
describe '#reset_after_tests' do
|
48
|
+
it 'empties all the destination queues' do
|
49
49
|
destinations = (1..3).map(&adapter.method(:create_destination))
|
50
50
|
destinations.each do |destination|
|
51
51
|
destination.publish("There's always money in the banana stand!", {}, {})
|
@@ -58,9 +58,9 @@ module MessageDriver::Adapters
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
it
|
61
|
+
it 'removes any existing subscriptions' do
|
62
62
|
destinations = (1..3).map(&adapter.method(:create_destination))
|
63
|
-
consumer = lambda do |
|
63
|
+
consumer = lambda do |_| end
|
64
64
|
destinations.each do |destination|
|
65
65
|
destination.subscribe(&consumer)
|
66
66
|
end
|
@@ -74,43 +74,43 @@ module MessageDriver::Adapters
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe
|
78
|
-
let(:queue_name) {
|
77
|
+
describe 'accessing the same queue from two destinations' do
|
78
|
+
let(:queue_name) { 'my_queue' }
|
79
79
|
let(:dest1) { adapter.create_destination(queue_name) }
|
80
80
|
let(:dest2) { adapter.create_destination(queue_name) }
|
81
81
|
|
82
|
-
context
|
83
|
-
let(:consumer) { lambda do |
|
82
|
+
context 'when I have a consumer on one destination' do
|
83
|
+
let(:consumer) { lambda do |_| end }
|
84
84
|
before do
|
85
85
|
dest1.subscribe(&consumer)
|
86
86
|
end
|
87
|
-
it
|
87
|
+
it 'is the same consumer on the other destination' do
|
88
88
|
expect(dest2.subscription.consumer).to be(consumer)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
context
|
93
|
-
it
|
92
|
+
context 'when I publish a message to one destination' do
|
93
|
+
it 'changes the message_count on the other' do
|
94
94
|
expect {
|
95
|
-
dest1.publish(
|
95
|
+
dest1.publish('my test message')
|
96
96
|
}.to change{dest2.message_count}.from(0).to(1)
|
97
97
|
end
|
98
98
|
|
99
|
-
it
|
100
|
-
dest1.publish(
|
99
|
+
it 'can be popped off the other' do
|
100
|
+
dest1.publish('my test message')
|
101
101
|
msg = dest2.pop_message
|
102
102
|
expect(msg).to_not be_nil
|
103
|
-
expect(msg.body).to eq(
|
103
|
+
expect(msg.body).to eq('my test message')
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
context
|
108
|
-
let(:message_body) {
|
107
|
+
context 'when I pop a message off one destination' do
|
108
|
+
let(:message_body) { 'test popping a message' }
|
109
109
|
before do
|
110
110
|
dest2.publish(message_body)
|
111
111
|
end
|
112
112
|
|
113
|
-
it
|
113
|
+
it 'changes the message_count on the other' do
|
114
114
|
expect {
|
115
115
|
dest1.pop_message
|
116
116
|
}.to change{dest2.message_count}.from(1).to(0)
|
@@ -118,7 +118,7 @@ module MessageDriver::Adapters
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
-
describe
|
121
|
+
describe 'subscribing a consumer' do
|
122
122
|
let(:destination) { adapter.create_destination(:my_queue) }
|
123
123
|
|
124
124
|
let(:subscription_type) { MessageDriver::Adapters::InMemoryAdapter::Subscription }
|