bunny 1.7.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 (141) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE.md +18 -0
  3. data/.gitignore +6 -1
  4. data/.rspec +1 -3
  5. data/.travis.yml +21 -14
  6. data/CONTRIBUTING.md +132 -0
  7. data/ChangeLog.md +745 -1
  8. data/Gemfile +13 -13
  9. data/LICENSE +1 -1
  10. data/README.md +41 -75
  11. data/Rakefile +54 -0
  12. data/bunny.gemspec +4 -10
  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/getting_started/hello_world.rb +2 -0
  30. data/examples/guides/getting_started/weathr.rb +2 -0
  31. data/examples/guides/queues/one_off_consumer.rb +2 -0
  32. data/examples/guides/queues/redeliveries.rb +2 -0
  33. data/lib/bunny.rb +6 -2
  34. data/lib/bunny/channel.rb +192 -109
  35. data/lib/bunny/channel_id_allocator.rb +6 -4
  36. data/lib/bunny/concurrent/continuation_queue.rb +34 -13
  37. data/lib/bunny/consumer_work_pool.rb +34 -6
  38. data/lib/bunny/cruby/socket.rb +29 -16
  39. data/lib/bunny/cruby/ssl_socket.rb +20 -7
  40. data/lib/bunny/exceptions.rb +7 -1
  41. data/lib/bunny/exchange.rb +11 -7
  42. data/lib/bunny/get_response.rb +1 -1
  43. data/lib/bunny/heartbeat_sender.rb +3 -2
  44. data/lib/bunny/jruby/socket.rb +23 -6
  45. data/lib/bunny/jruby/ssl_socket.rb +5 -0
  46. data/lib/bunny/queue.rb +12 -10
  47. data/lib/bunny/reader_loop.rb +31 -18
  48. data/lib/bunny/session.rb +389 -134
  49. data/lib/bunny/test_kit.rb +14 -0
  50. data/lib/bunny/timeout.rb +1 -12
  51. data/lib/bunny/transport.rb +114 -67
  52. data/lib/bunny/version.rb +1 -1
  53. data/repl +1 -1
  54. data/spec/config/rabbitmq.conf +13 -0
  55. data/spec/higher_level_api/integration/basic_ack_spec.rb +154 -22
  56. data/spec/higher_level_api/integration/basic_cancel_spec.rb +77 -11
  57. data/spec/higher_level_api/integration/basic_consume_spec.rb +60 -55
  58. data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +6 -6
  59. data/spec/higher_level_api/integration/basic_get_spec.rb +31 -7
  60. data/spec/higher_level_api/integration/basic_nack_spec.rb +22 -19
  61. data/spec/higher_level_api/integration/basic_publish_spec.rb +11 -100
  62. data/spec/higher_level_api/integration/basic_qos_spec.rb +32 -4
  63. data/spec/higher_level_api/integration/basic_reject_spec.rb +94 -16
  64. data/spec/higher_level_api/integration/basic_return_spec.rb +4 -4
  65. data/spec/higher_level_api/integration/channel_close_spec.rb +51 -10
  66. data/spec/higher_level_api/integration/channel_open_spec.rb +12 -12
  67. data/spec/higher_level_api/integration/connection_recovery_spec.rb +412 -286
  68. data/spec/higher_level_api/integration/connection_spec.rb +284 -134
  69. data/spec/higher_level_api/integration/connection_stop_spec.rb +31 -19
  70. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +17 -17
  71. data/spec/higher_level_api/integration/dead_lettering_spec.rb +14 -14
  72. data/spec/higher_level_api/integration/exchange_bind_spec.rb +5 -5
  73. data/spec/higher_level_api/integration/exchange_declare_spec.rb +32 -31
  74. data/spec/higher_level_api/integration/exchange_delete_spec.rb +12 -12
  75. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +5 -5
  76. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +5 -5
  77. data/spec/higher_level_api/integration/heartbeat_spec.rb +4 -4
  78. data/spec/higher_level_api/integration/message_properties_access_spec.rb +49 -49
  79. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +2 -2
  80. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +92 -27
  81. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +19 -19
  82. data/spec/higher_level_api/integration/queue_bind_spec.rb +23 -23
  83. data/spec/higher_level_api/integration/queue_declare_spec.rb +129 -34
  84. data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
  85. data/spec/higher_level_api/integration/queue_purge_spec.rb +5 -5
  86. data/spec/higher_level_api/integration/queue_unbind_spec.rb +6 -6
  87. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +9 -9
  88. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +10 -10
  89. data/spec/higher_level_api/integration/tls_connection_spec.rb +218 -112
  90. data/spec/higher_level_api/integration/toxiproxy_spec.rb +76 -0
  91. data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
  92. data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
  93. data/spec/higher_level_api/integration/with_channel_spec.rb +2 -2
  94. data/spec/issues/issue100_spec.rb +11 -12
  95. data/spec/issues/issue141_spec.rb +13 -14
  96. data/spec/issues/issue202_spec.rb +1 -1
  97. data/spec/issues/issue224_spec.rb +5 -5
  98. data/spec/issues/issue465_spec.rb +32 -0
  99. data/spec/issues/issue549_spec.rb +30 -0
  100. data/spec/issues/issue78_spec.rb +21 -24
  101. data/spec/issues/issue83_spec.rb +5 -6
  102. data/spec/issues/issue97_spec.rb +44 -45
  103. data/spec/lower_level_api/integration/basic_cancel_spec.rb +15 -16
  104. data/spec/lower_level_api/integration/basic_consume_spec.rb +20 -21
  105. data/spec/spec_helper.rb +2 -19
  106. data/spec/stress/channel_close_stress_spec.rb +3 -3
  107. data/spec/stress/channel_open_stress_spec.rb +4 -4
  108. data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +7 -7
  109. data/spec/stress/concurrent_consumers_stress_spec.rb +18 -16
  110. data/spec/stress/concurrent_publishers_stress_spec.rb +16 -19
  111. data/spec/stress/connection_open_close_spec.rb +9 -9
  112. data/spec/stress/merry_go_round_spec.rb +105 -0
  113. data/spec/tls/ca_certificate.pem +27 -16
  114. data/spec/tls/ca_key.pem +52 -27
  115. data/spec/tls/client_certificate.pem +27 -16
  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_certificate.pem +27 -16
  121. data/spec/tls/server_key.pem +49 -25
  122. data/spec/toxiproxy_helper.rb +28 -0
  123. data/spec/unit/bunny_spec.rb +5 -5
  124. data/spec/unit/concurrent/atomic_fixnum_spec.rb +6 -6
  125. data/spec/unit/concurrent/condition_spec.rb +8 -8
  126. data/spec/unit/concurrent/linked_continuation_queue_spec.rb +2 -2
  127. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +16 -16
  128. data/spec/unit/exchange_recovery_spec.rb +39 -0
  129. data/spec/unit/version_delivery_tag_spec.rb +3 -3
  130. metadata +42 -35
  131. data/lib/bunny/system_timer.rb +0 -20
  132. data/spec/config/rabbitmq.config +0 -18
  133. data/spec/higher_level_api/integration/basic_recover_spec.rb +0 -18
  134. data/spec/higher_level_api/integration/confirm_select_spec.rb +0 -19
  135. data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +0 -50
  136. data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
  137. data/spec/stress/long_running_consumer_spec.rb +0 -83
  138. data/spec/tls/cacert.pem +0 -18
  139. data/spec/tls/client_cert.pem +0 -18
  140. data/spec/tls/server_cert.pem +0 -18
  141. data/spec/unit/system_timer_spec.rb +0 -10
