bunny 1.3.0 → 2.17.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 (143) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE.md +18 -0
  3. data/.gitignore +7 -1
  4. data/.rspec +1 -3
  5. data/.travis.yml +21 -14
  6. data/CONTRIBUTING.md +132 -0
  7. data/ChangeLog.md +887 -1
  8. data/Gemfile +13 -13
  9. data/LICENSE +1 -1
  10. data/README.md +46 -60
  11. data/Rakefile +54 -0
  12. data/bunny.gemspec +5 -11
  13. data/docker-compose.yml +28 -0
  14. data/docker/Dockerfile +24 -0
  15. data/docker/apt/preferences.d/erlang +3 -0
  16. data/docker/apt/sources.list.d/bintray.rabbitmq.list +2 -0
  17. data/docker/docker-entrypoint.sh +26 -0
  18. data/docker/rabbitmq.conf +29 -0
  19. data/examples/connection/automatic_recovery_with_basic_get.rb +1 -1
  20. data/examples/connection/automatic_recovery_with_client_named_queues.rb +1 -1
  21. data/examples/connection/automatic_recovery_with_multiple_consumers.rb +1 -1
  22. data/examples/connection/automatic_recovery_with_republishing.rb +1 -1
  23. data/examples/connection/automatic_recovery_with_server_named_queues.rb +1 -1
  24. data/examples/connection/channel_level_exception.rb +1 -9
  25. data/examples/connection/disabled_automatic_recovery.rb +1 -1
  26. data/examples/connection/heartbeat.rb +1 -1
  27. data/examples/consumers/high_and_low_priority.rb +1 -1
  28. data/examples/guides/extensions/alternate_exchange.rb +2 -0
  29. data/examples/guides/extensions/basic_nack.rb +1 -1
  30. data/examples/guides/extensions/dead_letter_exchange.rb +1 -1
  31. data/examples/guides/getting_started/hello_world.rb +2 -0
  32. data/examples/guides/getting_started/weathr.rb +2 -0
  33. data/examples/guides/queues/one_off_consumer.rb +2 -0
  34. data/examples/guides/queues/redeliveries.rb +4 -2
  35. data/lib/bunny.rb +8 -4
  36. data/lib/bunny/channel.rb +268 -153
  37. data/lib/bunny/channel_id_allocator.rb +6 -4
  38. data/lib/bunny/concurrent/continuation_queue.rb +34 -13
  39. data/lib/bunny/consumer_work_pool.rb +34 -6
  40. data/lib/bunny/cruby/socket.rb +48 -21
  41. data/lib/bunny/cruby/ssl_socket.rb +65 -4
  42. data/lib/bunny/exceptions.rb +25 -4
  43. data/lib/bunny/exchange.rb +24 -28
  44. data/lib/bunny/get_response.rb +1 -1
  45. data/lib/bunny/heartbeat_sender.rb +3 -2
  46. data/lib/bunny/jruby/socket.rb +23 -6
  47. data/lib/bunny/jruby/ssl_socket.rb +5 -0
  48. data/lib/bunny/queue.rb +31 -22
  49. data/lib/bunny/reader_loop.rb +31 -18
  50. data/lib/bunny/session.rb +448 -159
  51. data/lib/bunny/test_kit.rb +14 -0
  52. data/lib/bunny/timeout.rb +1 -12
  53. data/lib/bunny/transport.rb +205 -98
  54. data/lib/bunny/version.rb +1 -1
  55. data/repl +1 -1
  56. data/spec/config/enabled_plugins +1 -0
  57. data/spec/config/rabbitmq.conf +13 -0
  58. data/spec/higher_level_api/integration/basic_ack_spec.rb +175 -16
  59. data/spec/higher_level_api/integration/basic_cancel_spec.rb +77 -11
  60. data/spec/higher_level_api/integration/basic_consume_spec.rb +60 -55
  61. data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +6 -6
  62. data/spec/higher_level_api/integration/basic_get_spec.rb +31 -7
  63. data/spec/higher_level_api/integration/basic_nack_spec.rb +22 -19
  64. data/spec/higher_level_api/integration/basic_publish_spec.rb +11 -100
  65. data/spec/higher_level_api/integration/basic_qos_spec.rb +32 -4
  66. data/spec/higher_level_api/integration/basic_reject_spec.rb +94 -16
  67. data/spec/higher_level_api/integration/basic_return_spec.rb +4 -4
  68. data/spec/higher_level_api/integration/channel_close_spec.rb +51 -10
  69. data/spec/higher_level_api/integration/channel_open_spec.rb +12 -12
  70. data/spec/higher_level_api/integration/connection_recovery_spec.rb +424 -221
  71. data/spec/higher_level_api/integration/connection_spec.rb +300 -126
  72. data/spec/higher_level_api/integration/connection_stop_spec.rb +31 -19
  73. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +17 -17
  74. data/spec/higher_level_api/integration/dead_lettering_spec.rb +34 -11
  75. data/spec/higher_level_api/integration/exchange_bind_spec.rb +5 -5
  76. data/spec/higher_level_api/integration/exchange_declare_spec.rb +32 -31
  77. data/spec/higher_level_api/integration/exchange_delete_spec.rb +12 -12
  78. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +5 -5
  79. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +5 -5
  80. data/spec/higher_level_api/integration/heartbeat_spec.rb +26 -8
  81. data/spec/higher_level_api/integration/message_properties_access_spec.rb +49 -49
  82. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +2 -2
  83. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +156 -42
  84. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +19 -19
  85. data/spec/higher_level_api/integration/queue_bind_spec.rb +23 -23
  86. data/spec/higher_level_api/integration/queue_declare_spec.rb +129 -34
  87. data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
  88. data/spec/higher_level_api/integration/queue_purge_spec.rb +5 -5
  89. data/spec/higher_level_api/integration/queue_unbind_spec.rb +6 -6
  90. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +9 -9
  91. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +10 -10
  92. data/spec/higher_level_api/integration/tls_connection_spec.rb +224 -89
  93. data/spec/higher_level_api/integration/toxiproxy_spec.rb +76 -0
  94. data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
  95. data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
  96. data/spec/higher_level_api/integration/with_channel_spec.rb +2 -2
  97. data/spec/issues/issue100_spec.rb +11 -11
  98. data/spec/issues/issue141_spec.rb +13 -14
  99. data/spec/issues/issue202_spec.rb +1 -1
  100. data/spec/issues/issue224_spec.rb +40 -0
  101. data/spec/issues/issue465_spec.rb +32 -0
  102. data/spec/issues/issue549_spec.rb +30 -0
  103. data/spec/issues/issue78_spec.rb +21 -24
  104. data/spec/issues/issue83_spec.rb +5 -6
  105. data/spec/issues/issue97_spec.rb +44 -45
  106. data/spec/lower_level_api/integration/basic_cancel_spec.rb +15 -16
  107. data/spec/lower_level_api/integration/basic_consume_spec.rb +20 -21
  108. data/spec/spec_helper.rb +8 -26
  109. data/spec/stress/channel_close_stress_spec.rb +64 -0
  110. data/spec/stress/channel_open_stress_spec.rb +15 -9
  111. data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +7 -7
  112. data/spec/stress/concurrent_consumers_stress_spec.rb +18 -16
  113. data/spec/stress/concurrent_publishers_stress_spec.rb +16 -19
  114. data/spec/stress/connection_open_close_spec.rb +9 -9
  115. data/spec/stress/merry_go_round_spec.rb +105 -0
  116. data/spec/tls/client_key.pem +49 -25
  117. data/spec/tls/generate-server-cert.sh +8 -0
  118. data/spec/tls/server-openssl.cnf +10 -0
  119. data/spec/tls/server.csr +16 -0
  120. data/spec/tls/server_key.pem +49 -25
  121. data/spec/toxiproxy_helper.rb +28 -0
  122. data/spec/unit/bunny_spec.rb +5 -5
  123. data/spec/unit/concurrent/atomic_fixnum_spec.rb +6 -6
  124. data/spec/unit/concurrent/condition_spec.rb +8 -8
  125. data/spec/unit/concurrent/linked_continuation_queue_spec.rb +2 -2
  126. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +16 -16
  127. data/spec/unit/exchange_recovery_spec.rb +39 -0
  128. data/spec/unit/version_delivery_tag_spec.rb +3 -3
  129. metadata +65 -47
  130. data/.ruby-version +0 -1
  131. data/lib/bunny/compatibility.rb +0 -24
  132. data/lib/bunny/system_timer.rb +0 -20
  133. data/spec/compatibility/queue_declare_spec.rb +0 -44
  134. data/spec/compatibility/queue_declare_with_default_channel_spec.rb +0 -33
  135. data/spec/higher_level_api/integration/basic_recover_spec.rb +0 -18
  136. data/spec/higher_level_api/integration/confirm_select_spec.rb +0 -19
  137. data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +0 -50
  138. data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
  139. data/spec/stress/long_running_consumer_spec.rb +0 -83
  140. data/spec/tls/cacert.pem +0 -18
  141. data/spec/tls/client_cert.pem +0 -18
  142. data/spec/tls/server_cert.pem +0 -18
  143. data/spec/unit/system_timer_spec.rb +0 -10
