message-driver 0.2.2 → 0.3.0

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.
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