@@ -1,5 +1,9 @@
1
1
  require "spec_helper"
2
2
 
3
+ def local_hostname
4
+ ENV.fetch("BUNNY_RABBITMQ_HOSTNAME", "127.0.0.1")
5
+ end
6
+
3
7
  describe Bunny::Session do
4
8
  let(:port) { AMQ::Protocol::DEFAULT_PORT }
5
9
  let(:username) { "guest" }
@@ -19,45 +23,40 @@ describe Bunny::Session do
19
23
  end
20
24
  end
21
25
 
22
-
23
26
  it "handles amqp:// URIs w/o path part" do
24
27
  session = described_class.new("amqp://127.0.0.1")
25
28
  session.start
26
29
 
27
- session.vhost.should == "/"
28
- session.host.should == "127.0.0.1"
29
- session.port.should == 5672
30
- session.ssl?.should be_false
30
+ expect(session.vhost).to eq "/"
31
+ expect(session.host).to eq "127.0.0.1"
32
+ expect(session.port).to eq 5672
33
+ expect(session.ssl?).to eq false
31
34
 
32
35
  session.close
33
36
  end
34
37
 
35
-
36
38
  context "when URI ends in a slash" do
37
39
  it "parses vhost as an empty string" do
38
40
  session = described_class.new("amqp://127.0.0.1/")