@@ -1,33 +1,32 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Message framing implementation" do
4
- let(:connection) do
5
- c = Bunny.new(:user => "bunny_gem",
6
- :password => "bunny_password",
7
- :vhost => "bunny_testbed",
8
- :port => ENV.fetch("RABBITMQ_PORT", 5672))
9
- c.start
10
- c
4
+ before :all do
5
+ @connection = Bunny.new(username: "bunny_gem",
6
+ password: "bunny_password",
7
+ vhost: "bunny_testbed",
8
+ port: ENV.fetch("RABBITMQ_PORT", 5672))
9
+ @connection.start
11
10
  end
12
11
 
13
12
  after :all do
14
- connection.close if connection.open?
13
+ @connection.close if @connection.open?
15
14
  end
16
15
 
17
16
 
18
17
  unless ENV["CI"]
19
18
  context "with payload ~ 248K in size including non-ASCII characters" do
20
19
  it "successfully frames the message" do
21
- ch = connection.create_channel
20
+ ch = @connection.create_channel
22
21
 
23
- q = ch.queue("", :exclusive => true)
22
+ q = ch.queue("", exclusive: true)
24
23
  x = ch.default_exchange
25
24
 
26
25
  body = IO.read("spec/issues/issue97_attachment.json")
27
- x.publish(body, :routing_key => q.name, :persistent => true)
26
+ x.publish(body, routing_key: q.name, persistent: true)
28
27
 
