message-driver 0.1.0 → 0.2.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +18 -7
- data/CHANGELOG.md +12 -2
- data/Gemfile +17 -0
- data/Guardfile +8 -4
- data/README.md +14 -5
- data/Rakefile +44 -11
- data/examples/basic_producer_and_consumer/Gemfile +5 -0
- data/examples/basic_producer_and_consumer/common.rb +17 -0
- data/examples/basic_producer_and_consumer/consumer.rb +24 -0
- data/examples/basic_producer_and_consumer/producer.rb +33 -0
- data/features/.nav +8 -0
- data/features/CHANGELOG.md +12 -2
- data/features/amqp_specific_features/binding_amqp_destinations.feature +7 -7
- data/features/amqp_specific_features/declaring_amqp_exchanges.feature +3 -3
- data/features/amqp_specific_features/nack_redelivered_messages.feature +92 -0
- data/features/amqp_specific_features/requeueing_on_nack.feature +44 -0
- data/features/amqp_specific_features/server_named_destinations.feature +5 -5
- data/features/client_acks.feature +92 -0
- data/features/destination_metadata.feature +9 -11
- data/features/dynamic_destinations.feature +7 -7
- data/features/error_handling.feature +11 -9
- data/features/logging.feature +14 -0
- data/features/message_consumers/auto_ack_consumers.feature +79 -0
- data/features/message_consumers/manual_ack_consumers.feature +95 -0
- data/features/message_consumers/transactional_ack_consumers.feature +77 -0
- data/features/message_consumers.feature +54 -0
- data/features/publishing_a_message.feature +6 -10
- data/features/publishing_with_transactions.feature +10 -14
- data/features/rabbitmq_specific_features/dead_letter_queueing.feature +116 -0
- data/features/step_definitions/dynamic_destinations_steps.rb +3 -3
- data/features/step_definitions/error_handling_steps.rb +4 -2
- data/features/step_definitions/logging_steps.rb +28 -0
- data/features/step_definitions/message_consumers_steps.rb +29 -0
- data/features/step_definitions/steps.rb +60 -9
- data/features/support/broker_config_helper.rb +19 -0
- data/features/support/env.rb +1 -0
- data/features/support/firewall_helper.rb +8 -11
- data/features/support/message_table_matcher.rb +21 -5
- data/features/support/test_runner.rb +39 -16
- data/lib/message_driver/adapters/base.rb +51 -4
- data/lib/message_driver/adapters/bunny_adapter.rb +251 -127
- data/lib/message_driver/adapters/in_memory_adapter.rb +97 -18
- data/lib/message_driver/adapters/stomp_adapter.rb +127 -0
- data/lib/message_driver/broker.rb +23 -24
- data/lib/message_driver/client.rb +157 -0
- data/lib/message_driver/destination.rb +7 -4
- data/lib/message_driver/errors.rb +27 -0
- data/lib/message_driver/logging.rb +11 -0
- data/lib/message_driver/message.rb +8 -0
- data/lib/message_driver/subscription.rb +18 -0
- data/lib/message_driver/vendor/.document +0 -0
- data/lib/message_driver/vendor/nesty/nested_error.rb +26 -0
- data/lib/message_driver/vendor/nesty.rb +1 -0
- data/lib/message_driver/version.rb +1 -1
- data/lib/message_driver.rb +4 -2
- data/message-driver.gemspec +4 -4
- data/spec/integration/{amqp_integration_spec.rb → bunny/amqp_integration_spec.rb} +29 -28
- data/spec/integration/bunny/bunny_adapter_spec.rb +339 -0
- data/spec/integration/in_memory/in_memory_adapter_spec.rb +126 -0
- data/spec/integration/stomp/stomp_adapter_spec.rb +142 -0
- data/spec/spec_helper.rb +5 -2
- data/spec/support/shared/adapter_examples.rb +17 -0
- data/spec/support/shared/client_ack_examples.rb +18 -0
- data/spec/support/shared/context_examples.rb +14 -0
- data/spec/support/shared/destination_examples.rb +4 -5
- data/spec/support/shared/subscription_examples.rb +146 -0
- data/spec/support/shared/transaction_examples.rb +43 -0
- data/spec/support/utils.rb +14 -0
- data/spec/units/message_driver/adapters/base_spec.rb +38 -19
- data/spec/units/message_driver/broker_spec.rb +71 -18
- data/spec/units/message_driver/client_spec.rb +375 -0
- data/spec/units/message_driver/destination_spec.rb +9 -0
- data/spec/units/message_driver/logging_spec.rb +18 -0
- data/spec/units/message_driver/message_spec.rb +36 -0
- data/spec/units/message_driver/subscription_spec.rb +24 -0
- data/test_lib/broker_config.rb +50 -20
- metadata +83 -45
- data/.rbenv-version +0 -1
- data/lib/message_driver/exceptions.rb +0 -18
- data/lib/message_driver/message_publisher.rb +0 -15
- data/spec/integration/message_driver/adapters/bunny_adapter_spec.rb +0 -301
- data/spec/units/message_driver/adapters/in_memory_adapter_spec.rb +0 -43
- data/spec/units/message_driver/message_publisher_spec.rb +0 -65
@@ -0,0 +1,375 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'message_driver/adapters/in_memory_adapter'
|
4
|
+
|
5
|
+
module MessageDriver
|
6
|
+
describe Client do
|
7
|
+
class TestPublisher
|
8
|
+
include Client
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:adapter) { Adapters::InMemoryAdapter.new({}) }
|
12
|
+
let(:adapter_context) { adapter.new_context }
|
13
|
+
let(:logger) { double(Logger).as_null_object }
|
14
|
+
|
15
|
+
before do
|
16
|
+
MessageDriver.configure(adapter: adapter, logger: logger)
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples "a Client" do
|
20
|
+
describe "#current_adapter_context" do
|
21
|
+
before { subject.clear_context }
|
22
|
+
|
23
|
+
it "returns an adapter_context" do
|
24
|
+
expect(subject.current_adapter_context).to be_a Adapters::ContextBase
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the same adapter context on the second call" do
|
28
|
+
ctx = subject.current_adapter_context
|
29
|
+
expect(subject.current_adapter_context).to be ctx
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when called with false" do
|
33
|
+
it "doesn't initialize the adapter context if there isn't one" do
|
34
|
+
expect(subject.current_adapter_context(false)).to be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with a given adapter_context" do
|
40
|
+
around do |example|
|
41
|
+
subject.with_adapter_context(adapter_context, &example)
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#dynamic_destination" do
|
45
|
+
let(:dest_name) { "my_new_queue" }
|
46
|
+
let(:dest_options) { {type: 2} }
|
47
|
+
let(:message_props) { {expires: "soon"} }
|
48
|
+
let(:created_dest) { double("created destination") }
|
49
|
+
before do
|
50
|
+
adapter_context.stub(:create_destination) { created_dest }
|
51
|
+
end
|
52
|
+
|
53
|
+
it "delegates to the adapter_context" do
|
54
|
+
result = subject.dynamic_destination(dest_name, dest_options, message_props)
|
55
|
+
expect(result).to be(created_dest)
|
56
|
+
|
57
|
+
adapter_context.should have_received(:create_destination).with(dest_name, dest_options, message_props)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "only requires destination name" do
|
61
|
+
result = subject.dynamic_destination(dest_name)
|
62
|
+
expect(result).to be(created_dest)
|
63
|
+
|
64
|
+
adapter_context.should have_received(:create_destination).with(dest_name, {}, {})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#publish" do
|
69
|
+
let(:destination) { Broker.destination(:my_queue, "my_queue", exclusive: true) }
|
70
|
+
let(:body) { "my message" }
|
71
|
+
let(:headers) { {foo: :bar} }
|
72
|
+
let(:properties) { {bar: :baz} }
|
73
|
+
before do
|
74
|
+
adapter_context.stub(:publish)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "delegates to the adapter_context" do
|
78
|
+
subject.publish(destination, body, headers, properties)
|
79
|
+
adapter_context.should have_received(:publish).with(destination, body, headers, properties)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "only requires destination and body" do
|
83
|
+
subject.publish(destination, body)
|
84
|
+
adapter_context.should have_received(:publish).with(destination, body, {}, {})
|
85
|
+
end
|
86
|
+
|
87
|
+
it "looks up the destination if necessary" do
|
88
|
+
destination
|
89
|
+
subject.publish(:my_queue, body, headers, properties)
|
90
|
+
adapter_context.should have_received(:publish).with(destination, body, headers, properties)
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when the destination can't be found" do
|
94
|
+
let(:bad_dest_name) { :not_a_queue }
|
95
|
+
it "raises a MessageDriver:NoSuchDestinationError" do
|
96
|
+
expect {
|
97
|
+
subject.publish(bad_dest_name, body, headers, properties)
|
98
|
+
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
99
|
+
adapter_context.should_not have_received(:publish)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#pop_message" do
|
105
|
+
let(:expected) { double(MessageDriver::Message) }
|
106
|
+
let(:destination) { Broker.destination(:my_queue, "my_queue", exclusive: true) }
|
107
|
+
let(:options) { {foo: :bar} }
|
108
|
+
before do
|
109
|
+
adapter_context.stub(:pop_message)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "delegates to the adapter_context" do
|
113
|
+
subject.pop_message(destination, options)
|
114
|
+
adapter_context.should have_received(:pop_message).with(destination, options)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "looks up the destination if necessary" do
|
118
|
+
destination
|
119
|
+
subject.pop_message(:my_queue, options)
|
120
|
+
adapter_context.should have_received(:pop_message).with(destination, options)
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when the destination can't be found" do
|
124
|
+
let(:bad_dest_name) { :not_a_queue }
|
125
|
+
it "raises a MessageDriver:NoSuchDestinationError" do
|
126
|
+
expect {
|
127
|
+
subject.pop_message(bad_dest_name, options)
|
128
|
+
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
129
|
+
adapter_context.should_not have_received(:pop_message)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "requires the destination and returns the message" do
|
134
|
+
adapter_context.should_receive(:pop_message).with(destination, {}).and_return(expected)
|
135
|
+
|
136
|
+
actual = subject.pop_message(destination)
|
137
|
+
|
138
|
+
expect(actual).to be expected
|
139
|
+
end
|
140
|
+
|
141
|
+
it "passes the options through and returns the message" do
|
142
|
+
adapter_context.should_receive(:pop_message).with(destination, options).and_return(expected)
|
143
|
+
|
144
|
+
actual = subject.pop_message(destination, options)
|
145
|
+
|
146
|
+
expect(actual).to be expected
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#with_message_transaction" do
|
151
|
+
before do
|
152
|
+
adapter_context.stub(:begin_transaction)
|
153
|
+
adapter_context.stub(:commit_transaction)
|
154
|
+
adapter_context.stub(:rollback_transaction)
|
155
|
+
end
|
156
|
+
|
157
|
+
context "when the adapter supports transactions" do
|
158
|
+
before do
|
159
|
+
adapter_context.stub(:supports_transactions?) { true }
|
160
|
+
end
|
161
|
+
it "delegates to the adapter context" do
|
162
|
+
expect { |blk|
|
163
|
+
subject.with_message_transaction(&blk)
|
164
|
+
}.to yield_control
|
165
|
+
adapter_context.should have_received(:begin_transaction)
|
166
|
+
adapter_context.should have_received(:commit_transaction)
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when the block raises an error" do
|
170
|
+
it "calls rollback instead of commit and raises the error" do
|
171
|
+
expect {
|
172
|
+
subject.with_message_transaction do
|
173
|
+
raise "having a tough time"
|
174
|
+
end
|
175
|
+
}.to raise_error "having a tough time"
|
176
|
+
adapter_context.should have_received(:begin_transaction)
|
177
|
+
adapter_context.should_not have_received(:commit_transaction)
|
178
|
+
adapter_context.should have_received(:rollback_transaction)
|
179
|
+
end
|
180
|
+
|
181
|
+
context "and the the rollback raises an error" do
|
182
|
+
it "logs the error from the rollback and raises the original error" do
|
183
|
+
adapter_context.stub(:rollback_transaction).and_raise("rollback failed!")
|
184
|
+
expect {
|
185
|
+
subject.with_message_transaction do
|
186
|
+
raise "having a tough time"
|
187
|
+
end
|
188
|
+
}.to raise_error "having a tough time"
|
189
|
+
expect(logger).to have_received(:error).with(match("rollback failed!"))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "when the transactions are nested" do
|
195
|
+
it "only starts and commits once" do
|
196
|
+
expect { |blk|
|
197
|
+
subject.with_message_transaction do
|
198
|
+
subject.with_message_transaction(&blk)
|
199
|
+
end
|
200
|
+
}.to yield_control
|
201
|
+
adapter_context.should have_received(:begin_transaction).once
|
202
|
+
adapter_context.should have_received(:commit_transaction).once
|
203
|
+
end
|
204
|
+
|
205
|
+
context "when the block raises an error" do
|
206
|
+
it "calls rollback instead of commit and raises the error" do
|
207
|
+
expect {
|
208
|
+
subject.with_message_transaction do
|
209
|
+
subject.with_message_transaction do
|
210
|
+
raise "having a tough time"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
}.to raise_error "having a tough time"
|
214
|
+
adapter_context.should have_received(:begin_transaction).once
|
215
|
+
adapter_context.should_not have_received(:commit_transaction)
|
216
|
+
adapter_context.should have_received(:rollback_transaction).once
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "when the adapter doesn't support transactions" do
|
223
|
+
before do
|
224
|
+
adapter_context.stub(:supports_transactions?) { false }
|
225
|
+
end
|
226
|
+
it "run the block on it's own" do
|
227
|
+
expect { |blk|
|
228
|
+
subject.with_message_transaction(&blk)
|
229
|
+
}.to yield_control
|
230
|
+
adapter_context.should_not have_received(:begin_transaction)
|
231
|
+
adapter_context.should_not have_received(:commit_transaction)
|
232
|
+
adapter_context.should_not have_received(:rollback_transaction)
|
233
|
+
end
|
234
|
+
it "logs a warning" do
|
235
|
+
expect { |blk|
|
236
|
+
subject.with_message_transaction(&blk)
|
237
|
+
}.to yield_control
|
238
|
+
expect(logger).to have_received(:debug).with("this adapter does not support transactions")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "#ack_message" do
|
244
|
+
let(:message) { double("message") }
|
245
|
+
let(:options) { {foo: :bar} }
|
246
|
+
before do
|
247
|
+
adapter_context.stub(:ack_message)
|
248
|
+
end
|
249
|
+
context "when the adapter supports client acks" do
|
250
|
+
before do
|
251
|
+
adapter_context.stub(:supports_client_acks?) { true }
|
252
|
+
end
|
253
|
+
it "calls #ack_message with the message" do
|
254
|
+
subject.ack_message(message)
|
255
|
+
adapter_context.should have_received(:ack_message).with(message, {})
|
256
|
+
end
|
257
|
+
it "passes the supplied options to ack_message" do
|
258
|
+
subject.ack_message(message, options)
|
259
|
+
adapter_context.should have_received(:ack_message).with(message, options)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
context "when the adapter doesn't support client acks" do
|
263
|
+
before do
|
264
|
+
adapter_context.stub(:supports_client_acks?) { false }
|
265
|
+
end
|
266
|
+
it "doesn't call #ack_message" do
|
267
|
+
subject.ack_message(message)
|
268
|
+
adapter_context.should_not have_received(:ack_message)
|
269
|
+
end
|
270
|
+
it "logs a warning" do
|
271
|
+
subject.ack_message(message)
|
272
|
+
expect(logger).to have_received(:debug).with("this adapter does not support client acks")
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe "#nack_message" do
|
278
|
+
let(:message) { double("message") }
|
279
|
+
let(:options) { {foo: :bar} }
|
280
|
+
before do
|
281
|
+
adapter_context.stub(:nack_message)
|
282
|
+
end
|
283
|
+
context "when the adapter supports client acks" do
|
284
|
+
before do
|
285
|
+
adapter_context.stub(:supports_client_acks?) { true }
|
286
|
+
end
|
287
|
+
it "calls #nack_message with the message" do
|
288
|
+
subject.nack_message(message)
|
289
|
+
adapter_context.should have_received(:nack_message).with(message, {})
|
290
|
+
end
|
291
|
+
it "passes the supplied options to nack_message" do
|
292
|
+
subject.nack_message(message, options)
|
293
|
+
adapter_context.should have_received(:nack_message).with(message, options)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
context "when the adapter doesn't support client acks" do
|
297
|
+
before do
|
298
|
+
adapter_context.stub(:supports_client_acks?) { false }
|
299
|
+
end
|
300
|
+
it "doesn't call #nack_message" do
|
301
|
+
subject.nack_message(message)
|
302
|
+
adapter_context.should_not have_received(:nack_message)
|
303
|
+
end
|
304
|
+
it "logs a warning" do
|
305
|
+
subject.nack_message(message)
|
306
|
+
expect(logger).to have_received(:debug).with("this adapter does not support client acks")
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
describe "#subscribe" do
|
312
|
+
let(:destination) { Broker.destination(:my_queue, "my_queue", exclusive: true) }
|
313
|
+
let(:consumer_double) { lambda do |m| end }
|
314
|
+
|
315
|
+
before do
|
316
|
+
adapter_context.stub(:subscribe)
|
317
|
+
Broker.consumer(:my_consumer, &consumer_double)
|
318
|
+
end
|
319
|
+
|
320
|
+
it "delegates to the adapter_context" do
|
321
|
+
adapter_context.should_receive(:subscribe).with(destination, {}) do |&blk|
|
322
|
+
expect(blk).to be(consumer_double)
|
323
|
+
end
|
324
|
+
subject.subscribe(destination, :my_consumer)
|
325
|
+
end
|
326
|
+
|
327
|
+
it "passes the options through" do
|
328
|
+
options = {foo: :bar}
|
329
|
+
adapter_context.should_receive(:subscribe).with(destination, options) do |&blk|
|
330
|
+
expect(blk).to be(consumer_double)
|
331
|
+
end
|
332
|
+
subject.subscribe(destination, :my_consumer, options)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "looks up the destination" do
|
336
|
+
adapter_context.should_receive(:subscribe).with(destination, {}) do |&blk|
|
337
|
+
expect(blk).to be(consumer_double)
|
338
|
+
end
|
339
|
+
subject.subscribe(:my_queue, :my_consumer)
|
340
|
+
end
|
341
|
+
|
342
|
+
context "when the destination can't be found" do
|
343
|
+
let(:bad_dest_name) { :not_a_queue }
|
344
|
+
it "raises a MessageDriver:NoSuchDestinationError" do
|
345
|
+
expect {
|
346
|
+
subject.subscribe(bad_dest_name, :my_consumer)
|
347
|
+
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
348
|
+
adapter_context.should_not have_received(:subscribe)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context "when the consumer can't be found" do
|
353
|
+
let(:bad_consumer_name) { :not_a_consumer }
|
354
|
+
it "raises a MessageDriver:NoSuchConsumerError" do
|
355
|
+
expect {
|
356
|
+
subject.subscribe(destination, bad_consumer_name)
|
357
|
+
}.to raise_error(MessageDriver::NoSuchConsumerError, /#{bad_consumer_name}/)
|
358
|
+
adapter_context.should_not have_received(:subscribe)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context "when used as an included module" do
|
366
|
+
subject { TestPublisher.new }
|
367
|
+
it_behaves_like "a Client"
|
368
|
+
end
|
369
|
+
|
370
|
+
context "when the module is used directly" do
|
371
|
+
subject { described_class }
|
372
|
+
it_behaves_like "a Client"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
@@ -7,5 +7,14 @@ module MessageDriver::Destination
|
|
7
7
|
it "needs some real tests"
|
8
8
|
|
9
9
|
include_examples "doesn't support #message_count"
|
10
|
+
|
11
|
+
describe "#subscribe" do
|
12
|
+
it "raises an error" do
|
13
|
+
expect {
|
14
|
+
consumer = lambda do |m| end
|
15
|
+
destination.subscribe(&consumer)
|
16
|
+
}.to raise_error "#subscribe is not supported by #{destination.class}"
|
17
|
+
end
|
18
|
+
end
|
10
19
|
end
|
11
20
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MessageDriver
|
4
|
+
describe Logging do
|
5
|
+
class TestLogger
|
6
|
+
include Logging
|
7
|
+
end
|
8
|
+
subject { TestLogger.new }
|
9
|
+
|
10
|
+
describe "#logger" do
|
11
|
+
let(:logger) { double(Logger) }
|
12
|
+
it "returns the broker logger" do
|
13
|
+
allow(MessageDriver::Broker).to receive(:logger).and_return(logger)
|
14
|
+
expect(subject.logger).to be logger
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -15,5 +15,41 @@ module MessageDriver::Message
|
|
15
15
|
its(:properties) { should eq(properties) }
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
subject(:message) { described_class.new("body", {}, {}) }
|
20
|
+
|
21
|
+
describe "#ack" do
|
22
|
+
let(:options) { {foo: :bar} }
|
23
|
+
|
24
|
+
before do
|
25
|
+
MessageDriver::Client.stub(:ack_message)
|
26
|
+
end
|
27
|
+
it "passes itself to Client.ack_message" do
|
28
|
+
subject.ack
|
29
|
+
expect(MessageDriver::Client).to have_received(:ack_message).with(subject, {})
|
30
|
+
end
|
31
|
+
|
32
|
+
it "passes the options to Client.ack_message" do
|
33
|
+
subject.ack(options)
|
34
|
+
expect(MessageDriver::Client).to have_received(:ack_message).with(subject, options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#nack" do
|
39
|
+
let(:options) { {foo: :bar} }
|
40
|
+
|
41
|
+
before do
|
42
|
+
MessageDriver::Client.stub(:nack_message)
|
43
|
+
end
|
44
|
+
it "passes itself to Client.nack_message" do
|
45
|
+
subject.nack
|
46
|
+
expect(MessageDriver::Client).to have_received(:nack_message).with(subject, {})
|
47
|
+
end
|
48
|
+
|
49
|
+
it "passes the options to Client.nack_message" do
|
50
|
+
subject.nack(options)
|
51
|
+
expect(MessageDriver::Client).to have_received(:nack_message).with(subject, options)
|
52
|
+
end
|
53
|
+
end
|
18
54
|
end
|
19
55
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MessageDriver::Subscription
|
4
|
+
describe Base do
|
5
|
+
let(:adapter) { double(MessageDriver::Adapters::Base) }
|
6
|
+
let(:destination) { double(MessageDriver::Destination::Base) }
|
7
|
+
let(:consumer) { double("a consumer") }
|
8
|
+
subject(:subscription) { Base.new(adapter, destination, consumer) }
|
9
|
+
|
10
|
+
it "sets it's adapter, destination and consumer on instansiation" do
|
11
|
+
expect(subscription.adapter).to eq(adapter)
|
12
|
+
expect(subscription.destination).to eq(destination)
|
13
|
+
expect(subscription.consumer).to eq(consumer)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#unsubscribe" do
|
17
|
+
it "raises an error" do
|
18
|
+
expect {
|
19
|
+
subscription.unsubscribe
|
20
|
+
}.to raise_error("must be implemented in subclass")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/test_lib/broker_config.rb
CHANGED
@@ -1,25 +1,55 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
1
|
+
class BrokerConfig
|
2
|
+
class << self
|
3
|
+
def config
|
4
|
+
adapter_file = File.expand_path("../../.adapter_under_test", __FILE__)
|
5
|
+
@adapter, @version = (ENV['ADAPTER'] || (File.exist?(adapter_file) && File.read(adapter_file).chomp)).split(":")
|
6
|
+
case @adapter
|
7
|
+
when 'bunny'
|
8
|
+
{
|
9
|
+
adapter: :bunny,
|
10
|
+
vhost: 'message-driver-test'
|
11
|
+
}
|
12
|
+
when 'in_memory'
|
13
|
+
{adapter: :in_memory}
|
14
|
+
when 'stomp'
|
15
|
+
{
|
16
|
+
adapter: :stomp,
|
17
|
+
vhost: 'message-driver-test',
|
18
|
+
hosts: [{host: 'localhost', login: 'guest', passcode: 'guest'}],
|
19
|
+
reliable: false,
|
20
|
+
max_reconnect_attempts: 1
|
21
|
+
}
|
22
|
+
else
|
23
|
+
{adapter: :in_memory}
|
24
|
+
end
|
15
25
|
end
|
16
|
-
end
|
17
26
|
|
18
|
-
|
19
|
-
|
20
|
-
|
27
|
+
def all_adapters
|
28
|
+
%w(in_memory bunny stomp)
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_adapter
|
32
|
+
config[:adapter]
|
33
|
+
end
|
21
34
|
|
22
|
-
|
23
|
-
|
35
|
+
def adapter_version
|
36
|
+
config unless @version
|
37
|
+
@version
|
38
|
+
end
|
39
|
+
|
40
|
+
def unconfigured_adapters
|
41
|
+
all_adapters - [current_adapter]
|
42
|
+
end
|
43
|
+
|
44
|
+
def current_adapter_port
|
45
|
+
case current_adapter
|
46
|
+
when :bunny
|
47
|
+
5672
|
48
|
+
when :stomp
|
49
|
+
61613
|
50
|
+
else
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
24
54
|
end
|
25
55
|
end
|