39
41
 
40
- session.hostname.should == "127.0.0.1"
41
- session.port.should == 5672
42
- session.vhost.should == ""
42
+ expect(session.hostname).to eq "127.0.0.1"
43
+ expect(session.port).to eq 5672
44
+ expect(session.vhost).to eq ""
43
45
  end
44
46
  end
45
47
 
46
48
  context "when URI is amqp://dev.rabbitmq.com/a/path/with/slashes" do
47
49
  it "raises an ArgumentError" do
48
- lambda { described_class.new("amqp://dev.rabbitmq.com/a/path/with/slashes") }.should raise_error(ArgumentError)
50
+ expect { described_class.new("amqp://dev.rabbitmq.com/a/path/with/slashes") }.to raise_error(ArgumentError)
49
51
  end
50
52
  end
51
53
  end
52
54
 
53
-
54
-
55
-
56
55
  context "initialized with all defaults" do
57
56
  it "provides a way to fine tune socket options" do
58
57
  conn = Bunny.new
59
58
  conn.start
60
- conn.transport.socket.should respond_to(:setsockopt)
59
+ expect(conn.transport.socket).to respond_to(:setsockopt)
61
60
 
62
61
  conn.close
63
62
  end
@@ -65,16 +64,16 @@ describe Bunny::Session do
65
64
  it "successfully negotiates the connection" do
66
65
  conn = Bunny.new
67
66
  conn.start
68
- conn.should be_connected
67
+ expect(conn).to be_connected
69
68
 
70
- conn.server_properties.should_not be_nil
71
- conn.server_capabilities.should_not be_nil
69
+ expect(conn.server_properties).not_to be_nil
70
+ expect(conn.server_capabilities).not_to be_nil
72
71
 
73
72
  props = conn.server_properties
74
73
 
75
- props["product"].should_not be_nil
76
- props["platform"].should_not be_nil
77
- props["version"].should_not be_nil
74
+ expect(props["product"]).not_to be_nil
75
+ expect(props["platform"]).not_to be_nil
76
+ expect(props["version"]).not_to be_nil
78
77
 
79
78
  conn.close
80
79
  end
@@ -83,357 +82,508 @@ describe Bunny::Session do
83
82
  unless ENV["CI"]
84
83
  context "initialized with TCP connection timeout = 5" do
85
84
  it "successfully connects" do
86
- conn = described_class.new(:connection_timeout => 5)
85
+ conn = described_class.new(connection_timeout: 5)
87
86
  conn.start
88
- conn.should be_connected
87
+ expect(conn).to be_connected
89
88
 
90
- conn.server_properties.should_not be_nil
91
- conn.server_capabilities.should_not be_nil
89
+ expect(conn.server_properties).not_to be_nil
90
+ expect(conn.server_capabilities).not_to be_nil
92
91
 
93
92
  props = conn.server_properties
94
93
 
95
- props["product"].should_not be_nil
96
- props["platform"].should_not be_nil
97
- props["version"].should_not be_nil
94
+ expect(props["product"]).not_to be_nil
95
+ expect(props["platform"]).not_to be_nil
96
+ expect(props["version"]).not_to be_nil
98
97
 
99
98
  conn.close
100
99
  end
101
100
  end
102
101
 
103
- context "initialized with :host => 127.0.0.1" do
102
+ context "initialized with hostname: 127.0.0.1" do
104
103
  after :each do
105
104
  subject.close if subject.open?
106
105
  end
107
106
 
108
107
  let(:host) { "127.0.0.1" }
109
108
  subject do
110
- described_class.new(:host => host)
109
+ described_class.new(hostname: host)
111
110
  end
112
111
 
113
112
  it "uses hostname = 127.0.0.1" do
114
- subject.host.should == host
115
- subject.hostname.should == host
113
+ expect(subject.host).to eq host
114
+ expect(subject.hostname).to eq host
116
115
  end
117
116
 
118
117
  it "uses port 5672" do
119
- subject.port.should == port
118
+ expect(subject.port).to eq port
120
119
  end
