bunny 1.0.0.pre3 → 1.0.0.pre4

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -1
  3. data/ChangeLog.md +54 -0
  4. data/README.md +5 -5
  5. data/benchmarks/mutex_and_monitor.rb +42 -0
  6. data/bunny.gemspec +2 -2
  7. data/examples/guides/extensions/connection_blocked.rb +35 -0
  8. data/lib/bunny/channel.rb +16 -7
  9. data/lib/bunny/exceptions.rb +4 -1
  10. data/lib/bunny/reader_loop.rb +17 -3
  11. data/lib/bunny/session.rb +58 -6
  12. data/lib/bunny/transport.rb +10 -1
  13. data/lib/bunny/version.rb +1 -1
  14. data/spec/higher_level_api/integration/basic_cancel_spec.rb +1 -1
  15. data/spec/higher_level_api/integration/basic_consume_spec.rb +1 -1
  16. data/spec/higher_level_api/integration/basic_nack_spec.rb +1 -1
  17. data/spec/higher_level_api/integration/basic_publish_spec.rb +1 -1
  18. data/spec/higher_level_api/integration/basic_qos_spec.rb +5 -8
  19. data/spec/higher_level_api/integration/basic_reject_spec.rb +16 -17
  20. data/spec/higher_level_api/integration/basic_return_spec.rb +1 -1
  21. data/spec/higher_level_api/integration/channel_close_spec.rb +6 -10
  22. data/spec/higher_level_api/integration/channel_flow_spec.rb +6 -9
  23. data/spec/higher_level_api/integration/channel_open_spec.rb +11 -20
  24. data/spec/higher_level_api/integration/confirm_select_spec.rb +1 -1
  25. data/spec/higher_level_api/integration/connection_spec.rb +1 -1
  26. data/spec/higher_level_api/integration/connection_stop_spec.rb +13 -0
  27. data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +1 -1
  28. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +46 -1
  29. data/spec/higher_level_api/integration/dead_lettering_spec.rb +1 -1
  30. data/spec/higher_level_api/integration/exchange_bind_spec.rb +1 -1
  31. data/spec/higher_level_api/integration/exchange_declare_spec.rb +1 -1
  32. data/spec/higher_level_api/integration/exchange_delete_spec.rb +1 -1
  33. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +1 -1
  34. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +28 -0
  35. data/spec/higher_level_api/integration/merry_go_round_spec.rb +1 -1
  36. data/spec/higher_level_api/integration/message_properties_access_spec.rb +1 -1
  37. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +1 -1
  38. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +1 -1
  39. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +1 -1
  40. data/spec/higher_level_api/integration/queue_declare_spec.rb +1 -1
  41. data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
  42. data/spec/higher_level_api/integration/queue_purge_spec.rb +1 -1
  43. data/spec/higher_level_api/integration/queue_unbind_spec.rb +2 -2
  44. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +1 -1
  45. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +2 -2
  46. data/spec/higher_level_api/integration/tls_connection_spec.rb +2 -2
  47. data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
  48. data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
  49. data/spec/stress/connection_open_close_spec.rb +25 -2
  50. data/spec/unit/concurrent/condition_spec.rb +53 -46
  51. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +48 -9
  52. metadata +10 -5
@@ -41,7 +41,12 @@ module Bunny
41
41
  @tls_certificate = opts[:tls_certificate] || opts[:ssl_cert_string]
42
42
  @tls_key = opts[:tls_key] || opts[:ssl_key_string]
43
43
  @tls_certificate_store = opts[:tls_certificate_store]
44
- @tls_ca_certificates = opts.fetch(:tls_ca_certificates, [])
44
+ @tls_ca_certificates = opts.fetch(:tls_ca_certificates, [
45
+ '/etc/ssl/certs/ca-certificates.crt', # Ubuntu/Debian
46
+ '/etc/ssl/certs/ca-bundle.crt', # Amazon Linux
47
+ '/etc/ssl/ca-bundle.pem', # OpenSUSE
48
+ '/etc/pki/tls/certs/ca-bundle.crt' # Fedora/RHEL
49
+ ])
45
50
  @verify_peer = opts[:verify_ssl] || opts[:verify_peer]
46
51
 
47
52
  @read_write_timeout = opts[:socket_timeout] || 3
@@ -339,6 +344,10 @@ module Bunny
339
344
  end
340
345
 
341
346
  def initialize_tls_certificate_store(certs)
347
+ certs = certs.select { |path| File.readable? path }
348
+ if certs.empty?
349
+ @logger.error "No CA certificates found, add one with :tls_ca_certificates"
350
+ end
342
351
  OpenSSL::X509::Store.new.tap do |store|
343
352
  certs.each { |path| store.add_file(path) }
344
353
  end
data/lib/bunny/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "1.0.0.pre3"
5
+ VERSION = "1.0.0.pre4"
6
6
  end