29
28
  sleep(1)
30
- q.message_count.should == 1
29
+ expect(q.message_count).to eq 1
31
30
 
32
31
  q.purge
33
32
  ch.close
@@ -38,19 +37,19 @@ describe "Message framing implementation" do
38
37
 
39
38
  context "with payload of several MBs in size" do
40
39
  it "successfully frames the message" do
41
- ch = connection.create_channel
40
+ ch = @connection.create_channel
42
41
 
43
- q = ch.queue("", :exclusive => true)
42
+ q = ch.queue("", exclusive: true)
44
43
  x = ch.default_exchange
45
44
 
46
45
  as = ("a" * (1024 * 1024 * 4 + 2823777))
47
- x.publish(as, :routing_key => q.name, :persistent => true)
46
+ x.publish(as, routing_key: q.name, persistent: true)
48
47
 
49
48
  sleep(1)
50
- q.message_count.should == 1
49
+ expect(q.message_count).to eq 1
51
50
 
52
51
  _, _, payload = q.pop
53
- payload.bytesize.should == as.bytesize
52
+ expect(payload.bytesize).to eq as.bytesize
54
53
 
55
54
  ch.close
56
55
  end
@@ -60,23 +59,23 @@ describe "Message framing implementation" do
60
59
 
61
60
  context "with empty message body" do
62
61
  it "successfully publishes the message" do
63
- ch = connection.create_channel
62
+ ch = @connection.create_channel
64
63
 
65
- q = ch.queue("", :exclusive => true)
64
+ q = ch.queue("", exclusive: true)
66
65
  x = ch.default_exchange
67
66
 
68
- x.publish("", :routing_key => q.name, :persistent => true)
67
+ x.publish("", routing_key: q.name, persistent: true)
69
68
 
70
69
  sleep(1)