121
120
 
122
121
  it "uses username = guest" do
123
- subject.username.should == username
122
+ expect(subject.username).to eq username
124
123
  end
125
124
  end
126
125
 
127
- context "initialized with :hostname => localhost" do
126
+ context "initialized with hostname: localhost" do
128
127
  after :each do
129
128
  subject.close if subject.open?
130
129
  end
131
130
 
132
131
  let(:host) { "localhost" }
133
- let(:subject) { described_class.new(:hostname => host) }
132
+ let(:subject) { described_class.new(hostname: host) }
134
133
 
135
134
  it "uses hostname = localhost" do
136
- subject.host.should == host
137
- subject.hostname.should == host
135
+ expect(subject.host).to eq host
136
+ expect(subject.hostname).to eq host
138
137
  end
139
138
 
140
139
  it "uses port 5672" do
141
- subject.port.should == port
140
+ expect(subject.port).to eq port
142
141
  end
143
142
 
144
143
  it "uses username = guest" do
145
- subject.username.should == username
146
- subject.user.should == username
144
+ expect(subject.username).to eq username
145
+ expect(subject.user).to eq username
147
146
  end
148
147
  end
149
148
 
150
- context "initialized with :hosts => [...]" do
149
+ context "initialized with a list of hosts" do
151
150
  after :each do
152
151
  subject.close if subject.open?
153
152
  end
154
153
 
155
154
  let(:host) { "192.168.1.10" }
156
155
  let(:hosts) { [host] }
157
- let(:subject) { described_class.new(:hosts => hosts) }
156
+ let(:subject) { described_class.new(hosts: hosts) }
158
157
 
159
- it "uses hostname = localhost" do
160
- subject.host.should == host
161
- subject.hostname.should == host
158
+ it "uses hostname = 192.168.1.10" do
159
+ expect(subject.host).to eq host
160
+ expect(subject.hostname).to eq host
162
161
  end
163
162
 
164
163
  it "uses port 5672" do
165
- subject.port.should == port
164
+ expect(subject.port).to eq port
165
+ end
166
+
167
+ it "uses username = guest" do
168
+ expect(subject.username).to eq username
169
+ expect(subject.user).to eq username
170
+ end
171
+ end
172
+
173
+ context "initialized with a list of addresses" do
174
+ after :each do
175
+ subject.close if subject.open?
176
+ end
177
+
178
+ let(:host) { "192.168.1.10" }
179
+ let(:port) { 5673 }
180
+ let(:address) { "#{host}:#{port}" }
181
+ let(:addresses) { [address] }
182
+ let(:subject) { described_class.new(addresses: addresses) }
183
+
184
+ it "uses hostname = 192.168.1.10" do
185
+ expect(subject.host).to eq host
186
+ expect(subject.hostname).to eq host
187
+ end
188
+
189
+ it "uses port 5673" do
190
+ expect(subject.port).to eq port
166
191
  end
167
192
 
168
193
  it "uses username = guest" do
169
- subject.username.should == username
170
- subject.user.should == username
194
+ expect(subject.username).to eq username
195
+ expect(subject.user).to eq username
171
196
  end
172
197
  end
173
198
 