@@ -7,7 +7,7 @@ describe Bunny::Consumer, "#cancel" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -8,7 +8,7 @@ describe Bunny::Queue, "#subscribe" do
8
8
  c
9
9
  end
10
10
 
11
- after :all do
11
+ after :each do
12
12
  connection.close if connection.open?
13
13
  end
14
14
 
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#nack" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -8,7 +8,7 @@ if RUBY_VERSION <= "1.9"
8
8
  c
9
9
  end
10
10
 
11
- after :all do
11
+ after :each do
12
12
  connection.close if connection.open?
13
13
  end
14
14
 
@@ -7,25 +7,22 @@ describe Bunny::Channel, "#prefetch" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
-
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
14
  context "with a positive integer" do
20
15
  it "sets that prefetch level via basic.qos" do
21
- subject.prefetch(10).should be_instance_of(AMQ::Protocol::Basic::QosOk)
16
+ ch = connection.create_channel
17
+ ch.prefetch(10).should be_instance_of(AMQ::Protocol::Basic::QosOk)
22
18
  end
23
19
  end
24
20
 
25
21
  context "with a negative integer" do
26
22
  it "raises an ArgumentError" do
23
+ ch = connection.create_channel
27
24
  expect {
28
- subject.prefetch(-2)
25
+ ch.prefetch(-2)
29
26
  }.to raise_error(ArgumentError)
30
27
  end
31
28
  end
@@ -7,65 +7,64 @@ describe Bunny::Channel, "#reject" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
14
- subject do
15
- connection.create_channel
16
- end
17
-
18
14
  context "with requeue = true" do
19
15
  it "requeues a message" do
20
- q = subject.queue("bunny.basic.reject.manual-acks", :exclusive => true)
21
- x = subject.default_exchange
16
+ ch = connection.create_channel
17
+ q = ch.queue("bunny.basic.reject.manual-acks", :exclusive => true)
18
+ x = ch.default_exchange
22
19
 
23
20
  x.publish("bunneth", :routing_key => q.name)
24
21
  sleep(0.5)
25
22
  q.message_count.should == 1
26
23
  delivery_info, _, _ = q.pop(:ack => true)
27
24
 
28
- subject.reject(delivery_info.delivery_tag, true)
25
+ ch.reject(delivery_info.delivery_tag, true)
29
26
  sleep(0.5)
30
27
  q.message_count.should == 1
31
28
 
32
- subject.close
29
+ ch.close
33
30
  end
34
31
  end
35
32
 
36
33
  context "with requeue = false" do
37
34
  it "rejects a message" do
38
- q = subject.queue("bunny.basic.reject.with-requeue-false", :exclusive => true)
39
- x = subject.default_exchange
35
+ ch = connection.create_channel
36
+ q = ch.queue("bunny.basic.reject.with-requeue-false", :exclusive => true)
37
+ x = ch.default_exchange
40
38
 
41
39
  x.publish("bunneth", :routing_key => q.name)
42
40
  sleep(0.5)
43
41
  q.message_count.should == 1
44
42
  delivery_info, _, _ = q.pop(:ack => true)
45
43
 
46
- subject.reject(delivery_info.delivery_tag, false)
44
+ ch.reject(delivery_info.delivery_tag, false)
47
45
  sleep(0.5)
48
46
  q.message_count.should == 0
49
47
 
50
- subject.close
48
+ ch.close
51
49
  end
52
50
  end
53
51
 
54
52
 
55
53
  context "with an invalid (random) delivery tag" do
56
54
  it "causes a channel-level error" do
57
- q = subject.queue("bunny.basic.reject.unknown-delivery-tag", :exclusive => true)
58
- x = subject.default_exchange
55
+ ch = connection.create_channel
56
+ q = ch.queue("bunny.basic.reject.unknown-delivery-tag", :exclusive => true)
57
+ x = ch.default_exchange
59
58
 
60
59
  x.publish("bunneth", :routing_key => q.name)
61
60
  sleep(0.25)
62
61
  q.message_count.should == 1
63
62
  _, _, content = q.pop(:ack => true)
64
63
 
65
- subject.on_error do |ch, channel_close|
64
+ ch.on_error do |ch, channel_close|
66
65
  @channel_close = channel_close
67
66
  end
68
- subject.reject(82, true)
67
+ ch.reject(82, true)
69
68
 
70
69
  sleep 0.5
71
70
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange, "#publish" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,21 +7,17 @@ describe Bunny::Channel, "when closed" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
-
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
14
  it "releases the id" do
20
- n = subject.number
15
+ ch = connection.create_channel
16
+ n = ch.number
21
17
 
22
- subject.should be_open
23
- subject.close
24
- subject.should be_closed
18
+ ch.should be_open
19
+ ch.close
20
+ ch.should be_closed
25
21
 