71
- q.message_count.should == 1
70
+ expect(q.message_count).to eq 1
72
71
 
73
72
  envelope, headers, payload = q.pop
74
73
 
75
- payload.should == ""
74
+ expect(payload).to eq ""
76
75
 
77
- headers[:content_type].should == "application/octet-stream"
78
- headers[:delivery_mode].should == 2
79
- headers[:priority].should == 0
76
+ expect(headers[:content_type]).to eq "application/octet-stream"
77
+ expect(headers[:delivery_mode]).to eq 2
78
+ expect(headers[:priority]).to eq 0
80
79
 
81
80
  ch.close
82
81
  end
@@ -85,16 +84,16 @@ describe "Message framing implementation" do
85
84
 
86
85
  context "with payload being 2 bytes less than 128K bytes in size" do
87
86
  it "successfully frames the message" do
88
- ch = connection.create_channel
87
+ ch = @connection.create_channel
89
88
 
90
- q = ch.queue("", :exclusive => true)
89
+ q = ch.queue("", exclusive: true)
91
90
  x = ch.default_exchange
92
91
 
93
92
  as = "a" * (1024 * 128 - 2)
94
- x.publish(as, :routing_key => q.name, :persistent => true)
93
+ x.publish(as, routing_key: q.name, persistent: true)
95
94
 
96
95
  sleep(1)
97
- q.message_count.should == 1
96
+ expect(q.message_count).to eq 1
98
97
 
99
98
  q.purge
100
99
  ch.close
@@ -103,16 +102,16 @@ describe "Message framing implementation" do
103
102
 
104
103
  context "with payload being 1 byte less than 128K bytes in size" do
105
104
  it "successfully frames the message" do
106
- ch = connection.create_channel
105
+ ch = @connection.create_channel
107
106
 
108
- q = ch.queue("", :exclusive => true)
107
+ q = ch.queue("", exclusive: true)
109
108
  x = ch.default_exchange
110
109
 
111
110
  as = "a" * (1024 * 128 - 1)
112
- x.publish(as, :routing_key => q.name, :persistent => true)
111
+ x.publish(as, routing_key: q.name, persistent: true)
113
112
 
114
113
  sleep(1)
115
- q.message_count.should == 1
114
+ expect(q.message_count).to eq 1
116
115
 
117
116
  q.purge
118
117
  ch.close
@@ -121,16 +120,16 @@ describe "Message framing implementation" do
121
120
 
122
121
  context "with payload being exactly 128K bytes in size" do
123
122
  it "successfully frames the message" do
124
- ch = connection.create_channel
123
+ ch = @connection.create_channel
125
124
 
126
- q = ch.queue("", :exclusive => true)
125
+ q = ch.queue("", exclusive: true)
127
126
  x = ch.default_exchange
128
127
 
129
128
  as = "a" * (1024 * 128)
130
- x.publish(as, :routing_key => q.name, :persistent => true)
129
+ x.publish(as, routing_key: q.name, persistent: true)
131
130
 
132
131
  sleep(1)
133
- q.message_count.should == 1
132
+ expect(q.message_count).to eq 1
134
133
 
135
134
  q.purge
136
135
  ch.close
@@ -140,16 +139,16 @@ describe "Message framing implementation" do
140
139
 
141
140
  context "with payload being 1 byte greater than 128K bytes in size" do
142
141
  it "successfully frames the message" do
143
- ch = connection.create_channel
142
+ ch = @connection.create_channel
144
143
 
145
- q = ch.queue("", :exclusive => true)
144
+ q = ch.queue("", exclusive: true)
146
145
  x = ch.default_exchange
147
146
 
148
147
  as = "a" * (1024 * 128 + 1)
149
- x.publish(as, :routing_key => q.name, :persistent => true)
148
+ x.publish(as, routing_key: q.name, persistent: true)
150
149
 
151
150
  sleep(1)
152
- q.message_count.should == 1
151
+ expect(q.message_count).to eq 1
153
152
 
154
153
  q.purge
155
154
  ch.close
@@ -158,16 +157,16 @@ describe "Message framing implementation" do
158
157
 
159
158
  context "with payload being 2 bytes greater than 128K bytes in size" do
160
159
  it "successfully frames the message" do
