message-driver 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -17
  3. data/CHANGELOG.md +6 -1
  4. data/Guardfile +3 -3
  5. data/Rakefile +0 -2
  6. data/ci/reset_vhost +5 -0
  7. data/ci/travis_setup +10 -0
  8. data/features/.nav +5 -2
  9. data/features/CHANGELOG.md +6 -1
  10. data/features/amqp_specific_features/declaring_amqp_exchanges.feature +3 -3
  11. data/features/amqp_specific_features/nack_redelivered_messages.feature +2 -2
  12. data/features/amqp_specific_features/server_named_destinations.feature +3 -4
  13. data/features/connecting_to_multiple_brokers.feature +51 -0
  14. data/features/destination_metadata.feature +2 -2
  15. data/features/dynamic_destinations.feature +2 -2
  16. data/features/error_handling.feature +2 -4
  17. data/features/logging.feature +3 -2
  18. data/features/message_consumers/auto_ack_consumers.feature +4 -4
  19. data/features/{message_consumers.feature → message_consumers/basics.feature} +2 -2
  20. data/features/message_consumers/manual_ack_consumers.feature +5 -5
  21. data/features/message_consumers/prefetch_size.feature +4 -4
  22. data/features/message_consumers/transactional_ack_consumers.feature +7 -4
  23. data/features/rabbitmq_specific_features/dead_letter_queueing.feature +3 -3
  24. data/features/step_definitions/dynamic_destinations_steps.rb +2 -2
  25. data/features/step_definitions/logging_steps.rb +5 -1
  26. data/features/step_definitions/message_consumers_steps.rb +1 -1
  27. data/features/step_definitions/steps.rb +13 -4
  28. data/features/support/env.rb +1 -1
  29. data/features/support/test_runner.rb +6 -1
  30. data/lib/message_driver/adapters/base.rb +7 -1
  31. data/lib/message_driver/adapters/bunny_adapter.rb +22 -57
  32. data/lib/message_driver/adapters/in_memory_adapter.rb +3 -2
  33. data/lib/message_driver/adapters/stomp_adapter.rb +6 -6
  34. data/lib/message_driver/broker.rb +80 -19
  35. data/lib/message_driver/client.rb +50 -29
  36. data/lib/message_driver/destination.rb +2 -2
  37. data/lib/message_driver/errors.rb +2 -0
  38. data/lib/message_driver/logging.rb +7 -1
  39. data/lib/message_driver/message.rb +15 -4
  40. data/lib/message_driver/version.rb +1 -1
  41. data/lib/message_driver.rb +12 -5
  42. data/spec/integration/bunny/amqp_integration_spec.rb +15 -20
  43. data/spec/integration/bunny/bunny_adapter_spec.rb +13 -13
  44. data/spec/integration/in_memory/in_memory_adapter_spec.rb +2 -1
  45. data/spec/integration/stomp/stomp_adapter_spec.rb +6 -8
  46. data/spec/spec_helper.rb +9 -0
  47. data/spec/support/shared/adapter_examples.rb +6 -0
  48. data/spec/support/shared/context_examples.rb +2 -0
  49. data/spec/support/shared/destination_examples.rb +2 -0
  50. data/spec/units/message_driver/adapters/base_spec.rb +0 -8
  51. data/spec/units/message_driver/broker_spec.rb +240 -109
  52. data/spec/units/message_driver/client_spec.rb +69 -62
  53. data/spec/units/message_driver/message_spec.rb +59 -22
  54. data/test_lib/broker_config.rb +2 -1
  55. metadata +8 -7
  56. data/lib/bunny/session_patch.rb +0 -19
  57. data/spec/units/message_driver/logging_spec.rb +0 -18
@@ -1,18 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "AMQP Integration", :bunny, type: :integration do
4
- before(:each) do
5
- MessageDriver.configure BrokerConfig.config
6
- end
7
- after(:each) do
8
- MessageDriver::Broker.stop
9
- end
4
+ let!(:broker) { MessageDriver::Broker.configure BrokerConfig.config }
10
5
 
11
6
  context "when a queue can't be found" do
12
7
  let(:queue_name) { "my.lost.queue" }
13
8
  it "raises a MessageDriver::QueueNotFound error" do