26
22
  # a new channel with the same id can be created
27
23
  connection.create_channel(n)
@@ -7,18 +7,15 @@ describe Bunny::Channel, "#flow" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
-
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
14
  it "is supported" do
20
- subject.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
21
- subject.flow(false).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
22
- subject.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
15
+ ch = connection.create_channel
16
+
17
+ ch.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
18
+ ch.flow(false).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
19
+ ch.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
23
20
  end
24
21
  end
@@ -7,51 +7,42 @@ describe Bunny::Channel, "when opened" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
14
  context "without explicitly provided id" do
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
15
  it "gets an allocated id and is successfully opened" do
20
16
  connection.should be_connected
21
- subject.should be_open
17
+ ch = connection.create_channel
18
+ ch.should be_open
22
19
 
23
- subject.id.should be > 0
20
+ ch.id.should be > 0
24
21
  end
25
22
  end
26
23
 
27
24
 
28
25
  context "with explicitly provided id" do
29
- subject do
30
- connection.create_channel(767)
31
- end
32
-
33
26
  it "uses that id and is successfully opened" do
27
+ ch = connection.create_channel(767)
34
28
  connection.should be_connected
35
- subject.should be_open
29
+ ch.should be_open
36
30
 
37
- subject.id.should == 767
31
+ ch.id.should == 767
38
32
  end
39
33
  end
40
34
 
41
35
 
42
36
 
43
37
  context "with explicitly provided id that is already taken" do
44
- subject do
45
- connection.create_channel(767)
46
- end
47
-
48
38
  it "reuses the channel that is already opened" do
39
+ ch = connection.create_channel(767)
49
40
  connection.should be_connected
50
- subject.should be_open
41
+ ch.should be_open
51
42
 
52
- subject.id.should == 767
43
+ ch.id.should == 767
53
44
 
54
- connection.create_channel(767).should == subject
45
+ connection.create_channel(767).should == ch
55
46
  end
56
47
  end
57
48
  end
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#confirm_select" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -284,7 +284,7 @@ describe Bunny::Session do
284
284
 
285
285
 
286
286
  context "initialized with :host => 127.0.0.1 and non-default credentials (take 2)" do
287
- after :all do
287
+ after :each do
288
288
  subject.close if subject.open?
289
289
  end
290
290
 
@@ -11,3 +11,16 @@ describe Bunny::Session do
11
11
  c.should be_closed
12
12
  end
13
13
  end
14
+
15
+
16
+ describe Bunny::Session, "in a single threaded mode" do
17
+ it "can be closed" do
18
+ c = Bunny.new(:automatically_recover => false, :threaded => false)
19
+ c.start
20
+ ch = c.create_channel
21
+
22
+ c.should be_connected
23
+ c.stop
24
+ c.should be_closed
25
+ end
26
+ end
@@ -9,7 +9,7 @@ unless ENV["CI"]
9
9
  c
10
10
  end
11
11
 
12
- after :all do
12
+ after :each do
13
13
  connection.close
14
14
  end
15
15
 
@@ -7,7 +7,7 @@ describe Bunny::Channel do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -80,4 +80,49 @@ describe Bunny::Channel do
80
80
  ch.close
81
81
  end
82
82
  end
83
+
84
+
85
+
86
+ context "with consumer re-registration" do
87
+ class ExampleConsumerThatReregisters < Bunny::Consumer
88
+ def handle_cancellation(_)
89
+ @queue = @channel.queue("basic.consume.after_cancellation", :auto_delete => true)
90
+ @channel.basic_consume_with(self)
91
+ end
92
+ end
93
+
94
+ let(:queue_name) { "basic.consume#{rand}" }
95
+
96
+ it "works correctly" do
97
+ consumer = nil
98
+ xs = []
99
+
100
+ ch = connection.create_channel
101
+ t = Thread.new do
102
+ ch2 = connection.create_channel
103
+ q = ch2.queue(queue_name, :auto_delete => true)
104
+
105
+ consumer = ExampleConsumerThatReregisters.new(ch2, q, "")
106
+ consumer.on_delivery do |_, _, payload|
107
+ xs << payload
108
+ end
109
+ q.subscribe_with(consumer)
110
+ end
111
+ t.abort_on_exception = true
112
+
113
+ sleep 0.5
114
+ x = ch.default_exchange
115
+ x.publish("abc", :routing_key => queue_name)
116
+
117
+ sleep 0.5
118
+ ch.queue(queue_name, :auto_delete => true).delete
119
+
120
+ x.publish("abc", :routing_key => queue_name)
121
+ sleep 0.5
122
+ q = ch.queue("basic.consume.after_cancellation", :auto_delete => true)
123
+ xs.should == ["abc"]
124
+
125
+ ch.close
126
+ end
127
+ end
83
128
  end
@@ -7,7 +7,7 @@ describe "A message" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13