161
- ch = connection.create_channel
160
+ ch = @connection.create_channel
162
161
 
163
- q = ch.queue("", :exclusive => true)
162
+ q = ch.queue("", exclusive: true)
164
163
  x = ch.default_exchange
165
164
 
166
165
  as = "a" * (1024 * 128 + 2)
167
- x.publish(as, :routing_key => q.name, :persistent => true)
166
+ x.publish(as, routing_key: q.name, persistent: true)
168
167
 
169
168
  sleep(1)
170
- q.message_count.should == 1
169
+ expect(q.message_count).to eq 1
171
170
 
172
171
  q.purge
173
172
  ch.close
@@ -1,27 +1,26 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel, "#basic_cancel" do
4
- let(:connection) do
5
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
- c.start
7
- c
4
+ before(:all) do
5
+ @connection = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
+ @connection.start
8
7
  end
9
8
 
10
9
  after :all do
11
- connection.close if connection.open?
10
+ @connection.close if @connection.open?
12
11
  end
13
12
 
14
13
  let(:queue_name) { "bunny.queues.#{rand}" }
15
14
 
16
15
  it "returns basic.cancel-ok" do
17
- ch = connection.create_channel
16
+ ch = @connection.create_channel
18
17
  q = ch.queue("", :exclusive => true)
19
18
 
20
19
  consume_ok = ch.basic_consume(q, "")
21
20
  cancel_ok = ch.basic_cancel(consume_ok.consumer_tag)
22
21
 
23
- cancel_ok.should be_instance_of(AMQ::Protocol::Basic::CancelOk)
24
- cancel_ok.consumer_tag.should == consume_ok.consumer_tag
22
+ expect(cancel_ok).to be_instance_of AMQ::Protocol::Basic::CancelOk
23
+ expect(cancel_ok.consumer_tag).to eq consume_ok.consumer_tag
25
24
 
26
25
  ch.close
27
26
  end
@@ -33,32 +32,32 @@ describe Bunny::Channel, "#basic_cancel" do
33
32
  delivered_data = []
34
33
 
35
34
  t = Thread.new do
36
- ch = connection.create_channel
35
+ ch = @connection.create_channel
37
36
  q = ch.queue(queue_name, :auto_delete => true, :durable => false)
38
37
  consume_ok = ch.basic_consume(q, "", true, false) do |_, _, payload|
39
38
  delivered_data << payload
40
39
  end
41
40
 
42
- consume_ok.consumer_tag.should_not be_nil
41
+ expect(consume_ok.consumer_tag).not_to be_nil
43
42
  cancel_ok = ch.basic_cancel(consume_ok.consumer_tag)
44
- cancel_ok.consumer_tag.should == consume_ok.consumer_tag
43
+ expect(cancel_ok.consumer_tag).to eq consume_ok.consumer_tag
45
44
 
46
45
  ch.close
47
46
  end
48
47
  t.abort_on_exception = true
49
48
  sleep 0.5
50
49
 
51
- ch = connection.create_channel
50
+ ch = @connection.create_channel
52
51
  ch.default_exchange.publish("", :routing_key => queue_name)
53
52
 
54
53
  sleep 0.7
55
- delivered_data.should be_empty
54
+ expect(delivered_data).to be_empty
56
55
  end
57
56
  end
58
57
 
59
58
  context "when the given consumer tag is invalid (was never registered)" do
60
59
  it "DOES NOT cause a channel error" do
61
- ch = connection.create_channel
60
+ ch = @connection.create_channel
62
61
 
63
62
  # RabbitMQ 3.1 does not raise an exception w/ unknown consumer tag. MK.
64
63
  ch.basic_cancel("878798s7df89#{rand}#{Time.now.to_i}")
@@ -69,8 +68,8 @@ describe Bunny::Channel, "#basic_cancel" do
69
68
 
70
69
  context "when the given consumer tag belongs to a different channel" do
71
70
  it "DOES NOT cause a channel error" do
72
- ch1 = connection.create_channel
73
- ch2 = connection.create_channel
71
+ ch1 = @connection.create_channel
72
+ ch2 = @connection.create_channel
74
73
 
75
74
  q = ch1.queue("", :exclusive => true)