174
- context "initialized with :channel_max => 4096" do
199
+ context "initialized with addresses: [...] with quoted IPv6 hostnames" do
200
+ after :each do
201
+ subject.close if subject.open?
202
+ end
203
+
204
+ let(:host) { "[2001:db8:85a3:8d3:1319:8a2e:370:7348]" }
205
+ let(:port) { 5673 }
206
+ let(:address) { "#{host}:#{port}" }
207
+ let(:addresses) { [address] }
208
+ let(:subject) { described_class.new(addresses: addresses) }
209
+
210
+ it "uses correct hostname" do
211
+ expect(subject.host).to eq host
212
+ expect(subject.hostname).to eq host
213
+ end
214
+
215
+ it "uses port 5673" do
216
+ expect(subject.port).to eq port
217
+ end
218
+
219
+ it "uses username = guest" do
220
+ expect(subject.username).to eq username
221
+ expect(subject.user).to eq username
222
+ end
223
+ end
224
+
225
+ context "initialized with addresses: [...] with quoted IPv6 hostnames without ports" do
226
+ after :each do
227
+ subject.close if subject.open?
228
+ end
229
+
230
+ let(:host) { "[2001:db8:85a3:8d3:1319:8a2e:370:7348]" }
231
+ let(:address) { host }
232
+ let(:addresses) { [address] }
233
+ let(:subject) { described_class.new(addresses: addresses) }
234
+
235
+ it "uses correct hostname" do
236
+ expect(subject.host).to eq host
237
+ expect(subject.hostname).to eq host
238
+ end
239
+
240
+ it "uses port 5672" do
241
+ expect(subject.port).to eq 5672
242
+ end
243
+
244
+ it "uses username = guest" do
245
+ expect(subject.username).to eq username
246
+ expect(subject.user).to eq username
247
+ end
248
+ end
249
+
250
+ context "initialized with addresses: [...] with an quoted IPv6 hostnames" do
251
+ after :each do
252
+ subject.close if subject.open?
253
+ end
254
+
255
+ let(:host) { "2001:db8:85a3:8d3:1319:8a2e:370:7348" }
256
+ let(:port) { 5673 }
257
+ let(:address) { "#{host}:#{port}" }
258
+ let(:addresses) { [address] }
259
+ let(:subject) { described_class.new(addresses: addresses) }
260
+
261
+ it "fails to correctly parse the host (and emits a warning)" do
262
+ expect(subject.host).to eq "2001"
263
+ expect(subject.hostname).to eq "2001"
264
+ end
265
+
266
+ it "fails to correctly parse the port (and emits a warning)" do
267
+ expect(subject.port).to eq 0
268
+ end
269
+
270
+ it "uses username = guest" do
271
+ expect(subject.username).to eq username
272
+ expect(subject.user).to eq username
273
+ end
274
+ end
275
+
276
+ context "initialized with conflicting hosts and addresses" do
277
+ let(:host) { "192.168.1.10" }
278
+ let(:port) { 5673 }
279
+ let(:address) { "#{host}:#{port}" }
280
+ let(:io) { StringIO.new }
281
+ let(:logger) { ::Logger.new(io) }
282
+
283
+ it "raises an argument error when there is are hosts and an address" do
284
+ expect { described_class.new(addresses: [address], hosts: [host]) }.to raise_error(ArgumentError)
285
+ end
286
+
287
+ it "logs a warning when there is a single host and an array" do
288
+ described_class.new(addresses: [address], host: host, logger: logger)
289
+ expect(io.string).to match(/both a host and an array of hosts/)
290
+ end
291
+
292
+ it "converts hosts in addresses to addresses" do
293
+ strategy = Proc.new { |addresses| addresses }
294
+ session = described_class.new(addresses: [address,host ], hosts_shuffle_strategy: strategy)
295
+ strategy = Proc.new { |addresses| addresses }
296
+
297
+ expect(session.to_s).to include 'addresses=[192.168.1.10:5673,192.168.1.10:5672]'
298
+ end
299
+ end
300
+
301
+ context "initialized with channel_max: 4096" do
175
302
  after :each do
176
303
  subject.close if subject.open?
177
304
  end
178
305
 
179
306
  let(:channel_max) { 1024 }
180
- let(:subject) { described_class.new(:channel_max => channel_max) }
307
+ let(:subject) { described_class.new(channel_max: channel_max) }
181
308
 
182
309
  # this assumes RabbitMQ has no lower value configured. In 3.2
183
310
  # it is 0 (no limit) by default and 1024 is still a fairly low value
184
311
  # for future releases. MK.
185
312
  it "negotiates channel max to be 1024" do
186
313
  subject.start
187
- subject.channel_max.should == channel_max
314
+ expect(subject.channel_max).to eq channel_max
188
315
 
189
316
  subject.close
190
317
  end
191
318
  end
192
319
 
193
- context "initialized with :ssl => true" do
320
+ context "initialized with ssl: true" do
194
321
  let(:subject) do
195
- described_class.new(:user => "bunny_gem",
196
- :password => "bunny_password",
197
- :vhost => "bunny_testbed",
198
- :ssl => true,
199
- :ssl_cert => "spec/tls/client_cert.pem",
200
- :ssl_key => "spec/tls/client_key.pem",
201
- :ssl_ca_certificates => ["./spec/tls/cacert.pem"])
322
+ described_class.new(username: "bunny_gem",
323
+ password: "bunny_password",
324
+ vhost: "bunny_testbed",
325
+ ssl: true,
326
+ ssl_cert: "spec/tls/client_certificate.pem",
327
+ ssl_key: "spec/tls/client_key.pem",
328
+ ssl_ca_certificates: ["./spec/tls/ca_certificate.pem"])
202
329
  end