14
9
  expect {
15
- MessageDriver::Broker.dynamic_destination(queue_name, passive: true)
10
+ broker.dynamic_destination(queue_name, passive: true)
16
11
  }.to raise_error(MessageDriver::QueueNotFound) do |err|
17
12
  expect(err.queue_name).to eq(queue_name)
18
13
  expect(err.nested).to be_a Bunny::NotFound
@@ -23,16 +18,16 @@ describe "AMQP Integration", :bunny, type: :integration do
23
18
  context "when a channel level exception occurs" do
24
19
  it "raises a MessageDriver::WrappedError error" do
25
20
  expect {
26
- MessageDriver::Broker.dynamic_destination("not.a.queue", passive: true)
21
+ broker.dynamic_destination("not.a.queue", passive: true)
27
22
  }.to raise_error(MessageDriver::WrappedError) { |err| err.nested.should be_a Bunny::ChannelLevelException }
28
23
  end
29
24
 
30
25
  it "reestablishes the channel transparently" do
31
26
  expect {
32
- MessageDriver::Broker.dynamic_destination("not.a.queue", passive: true)
27
+ broker.dynamic_destination("not.a.queue", passive: true)
33
28
  }.to raise_error(MessageDriver::WrappedError)
34
29
  expect {
35
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
30
+ broker.dynamic_destination("", exclusive: true)
36
31
  }.to_not raise_error
37
32
  end
38
33
 
@@ -40,14 +35,14 @@ describe "AMQP Integration", :bunny, type: :integration do
40
35
  it "sets the channel_context as rollback-only until the transaction is finished" do
41
36
  MessageDriver::Client.with_message_transaction do
42
37
  expect {
43
- MessageDriver::Broker.dynamic_destination("not.a.queue", passive: true)
38
+ broker.dynamic_destination("not.a.queue", passive: true)
44
39
  }.to raise_error(MessageDriver::WrappedError)
45
40
  expect {
46
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
41
+ broker.dynamic_destination("", exclusive: true)
47
42
  }.to raise_error(MessageDriver::TransactionRollbackOnly)
48
43
  end
49
44
  expect {
50
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
45
+ broker.dynamic_destination("", exclusive: true)
51
46
  }.to_not raise_error
52
47
  end
53
48
  end
@@ -56,11 +51,11 @@ describe "AMQP Integration", :bunny, type: :integration do
56
51
  context "when the broker connection fails", pending: "these spec are busted" do
57
52
  def disrupt_connection
58
53
  #yes, this is very implementation specific
59
- MessageDriver::Broker.adapter.connection.instance_variable_get(:@transport).close
54
+ broker.adapter.connection.instance_variable_get(:@transport).close
60
55
  end
61
56
 
62
57
  def create_destination(queue_name)
63
- MessageDriver::Broker.dynamic_destination(queue_name, exclusive: true)
58
+ broker.dynamic_destination(queue_name, exclusive: true)
64
59
  end
65
60
 
66
61
  it "raises a MessageDriver::ConnectionError" do
@@ -91,7 +86,7 @@ describe "AMQP Integration", :bunny, type: :integration do
91
86
  expect {
92
87
  MessageDriver::Client.with_message_transaction do
93
88
  disrupt_connection
94
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
89
+ broker.dynamic_destination("", exclusive: true)
95
90
  end
96
91
  }.to raise_error(MessageDriver::ConnectionError)
97
92
  end
@@ -100,21 +95,21 @@ describe "AMQP Integration", :bunny, type: :integration do
100
95
  MessageDriver::Client.with_message_transaction do
101
96
  disrupt_connection
102
97
  expect {
103
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
98
+ broker.dynamic_destination("", exclusive: true)
104
99
  }.to raise_error(MessageDriver::ConnectionError)
105
100
  expect {
106
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
101
+ broker.dynamic_destination("", exclusive: true)
107
102
  }.to raise_error(MessageDriver::TransactionRollbackOnly)
108
103
  end
109
104
  expect {
110
- MessageDriver::Broker.dynamic_destination("", exclusive: true)
105
+ broker.dynamic_destination("", exclusive: true)
111
106
  }.to_not raise_error
112
107
  end
113
108
  end
114
109
  end
115
110
 
116
111
  context "when an unhandled expection occurs in a transaction" do