76
75
  cons = q.subscribe do |_, _, _|
@@ -1,33 +1,32 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel, "#basic_consume" do
4
- let(:connection) do
5
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
- c.start
7
- c
4
+ before(:all) do
5
+ @connection = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
+ @connection.start
8
7
  end
9
8
 
10
9
  after :all do
11
- connection.close if connection.open?
10
+ @connection.close if @connection.open?
12
11
  end
13
12
 
14
13
  it "returns basic.consume-ok when it is received" do
15
- ch = connection.create_channel
14
+ ch = @connection.create_channel
16
15
  q = ch.queue("", :exclusive => true)
17
16
 
18
17
  consume_ok = ch.basic_consume(q)
19
- consume_ok.should be_instance_of(AMQ::Protocol::Basic::ConsumeOk)
20
- consume_ok.consumer_tag.should_not be_nil
18
+ expect(consume_ok).to be_instance_of AMQ::Protocol::Basic::ConsumeOk
19
+ expect(consume_ok.consumer_tag).not_to be_nil
21
20
 
22
21
  ch.close
23
22
  end
24
23
 
25
24
  it "carries server-generated consumer tag with basic.consume-ok" do
26
- ch = connection.create_channel
25
+ ch = @connection.create_channel
27
26
  q = ch.queue("", :exclusive => true)
28
27
 
29
28
  consume_ok = ch.basic_consume(q, "")
30
- consume_ok.consumer_tag.should =~ /amq\.ctag.*/
29
+ expect(consume_ok.consumer_tag).to match /amq\.ctag.*/
31
30
 
32
31
  ch.close
33
32
  end
@@ -40,7 +39,7 @@ describe Bunny::Channel, "#basic_consume" do
40
39
  delivered_data = []
41
40
 
42
41
  t = Thread.new do
43
- ch = connection.create_channel
42
+ ch = @connection.create_channel
44
43
  q = ch.queue(queue_name, :auto_delete => true, :durable => false)
45
44
  ch.basic_consume(q, "", true, false) do |delivery_info, properties, payload|
46
45
  delivered_keys << delivery_info.routing_key
@@ -50,15 +49,15 @@ describe Bunny::Channel, "#basic_consume" do
50
49
  t.abort_on_exception = true
51
50
  sleep 0.5
52
51
 
53
- ch = connection.create_channel
52
+ ch = @connection.create_channel
54
53
  x = ch.default_exchange
55
54
  x.publish("hello", :routing_key => queue_name)
56
55
 
57
56
  sleep 0.7
58
- delivered_keys.should include(queue_name)
59
- delivered_data.should include("hello")
57
+ expect(delivered_keys).to include queue_name
58
+ expect(delivered_data).to include "hello"
60
59
 
61
- ch.queue(queue_name, :auto_delete => true, :durable => false).message_count.should == 0
60
+ expect(ch.queue(queue_name, :auto_delete => true, :durable => false).message_count).to eq 0
62
61
 
63
62
  ch.close
64
63
  end
@@ -72,7 +71,7 @@ describe Bunny::Channel, "#basic_consume" do
72
71
  delivered_data = []
73
72
 
74
73
  t = Thread.new do
75
- ch = connection.create_channel
74
+ ch = @connection.create_channel
76
75
  q = ch.queue(queue_name, :auto_delete => true, :durable => false)
77
76
  ch.basic_consume(q, "", false, false) do |delivery_info, properties, payload|
78
77
  delivered_keys << delivery_info.routing_key
@@ -84,17 +83,17 @@ describe Bunny::Channel, "#basic_consume" do
84
83
  t.abort_on_exception = true
85
84
  sleep 0.5
86
85
 
87
- ch = connection.create_channel
86
+ ch = @connection.create_channel
88
87
  x = ch.default_exchange
89
88
  x.publish("hello", :routing_key => queue_name)
90
89
 
91
90
  sleep 0.7
92
- delivered_keys.should include(queue_name)
93
- delivered_data.should include("hello")
91
+ expect(delivered_keys).to include queue_name
92
+ expect(delivered_data).to include "hello"
94
93
 
95
- ch.queue(queue_name, :auto_delete => true, :durable => false).message_count.should == 0
94
+ expect(ch.queue(queue_name, :auto_delete => true, :durable => false).message_count).to eq 0
96
95
 