203
330
 
204
331
  it "uses TLS port" do
205
- subject.port.should == tls_port
332
+ expect(subject.port).to eq tls_port
206
333
  end
207
334
  end
208
335
 
209
- context "initialized with :tls => true" do
336
+ context "initialized with tls: true" do
210
337
  let(:subject) do
211
- described_class.new(:user => "bunny_gem",
212
- :password => "bunny_password",
213
- :vhost => "bunny_testbed",
214
- :tls => true,
215
- :tls_cert => "spec/tls/client_cert.pem",
216
- :tls_key => "spec/tls/client_key.pem",
217
- :tls_ca_certificates => ["./spec/tls/cacert.pem"])
338
+ described_class.new(username: "bunny_gem",
339
+ password: "bunny_password",
340
+ vhost: "bunny_testbed",
341
+ tls: true,
342
+ tls_cert: "spec/tls/client_certificate.pem",
343
+ tls_key: "spec/tls/client_key.pem",
344
+ tls_ca_certificates: ["./spec/tls/ca_certificate.pem"])
218
345
  end
219
346
 
220
347
  it "uses TLS port" do
221
- subject.port.should == tls_port
348
+ expect(subject.port).to eq tls_port
222
349
  end
223
350
  end
224
351
  end
225
352
 
226
-
227
- context "initialized with :host => 127.0.0.1 and non-default credentials" do
353
+ context "initialized with hostname: 127.0.0.1 and non-default credentials" do
228
354
  after :each do
229
355
  subject.close if subject.open?
230
356
  end
231
357
 
232
358
  let(:host) { "127.0.0.1" }
233
- # see ./bin/ci/before_build.sh
359
+ # see ./bin/ci/before_build
234
360
  let(:username) { "bunny_gem" }
235
361
  let(:password) { "bunny_password" }
236
362
  let(:vhost) { "bunny_testbed" }
237
363
 
238
364
  subject do
239
- described_class.new(:hostname => host, :username => username, :password => password, :virtual_host => vhost)
365
+ described_class.new(hostname: host, username: username, password: password, virtual_host: vhost)
240
366
  end
241
367
 
242
368
  it "successfully connects" do
243
369
  5.times { subject.start }
244
- subject.should be_connected
370
+ expect(subject).to be_connected
245
371
 
246
- subject.server_properties.should_not be_nil
247
- subject.server_capabilities.should_not be_nil
372
+ expect(subject.server_properties).not_to be_nil
373
+ expect(subject.server_capabilities).not_to be_nil
248
374
 
249
375
  props = subject.server_properties
250
376
 
251
- props["product"].should_not be_nil
252
- props["platform"].should_not be_nil
253
- props["version"].should_not be_nil
377
+ expect(props["product"]).not_to be_nil
378
+ expect(props["platform"]).not_to be_nil
379
+ expect(props["version"]).not_to be_nil
254
380
  end
255
381
 
256
382
  it "uses hostname = 127.0.0.1" do
257
- subject.host.should == host
258
- subject.hostname.should == host
383
+ expect(subject.host).to eq host
384
+ expect(subject.hostname).to eq host
259
385
  end
260
386
 
261
387
  it "uses port 5672" do
262
- subject.port.should == port
388
+ expect(subject.port).to eq port
263
389
  end
264
390
 
265
391
  it "uses provided vhost" do
266
- subject.vhost.should == vhost
267
- subject.virtual_host.should == vhost
392
+ expect(subject.vhost).to eq vhost
393
+ expect(subject.virtual_host).to eq vhost
268
394
  end
269
395
 
270
396
  it "uses provided username" do
271
- subject.username.should == username
397
+ expect(subject.username).to eq username
272
398
  end
273
399
 
274
400
  it "uses provided password" do
275
- subject.password.should == password
401
+ expect(subject.password).to eq password
276
402
  end
277
403
  end
278
404
 
279
-
280
- context "initialized with :host => 127.0.0.1 and non-default credentials (take 2)" do
405
+ context "initialized with hostname: 127.0.0.1 and non-default credentials (take 2)" do
281
406
  after :each do