117
- let(:destination) { MessageDriver::Broker.dynamic_destination("", exclusive: true) }
112
+ let(:destination) { broker.dynamic_destination("", exclusive: true) }
118
113
 
119
114
  it "rolls back the transaction" do
120
115
  expect {
@@ -9,12 +9,13 @@ module MessageDriver::Adapters
9
9
 
10
10
  describe "#initialize" do
11
11
  context "differing bunny versions" do
12
+ let(:broker) { double("broker") }
12
13
  shared_examples "raises an error" do
13
14
  it "raises an error" do
14
15
  stub_const("Bunny::VERSION", version)
15
16
  expect {
16
- described_class.new(valid_connection_attrs)
17
- }.to raise_error MessageDriver::Error, "bunny 0.10.8 or later is required for the bunny adapter"
17
+ described_class.new(broker, valid_connection_attrs)
18
+ }.to raise_error MessageDriver::Error, "bunny 1.1.3 or later is required for the bunny adapter"
18
19
  end
19
20
  end
20
21
  shared_examples "doesn't raise an error" do
@@ -22,17 +23,17 @@ module MessageDriver::Adapters
22
23
  stub_const("Bunny::VERSION", version)
23
24
  adapter = nil
24
25
  expect {
25
- adapter = described_class.new(valid_connection_attrs)
26
+ adapter = described_class.new(broker, valid_connection_attrs)
26
27
  }.to_not raise_error
27
28
  end
28
29
  end
29
- %w(0.8.0 0.9.0.pre11 0.9.0.rc1 0.9.0 0.9.2 0.9.8 0.10.7).each do |v|
30
+ %w(0.8.0 0.9.0.pre11 0.9.0.rc1 0.9.0 0.9.8 0.10.7 1.0.3 1.1.2).each do |v|
30
31
  context "bunny version #{v}" do
31
32
  let(:version) { v }
32
33
  include_examples "raises an error"
33
34
  end
34
35
  end
35
- %w(0.10.8 1.0.0 1.0.3).each do |v|
36
+ %w(1.1.3 1.1.5).each do |v|
36
37
  context "bunny version #{v}" do
37
38
  let(:version) { v }
38
39
  include_examples "doesn't raise an error"
@@ -41,27 +42,26 @@ module MessageDriver::Adapters
41
42
  end
42
43
 
43
44
  it "connects to the rabbit broker" do
44
- adapter = described_class.new(valid_connection_attrs)
45
+ broker = double(:broker)
46
+ adapter = described_class.new(broker, valid_connection_attrs)
45
47
 
46
48
  expect(adapter.connection).to be_a Bunny::Session
47
49
  expect(adapter.connection).to be_open
48
50
  end
49
51
 
50
52
  it "connects to the rabbit broker lazily" do
51
- adapter = described_class.new(valid_connection_attrs)
53
+ broker = double(:broker)
54
+ adapter = described_class.new(broker, valid_connection_attrs)
52
55
 
53
- expect(adapter.connection(false)).to_not be_open
56
+ expect(adapter.connection(false)).to be_nil
54
57
  end
55
58
  end
56
59
 
57
60
  shared_context "a connected bunny adapter" do
58
- subject(:adapter) { described_class.new(valid_connection_attrs) }
61
+ let(:broker) { MessageDriver::Broker.configure(valid_connection_attrs) }
62
+ subject(:adapter) { broker.adapter }
59
63
  let(:connection) { adapter.connection }
60
64
 
61
- before do
62
- MessageDriver::Broker.configure(adapter: adapter)
63
- end
64
-
65
65
  after do
66
66
  adapter.stop
67
67
  end
@@ -4,7 +4,8 @@ require 'message_driver/adapters/in_memory_adapter'
4
4
 
5
5
  module MessageDriver::Adapters
6
6
  describe InMemoryAdapter, :in_memory, type: :integration do
7
- subject(:adapter) { described_class.new }
7
+ let(:broker) { double("broker") }
8
+ subject(:adapter) { described_class.new(broker) }
8
9
 
9
10
  describe "#new_context" do
10
11
  it "returns a InMemoryAdapter::InMemoryContext" do
@@ -9,13 +9,14 @@ module MessageDriver::Adapters
9
9
 
10
10
  describe "#initialize" do
11
11
  let(:connection_attrs) { valid_connection_attrs }
12
+ let(:broker) { double("broker") }
12
13
 