97
- ch.close
96
+ ch.close
98
97
  end
99
98
  end
100
99
  end
data/spec/spec_helper.rb CHANGED
@@ -3,47 +3,29 @@
3
3
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
4
 
5
5
  require 'bundler'
6
- Bundler.setup(:default, :test)
6
+ Bundler.require(:default, :test)
7
7
 
8
-
9
- require "effin_utf8"
10
8
  require "bunny"
11
- require "rabbitmq/http/client"
12
-
9
+ require "bunny/test_kit"
13
10
 
14
- require "amq/protocol/version"
15
11
  puts "Using Ruby #{RUBY_VERSION}, amq-protocol #{AMQ::Protocol::VERSION}"
16
12
 
17
-
18
-
19
- #
20
- # Ruby version-specific
21
- #
22
-
23
- case RUBY_VERSION
24
- when "1.8.7" then
25
- class Array
26
- alias sample choice
27
- end
28
- when "1.8.6" then
29
- raise "Ruby 1.8.6 is not supported. Sorry, pal. Time to move on beyond One True Ruby. Yes, time flies by."
30
- end
31
-
32
-
33
-
34
13
  module RabbitMQ
35
14
  module Control
15
+
16
+ RABBITMQ_NODENAME = ENV['RABBITMQ_NODENAME'] || 'rabbit'
17
+
36
18
  def rabbitmq_pid
37
- $1.to_i if `rabbitmqctl status` =~ /\{pid,(\d+)\}/
19
+ $1.to_i if `rabbitmqctl -n #{RABBITMQ_NODENAME} status` =~ /\{pid,(\d+)\}/
38
20
  end
39
21
 
40
22
  def start_rabbitmq(delay = 1.0)
41
23
  # this is Homebrew-specific :(
42
- `rabbitmq-server > /dev/null 2>&1 &`; sleep(delay)
24
+ `RABBITMQ_NODENAME=#{RABBITMQ_NODENAME} rabbitmq-server > /dev/null 2>&1 &`; sleep(delay)
43
25
  end
44
26
 
45
27
  def stop_rabbitmq(pid = rabbitmq_pid, delay = 1.0)
46
- `rabbitmqctl stop`; sleep(delay)
28
+ `rabbitmqctl -n #{RABBITMQ_NODENAME} stop`; sleep(delay)
47
29
  end
48
30
 
49
31
  def kill_rabbitmq(pid = rabbitmq_pid, delay = 1.0)
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ describe "Rapidly closing lots of temporary channels" do
4
+ before :all do
5
+ @connection = Bunny.new(automatic_recovery: false).tap do |c|
6
+ c.start
7
+ end
8
+ end
9
+
10
+ after :all do
11
+ @connection.close
12
+ end
13
+
14
+ 100.times do |i|
15
+ context "in a multi-threaded scenario A (take #{i})" do
16
+ let(:n) { 20 }
17
+
18
+ it "works correctly" do
19
+ ts = []
20
+
21
+ n.times do
22
+ t = Thread.new do
23
+ @connection.with_channel do |ch1|
24
+ q = ch1.queue("", exclusive: true)
25
+ q.delete
26
+ ch1.close
27
+ end
28
+
29
+ ch2 = @connection.create_channel
30
+ ch2.close
31
+ end
32
+ t.abort_on_exception = true
33
+ ts << t
34
+ end
35
+
36
+ ts.each { |t| t.join }
37
+ end
38
+ end
39
+ end
40
+
41
+ 100.times do |i|
42
+ context "in a multi-threaded scenario B (take #{i})" do
43
+ let(:n) { 20 }
44
+
45
+ it "works correctly" do
46
+ ts = []
47
+
48
+ n.times do
49
+ t = Thread.new do
50
+ 3.times do
51
+ @connection.with_channel do |ch|
52
+ x = ch.topic('bunny.stress.topics.t2', durable: false)
53
+ end
54
+ end
55
+ end
56
+ t.abort_on_exception = true
57
+ ts << t
58
+ end
59
+
60
+ ts.each { |t| t.join }
61
+ end
62
+ end
63
+ end
64
+ end