282
407
  subject.close if subject.open?
283
408
  end
284
409
 
285
410
  let(:host) { "127.0.0.1" }
286
- # see ./bin/ci/before_build.sh
411
+ # see ./bin/ci/before_build
287
412
  let(:username) { "bunny_gem" }
288
413
  let(:password) { "bunny_password" }
289
414
  let(:vhost) { "bunny_testbed" }
290
415
 
291
416
  subject do
292
- described_class.new(:hostname => host, :user => username, :pass => password, :vhost => vhost)
417
+ described_class.new(hostname: host, username: username, password: password, vhost: vhost)
293
418
  end
294
419
 
295
420
  it "successfully connects" do
296
421
  subject.start
297
- subject.should be_connected
422
+ expect(subject).to be_connected
298
423
 
299
- subject.server_properties.should_not be_nil
300
- subject.server_capabilities.should_not be_nil
424
+ expect(subject.server_properties).not_to be_nil
425
+ expect(subject.server_capabilities).not_to be_nil
301
426
 
302
427
  props = subject.server_properties
303
428
 
304
- props["product"].should_not be_nil
305
- props["platform"].should_not be_nil
306
- props["version"].should_not be_nil
429
+ expect(props["product"]).not_to be_nil
430
+ expect(props["platform"]).not_to be_nil
431
+ expect(props["version"]).not_to be_nil
307
432
  end
308
433
 
309
434
  it "uses hostname = 127.0.0.1" do
310
- subject.host.should == host
311
- subject.hostname.should == host
435
+ expect(subject.host).to eq host
436
+ expect(subject.hostname).to eq host
312
437
  end
313
438
 
314
439
  it "uses port 5672" do
315
- subject.port.should == port
440
+ expect(subject.port).to eq port
316
441
  end
317
442
 
318
443
  it "uses provided username" do
319
- subject.username.should == username
444
+ expect(subject.username).to eq username
320
445
  end
321
446
 
322
447
  it "uses provided password" do
323
- subject.password.should == password
448
+ expect(subject.password).to eq password
324
449
  end
325
450
  end
326
451
 
327
-
328
-
329
- context "initialized with :host => 127.0.0.1 and non-default credentials (take 2)" do
452
+ context "initialized with hostname: 127.0.0.1 and non-default credentials (take 2)" do
330
453
  after :each do
331
454
  subject.close if subject.open?
332
455
  end
333
456
 
334
457
  let(:host) { "127.0.0.1" }
335
- # see ./bin/ci/before_build.sh
458
+ # see ./bin/ci/before_build
336
459
  let(:username) { "bunny_gem" }
337
460
  let(:password) { "bunny_password" }
338
461
  let(:vhost) { "bunny_testbed" }
339
462
  let(:interval) { 1 }
340
463
 
341
464
  subject do
342
- described_class.new(:hostname => host, :user => username, :pass => password, :vhost => vhost, :heartbeat_interval => interval)
465
+ described_class.new(hostname: host, username: username, password: password, vhost: vhost, heartbeat_timeout: interval)
343
466
  end
344
467
 
345
468
  it "successfully connects" do
346
469
  subject.start
347
- subject.should be_connected
470
+ expect(subject).to be_connected
348
471
 
349
- subject.server_properties.should_not be_nil
350
- subject.server_capabilities.should_not be_nil
472
+ expect(subject.server_properties).not_to be_nil
473
+ expect(subject.server_capabilities).not_to be_nil
351
474
 
352
475
  props = subject.server_properties
353
476
 
354
- props["product"].should_not be_nil
355
- props["platform"].should_not be_nil
356
- props["version"].should_not be_nil
357
- props["capabilities"].should_not be_nil
477
+ expect(props["product"]).not_to be_nil
478
+ expect(props["platform"]).not_to be_nil
479
+ expect(props["version"]).not_to be_nil
480
+ expect(props["capabilities"]).not_to be_nil
358
481
 
359
482
  # this is negotiated with RabbitMQ, so we need to
360
483
  # establish the connection first
361
- subject.heartbeat.should == interval
484
+ expect(subject.heartbeat).to eq interval
362
485
  end
363
486
  end
364
487
 
365
-
366
-
367
- context "initialized with :host => 127.0.0.1 and INVALID credentials" do
488
+ context "initialized with hostname: 127.0.0.1 and INVALID credentials" do
368
489
  let(:host) { "127.0.0.1" }