13
14
  context "differing stomp versions" do
14
15
  shared_examples "raises a stomp error" do
15
16
  it "raises an error" do
16
17
  stub_const("Stomp::Version::STRING", version)
17
18
  expect {
18
- described_class.new(connection_attrs)
19
+ described_class.new(broker, connection_attrs)
19
20
  }.to raise_error MessageDriver::Error, "stomp 1.3.1 or a later version of the 1.3.x series is required for the stomp adapter"
20
21
  end
21
22
  end
@@ -24,7 +25,7 @@ module MessageDriver::Adapters
24
25
  stub_const("Stomp::Version::STRING", version)
25
26
  adapter = nil
26
27
  expect {
27
- adapter = described_class.new(connection_attrs)
28
+ adapter = described_class.new(broker, connection_attrs)
28
29
  }.to_not raise_error
29
30
  end
30
31
  end
@@ -44,7 +45,7 @@ module MessageDriver::Adapters
44
45
 
45
46
  describe "the resulting config" do
46
47
  let(:connection_attrs) { {hosts: [{host: "my_host"}]} }
47
- subject(:config) { described_class.new(connection_attrs).config }
48
+ subject(:config) { described_class.new(broker, connection_attrs).config }
48
49
 
49
50
  its([:connect_headers]) { should eq(:"accept-version" => "1.1,1.2") }
50
51
  its([:hosts]) { should eq(connection_attrs[:hosts]) }
@@ -71,11 +72,8 @@ module MessageDriver::Adapters
71
72
  end
72
73
 
73
74
  shared_context "a connected stomp adapter" do
74
- subject(:adapter) { described_class.new(valid_connection_attrs) }
75
-
76
- before do
77
- MessageDriver::Broker.configure(adapter: adapter)
78
- end
75
+ let(:broker) { MessageDriver::Broker.configure(valid_connection_attrs) }
76
+ subject(:adapter) { broker.adapter }
79
77
 
80
78
  after do
81
79
  adapter.stop
data/spec/spec_helper.rb CHANGED
@@ -11,6 +11,15 @@ RSpec.configure do |c|
11
11
 
12
12
  c.reporter.message("Acceptance Tests running with broker config: #{BrokerConfig.config}")
13
13
 
14
+ spec_logger = Logger.new(STDOUT).tap { |l| l.level = Logger::FATAL }
15
+ c.before(:each) do
16
+ MessageDriver.logger = spec_logger
17
+ end
18
+
19
+ c.after(:each) do
20
+ MessageDriver::Broker.reset
21
+ end
22
+
14
23
  c.filter_run_excluding :no_ci if ENV['CI']=='true' && ENV['ADAPTER'] && ENV['ADAPTER'].start_with?('bunny')
15
24
  if c.inclusion_filter[:all_adapters] == true
16
25
  BrokerConfig.unconfigured_adapters.each do |a|
@@ -14,4 +14,10 @@ shared_examples "an adapter" do
14
14
  expect(ctx2).to_not be_valid
15
15
  end
16
16
  end
17
+
18
+ describe "#broker" do
19
+ it "returns the broker associated with the adapter" do
20
+ expect(subject.broker).to be(broker)
21
+ end
22
+ end
17
23
  end
@@ -1,6 +1,8 @@
1
1
  shared_examples "an adapter context" do
2
2
  it { should be_a MessageDriver::Adapters::ContextBase }
3
3
 
4
+ its(:adapter) { should be adapter }
5
+
4
6
  it "is initially valid" do
5
7
  should be_valid
6
8
  end
@@ -1,4 +1,6 @@
1
1
  shared_examples "a destination" do
2
+ its(:adapter) { should be adapter }
3
+
2
4
  describe "#pop_message" do
3
5
  let(:body) { "The message body" }
4
6
  let(:headers) { { "foo" => "bar", "bar" => "baz"} }
@@ -16,14 +16,6 @@ module MessageDriver::Adapters
16
16
  end
17
17
  end
18
18
 
19
- describe "#stop" do
20
- it "raises an error", pending: "maybe we don't want to do this" do
21
- expect {
22
- subject.stop
23
- }.to raise_error "Must be implemented in subclass"
24
- end
25
- end
26
-
27
19
  describe ContextBase do
28
20
  class TestContext < ContextBase
29
21
  end