369
- # see ./bin/ci/before_build.sh
490
+ # see ./bin/ci/before_build
370
491
  let(:username) { "bunny_gem#{Time.now.to_i}" }
371
492
  let(:password) { "sdjkfhsdf8ysd8fy8" }
372
493
  let(:vhost) { "___sd89aysd98789" }
373
494
 
374
495
  subject do
375
- described_class.new(:hostname => host, :user => username, :pass => password, :vhost => vhost)
496
+ described_class.new(hostname: host, username: username, password: password, vhost: vhost)
376
497
  end
377
498
 
378
499
  it "fails to connect" do
379
- lambda do
500
+ expect do
380
501
  subject.start
381
- end.should raise_error(Bunny::PossibleAuthenticationFailureError)
502
+ end.to raise_error(Bunny::PossibleAuthenticationFailureError)
382
503
  end
383
504
 
384
505
  it "uses provided username" do
385
- subject.username.should == username
506
+ expect(subject.username).to eq username
386
507
  end
387
508
 
388
509
  it "uses provided password" do
389
- subject.password.should == password
510
+ expect(subject.password).to eq password
390
511
  end
391
512
  end
392
513
 
393
-
394
514
  context "initialized with unreachable host or port" do
395
515
  it "fails to connect" do
396
- lambda do
397
- c = described_class.new(:port => 38000)
516
+ expect do
517
+ c = described_class.new(port: 38000)
398
518
  c.start
399
- end.should raise_error(Bunny::TCPConnectionFailed)
519
+ end.to raise_error(Bunny::TCPConnectionFailed)
400
520
  end
401
521
 
402
522
  it "is not connected" do
403
523
  begin
404
- c = described_class.new(:port => 38000)
524
+ c = described_class.new(port: 38000)
405
525
  c.start
406
526
  rescue Bunny::TCPConnectionFailed => e
407
527
  true
408
528
  end
409
529
 
410
- subject.status.should == :not_connected
530
+ expect(subject.status).to eq :not_connected
411
531
  end
412
532
 
413
533
  it "is not open" do
414
534
  begin
415
- c = described_class.new(:port => 38000)
535
+ c = described_class.new(port: 38000)
416
536
  c.start
417
537
  rescue Bunny::TCPConnectionFailed => e
418
538
  true
419
539
  end
420
540
 
421
- subject.should_not be_open
541
+ expect(subject).not_to be_open
422
542
  end
423
543
  end
424
544
 
425
-
426
545
  context "initialized with a custom logger object" do
427
546
  let(:io) { StringIO.new }
428
547
  let(:logger) { ::Logger.new(io) }
429
548
 
430
549
  it "uses provided logger" do
431
- conn = described_class.new(:hostname => "localhost", :logger => logger)
550
+ conn = described_class.new(logger: logger)
432
551
  conn.start
433
552
 
434
- io.string.length.should > 100
553
+ expect(io.string.length).to be > 100
435
554
 
436
555
  conn.close
437
556
  end
557
+
558
+ it "doesn't reassign the logger's progname attribute" do
559
+ expect(logger).not_to receive(:progname=)
560
+ described_class.new(logger: logger)
561
+ end
562
+ end
563
+
564
+ context "initialized with a custom connection name" do
565
+ it "uses provided connection name with default connection string" do
566
+ conn = Bunny.new(connection_name: 'test_name')
567
+
568
+ expect(conn.connection_name).to eq 'test_name'
569
+ end
570
+
571
+ it "uses provided connection name from client property hash" do
572
+ conn = Bunny.new(client_properties: {connection_name: 'cp/test_name'})
573
+
574
+ expect(conn.connection_name).to eq 'cp/test_name'
575
+ end
576
+
577
+ it "uses provided connection name with custom connection string" do
578
+ conn = Bunny.new('amqp://guest:guest@rabbitmq:5672', connection_name: 'test_name3')
579
+
580
+ expect(conn.connection_name).to eq 'test_name3'
581
+ end
582
+
583
+ it "uses provided connection name with hash options" do
584
+ conn = Bunny.new(user: 'user', password: 'p455w0rd', connection_name: 'test_name4')
585
+
586
+ expect(conn.connection_name).to eq 'test_name4'
587
+ end
438
588
  end
439
589
  end