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.
- checksums.yaml +5 -5
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/.gitignore +7 -1
- data/.rspec +1 -3
- data/.travis.yml +21 -14
- data/CONTRIBUTING.md +132 -0
- data/ChangeLog.md +887 -1
- data/Gemfile +13 -13
- data/LICENSE +1 -1
- data/README.md +46 -60
- data/Rakefile +54 -0
- data/bunny.gemspec +5 -11
- data/docker-compose.yml +28 -0
- data/docker/Dockerfile +24 -0
- data/docker/apt/preferences.d/erlang +3 -0
- data/docker/apt/sources.list.d/bintray.rabbitmq.list +2 -0
- data/docker/docker-entrypoint.sh +26 -0
- data/docker/rabbitmq.conf +29 -0
- data/examples/connection/automatic_recovery_with_basic_get.rb +1 -1
- data/examples/connection/automatic_recovery_with_client_named_queues.rb +1 -1
- data/examples/connection/automatic_recovery_with_multiple_consumers.rb +1 -1
- data/examples/connection/automatic_recovery_with_republishing.rb +1 -1
- data/examples/connection/automatic_recovery_with_server_named_queues.rb +1 -1
- data/examples/connection/channel_level_exception.rb +1 -9
- data/examples/connection/disabled_automatic_recovery.rb +1 -1
- data/examples/connection/heartbeat.rb +1 -1
- data/examples/consumers/high_and_low_priority.rb +1 -1
- data/examples/guides/extensions/alternate_exchange.rb +2 -0
- data/examples/guides/extensions/basic_nack.rb +1 -1
- data/examples/guides/extensions/dead_letter_exchange.rb +1 -1
- data/examples/guides/getting_started/hello_world.rb +2 -0
- data/examples/guides/getting_started/weathr.rb +2 -0
- data/examples/guides/queues/one_off_consumer.rb +2 -0
- data/examples/guides/queues/redeliveries.rb +4 -2
- data/lib/bunny.rb +8 -4
- data/lib/bunny/channel.rb +268 -153
- data/lib/bunny/channel_id_allocator.rb +6 -4
- data/lib/bunny/concurrent/continuation_queue.rb +34 -13
- data/lib/bunny/consumer_work_pool.rb +34 -6
- data/lib/bunny/cruby/socket.rb +48 -21
- data/lib/bunny/cruby/ssl_socket.rb +65 -4
- data/lib/bunny/exceptions.rb +25 -4
- data/lib/bunny/exchange.rb +24 -28
- data/lib/bunny/get_response.rb +1 -1
- data/lib/bunny/heartbeat_sender.rb +3 -2
- data/lib/bunny/jruby/socket.rb +23 -6
- data/lib/bunny/jruby/ssl_socket.rb +5 -0
- data/lib/bunny/queue.rb +31 -22
- data/lib/bunny/reader_loop.rb +31 -18
- data/lib/bunny/session.rb +448 -159
- data/lib/bunny/test_kit.rb +14 -0
- data/lib/bunny/timeout.rb +1 -12
- data/lib/bunny/transport.rb +205 -98
- data/lib/bunny/version.rb +1 -1
- data/repl +1 -1
- data/spec/config/enabled_plugins +1 -0
- data/spec/config/rabbitmq.conf +13 -0
- data/spec/higher_level_api/integration/basic_ack_spec.rb +175 -16
- data/spec/higher_level_api/integration/basic_cancel_spec.rb +77 -11
- data/spec/higher_level_api/integration/basic_consume_spec.rb +60 -55
- data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +6 -6
- data/spec/higher_level_api/integration/basic_get_spec.rb +31 -7
- data/spec/higher_level_api/integration/basic_nack_spec.rb +22 -19
- data/spec/higher_level_api/integration/basic_publish_spec.rb +11 -100
- data/spec/higher_level_api/integration/basic_qos_spec.rb +32 -4
- data/spec/higher_level_api/integration/basic_reject_spec.rb +94 -16
- data/spec/higher_level_api/integration/basic_return_spec.rb +4 -4
- data/spec/higher_level_api/integration/channel_close_spec.rb +51 -10
- data/spec/higher_level_api/integration/channel_open_spec.rb +12 -12
- data/spec/higher_level_api/integration/connection_recovery_spec.rb +424 -221
- data/spec/higher_level_api/integration/connection_spec.rb +300 -126
- data/spec/higher_level_api/integration/connection_stop_spec.rb +31 -19
- data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +17 -17
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +34 -11
- data/spec/higher_level_api/integration/exchange_bind_spec.rb +5 -5
- data/spec/higher_level_api/integration/exchange_declare_spec.rb +32 -31
- data/spec/higher_level_api/integration/exchange_delete_spec.rb +12 -12
- data/spec/higher_level_api/integration/exchange_unbind_spec.rb +5 -5
- data/spec/higher_level_api/integration/exclusive_queue_spec.rb +5 -5
- data/spec/higher_level_api/integration/heartbeat_spec.rb +26 -8
- data/spec/higher_level_api/integration/message_properties_access_spec.rb +49 -49
- data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +2 -2
- data/spec/higher_level_api/integration/publisher_confirms_spec.rb +156 -42
- data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +19 -19
- data/spec/higher_level_api/integration/queue_bind_spec.rb +23 -23
- data/spec/higher_level_api/integration/queue_declare_spec.rb +129 -34
- data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
- data/spec/higher_level_api/integration/queue_purge_spec.rb +5 -5
- data/spec/higher_level_api/integration/queue_unbind_spec.rb +6 -6
- data/spec/higher_level_api/integration/read_only_consumer_spec.rb +9 -9
- data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +10 -10
- data/spec/higher_level_api/integration/tls_connection_spec.rb +224 -89
- data/spec/higher_level_api/integration/toxiproxy_spec.rb +76 -0
- data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
- data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
- data/spec/higher_level_api/integration/with_channel_spec.rb +2 -2
- data/spec/issues/issue100_spec.rb +11 -11
- data/spec/issues/issue141_spec.rb +13 -14
- data/spec/issues/issue202_spec.rb +1 -1
- data/spec/issues/issue224_spec.rb +40 -0
- data/spec/issues/issue465_spec.rb +32 -0
- data/spec/issues/issue549_spec.rb +30 -0
- data/spec/issues/issue78_spec.rb +21 -24
- data/spec/issues/issue83_spec.rb +5 -6
- data/spec/issues/issue97_spec.rb +44 -45
- data/spec/lower_level_api/integration/basic_cancel_spec.rb +15 -16
- data/spec/lower_level_api/integration/basic_consume_spec.rb +20 -21
- data/spec/spec_helper.rb +8 -26
- data/spec/stress/channel_close_stress_spec.rb +64 -0
- data/spec/stress/channel_open_stress_spec.rb +15 -9
- data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +7 -7
- data/spec/stress/concurrent_consumers_stress_spec.rb +18 -16
- data/spec/stress/concurrent_publishers_stress_spec.rb +16 -19
- data/spec/stress/connection_open_close_spec.rb +9 -9
- data/spec/stress/merry_go_round_spec.rb +105 -0
- data/spec/tls/client_key.pem +49 -25
- data/spec/tls/generate-server-cert.sh +8 -0
- data/spec/tls/server-openssl.cnf +10 -0
- data/spec/tls/server.csr +16 -0
- data/spec/tls/server_key.pem +49 -25
- data/spec/toxiproxy_helper.rb +28 -0
- data/spec/unit/bunny_spec.rb +5 -5
- data/spec/unit/concurrent/atomic_fixnum_spec.rb +6 -6
- data/spec/unit/concurrent/condition_spec.rb +8 -8
- data/spec/unit/concurrent/linked_continuation_queue_spec.rb +2 -2
- data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +16 -16
- data/spec/unit/exchange_recovery_spec.rb +39 -0
- data/spec/unit/version_delivery_tag_spec.rb +3 -3
- metadata +65 -47
- data/.ruby-version +0 -1
- data/lib/bunny/compatibility.rb +0 -24
- data/lib/bunny/system_timer.rb +0 -20
- data/spec/compatibility/queue_declare_spec.rb +0 -44
- data/spec/compatibility/queue_declare_with_default_channel_spec.rb +0 -33
- data/spec/higher_level_api/integration/basic_recover_spec.rb +0 -18
- data/spec/higher_level_api/integration/confirm_select_spec.rb +0 -19
- data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +0 -50
- data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
- data/spec/stress/long_running_consumer_spec.rb +0 -83
- data/spec/tls/cacert.pem +0 -18
- data/spec/tls/client_cert.pem +0 -18
- data/spec/tls/server_cert.pem +0 -18
- 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.
|
28
|
-
session.host.
|
29
|
-
session.port.
|
30
|
-
session.ssl
|
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.
|
41
|
-
session.port.
|
42
|
-
session.vhost.
|
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
|
-
|
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.
|
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.
|
67
|
+
expect(conn).to be_connected
|
69
68
|
|
70
|
-
conn.server_properties.
|
71
|
-
conn.server_capabilities.
|
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"].
|
76
|
-
props["platform"].
|
77
|
-
props["version"].
|
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,333 +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(:
|
85
|
+
conn = described_class.new(connection_timeout: 5)
|
87
86
|
conn.start
|
88
|
-
conn.
|
87
|
+
expect(conn).to be_connected
|
89
88
|
|
90
|
-
conn.server_properties.
|
91
|
-
conn.server_capabilities.
|
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"].
|
96
|
-
props["platform"].
|
97
|
-
props["version"].
|
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 :
|
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(:
|
109
|
+
described_class.new(hostname: host)
|
111
110
|
end
|
112
111
|
|
113
112
|
it "uses hostname = 127.0.0.1" do
|
114
|
-
subject.host.
|
115
|
-
subject.hostname.
|
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.
|
118
|
+
expect(subject.port).to eq port
|
120
119
|
end
|
121
120
|
|
122
121
|
it "uses username = guest" do
|
123
|
-
subject.username.
|
122
|
+
expect(subject.username).to eq username
|
124
123
|
end
|
125
124
|
end
|
126
125
|
|
127
|
-
context "initialized with :
|
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(:
|
132
|
+
let(:subject) { described_class.new(hostname: host) }
|
134
133
|
|
135
134
|
it "uses hostname = localhost" do
|
136
|
-
subject.host.
|
137
|
-
subject.hostname.
|
135
|
+
expect(subject.host).to eq host
|
136
|
+
expect(subject.hostname).to eq host
|
137
|
+
end
|
138
|
+
|
139
|
+
it "uses port 5672" do
|
140
|
+
expect(subject.port).to eq port
|
141
|
+
end
|
142
|
+
|
143
|
+
it "uses username = guest" do
|
144
|
+
expect(subject.username).to eq username
|
145
|
+
expect(subject.user).to eq username
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "initialized with a list of hosts" do
|
150
|
+
after :each do
|
151
|
+
subject.close if subject.open?
|
152
|
+
end
|
153
|
+
|
154
|
+
let(:host) { "192.168.1.10" }
|
155
|
+
let(:hosts) { [host] }
|
156
|
+
let(:subject) { described_class.new(hosts: hosts) }
|
157
|
+
|
158
|
+
it "uses hostname = 192.168.1.10" do
|
159
|
+
expect(subject.host).to eq host
|
160
|
+
expect(subject.hostname).to eq host
|
161
|
+
end
|
162
|
+
|
163
|
+
it "uses port 5672" do
|
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
|
191
|
+
end
|
192
|
+
|
193
|
+
it "uses username = guest" do
|
194
|
+
expect(subject.username).to eq username
|
195
|
+
expect(subject.user).to eq username
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
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
|
138
238
|
end
|
139
239
|
|
140
240
|
it "uses port 5672" do
|
141
|
-
subject.port.
|
241
|
+
expect(subject.port).to eq 5672
|
142
242
|
end
|
143
243
|
|
144
244
|
it "uses username = guest" do
|
145
|
-
subject.username.
|
146
|
-
subject.user.
|
245
|
+
expect(subject.username).to eq username
|
246
|
+
expect(subject.user).to eq username
|
147
247
|
end
|
148
248
|
end
|
149
249
|
|
150
|
-
context "initialized with :
|
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
|
151
302
|
after :each do
|
152
303
|
subject.close if subject.open?
|
153
304
|
end
|
154
305
|
|
155
306
|
let(:channel_max) { 1024 }
|
156
|
-
let(:subject) { described_class.new(:
|
307
|
+
let(:subject) { described_class.new(channel_max: channel_max) }
|
157
308
|
|
158
309
|
# this assumes RabbitMQ has no lower value configured. In 3.2
|
159
310
|
# it is 0 (no limit) by default and 1024 is still a fairly low value
|
160
311
|
# for future releases. MK.
|
161
312
|
it "negotiates channel max to be 1024" do
|
162
313
|
subject.start
|
163
|
-
subject.channel_max.
|
314
|
+
expect(subject.channel_max).to eq channel_max
|
164
315
|
|
165
316
|
subject.close
|
166
317
|
end
|
167
318
|
end
|
168
319
|
|
169
|
-
context "initialized with :
|
320
|
+
context "initialized with ssl: true" do
|
170
321
|
let(:subject) do
|
171
|
-
described_class.new(:
|
172
|
-
:
|
173
|
-
:
|
174
|
-
:
|
175
|
-
:
|
176
|
-
:
|
177
|
-
:
|
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"])
|
178
329
|
end
|
179
330
|
|
180
331
|
it "uses TLS port" do
|
181
|
-
subject.port.
|
332
|
+
expect(subject.port).to eq tls_port
|
182
333
|
end
|
183
334
|
end
|
184
335
|
|
185
|
-
context "initialized with :
|
336
|
+
context "initialized with tls: true" do
|
186
337
|
let(:subject) do
|
187
|
-
described_class.new(:
|
188
|
-
:
|
189
|
-
:
|
190
|
-
:
|
191
|
-
:
|
192
|
-
:
|
193
|
-
:
|
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"])
|
194
345
|
end
|
195
346
|
|
196
347
|
it "uses TLS port" do
|
197
|
-
subject.port.
|
348
|
+
expect(subject.port).to eq tls_port
|
198
349
|
end
|
199
350
|
end
|
200
351
|
end
|
201
352
|
|
202
|
-
|
203
|
-
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
|
204
354
|
after :each do
|
205
355
|
subject.close if subject.open?
|
206
356
|
end
|
207
357
|
|
208
358
|
let(:host) { "127.0.0.1" }
|
209
|
-
# see ./bin/ci/before_build
|
359
|
+
# see ./bin/ci/before_build
|
210
360
|
let(:username) { "bunny_gem" }
|
211
361
|
let(:password) { "bunny_password" }
|
212
362
|
let(:vhost) { "bunny_testbed" }
|
213
363
|
|
214
364
|
subject do
|
215
|
-
described_class.new(:
|
365
|
+
described_class.new(hostname: host, username: username, password: password, virtual_host: vhost)
|
216
366
|
end
|
217
367
|
|
218
368
|
it "successfully connects" do
|
219
369
|
5.times { subject.start }
|
220
|
-
subject.
|
370
|
+
expect(subject).to be_connected
|
221
371
|
|
222
|
-
subject.server_properties.
|
223
|
-
subject.server_capabilities.
|
372
|
+
expect(subject.server_properties).not_to be_nil
|
373
|
+
expect(subject.server_capabilities).not_to be_nil
|
224
374
|
|
225
375
|
props = subject.server_properties
|
226
376
|
|
227
|
-
props["product"].
|
228
|
-
props["platform"].
|
229
|
-
props["version"].
|
377
|
+
expect(props["product"]).not_to be_nil
|
378
|
+
expect(props["platform"]).not_to be_nil
|
379
|
+
expect(props["version"]).not_to be_nil
|
230
380
|
end
|
231
381
|
|
232
382
|
it "uses hostname = 127.0.0.1" do
|
233
|
-
subject.host.
|
234
|
-
subject.hostname.
|
383
|
+
expect(subject.host).to eq host
|
384
|
+
expect(subject.hostname).to eq host
|
235
385
|
end
|
236
386
|
|
237
387
|
it "uses port 5672" do
|
238
|
-
subject.port.
|
388
|
+
expect(subject.port).to eq port
|
239
389
|
end
|
240
390
|
|
241
391
|
it "uses provided vhost" do
|
242
|
-
subject.vhost.
|
243
|
-
subject.virtual_host.
|
392
|
+
expect(subject.vhost).to eq vhost
|
393
|
+
expect(subject.virtual_host).to eq vhost
|
244
394
|
end
|
245
395
|
|
246
396
|
it "uses provided username" do
|
247
|
-
subject.username.
|
397
|
+
expect(subject.username).to eq username
|
248
398
|
end
|
249
399
|
|
250
400
|
it "uses provided password" do
|
251
|
-
subject.password.
|
401
|
+
expect(subject.password).to eq password
|
252
402
|
end
|
253
403
|
end
|
254
404
|
|
255
|
-
|
256
|
-
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
|
257
406
|
after :each do
|
258
407
|
subject.close if subject.open?
|
259
408
|
end
|
260
409
|
|
261
410
|
let(:host) { "127.0.0.1" }
|
262
|
-
# see ./bin/ci/before_build
|
411
|
+
# see ./bin/ci/before_build
|
263
412
|
let(:username) { "bunny_gem" }
|
264
413
|
let(:password) { "bunny_password" }
|
265
414
|
let(:vhost) { "bunny_testbed" }
|
266
415
|
|
267
416
|
subject do
|
268
|
-
described_class.new(:
|
417
|
+
described_class.new(hostname: host, username: username, password: password, vhost: vhost)
|
269
418
|
end
|
270
419
|
|
271
420
|
it "successfully connects" do
|
272
421
|
subject.start
|
273
|
-
subject.
|
422
|
+
expect(subject).to be_connected
|
274
423
|
|
275
|
-
subject.server_properties.
|
276
|
-
subject.server_capabilities.
|
424
|
+
expect(subject.server_properties).not_to be_nil
|
425
|
+
expect(subject.server_capabilities).not_to be_nil
|
277
426
|
|
278
427
|
props = subject.server_properties
|
279
428
|
|
280
|
-
props["product"].
|
281
|
-
props["platform"].
|
282
|
-
props["version"].
|
429
|
+
expect(props["product"]).not_to be_nil
|
430
|
+
expect(props["platform"]).not_to be_nil
|
431
|
+
expect(props["version"]).not_to be_nil
|
283
432
|
end
|
284
433
|
|
285
434
|
it "uses hostname = 127.0.0.1" do
|
286
|
-
subject.host.
|
287
|
-
subject.hostname.
|
435
|
+
expect(subject.host).to eq host
|
436
|
+
expect(subject.hostname).to eq host
|
288
437
|
end
|
289
438
|
|
290
439
|
it "uses port 5672" do
|
291
|
-
subject.port.
|
440
|
+
expect(subject.port).to eq port
|
292
441
|
end
|
293
442
|
|
294
443
|
it "uses provided username" do
|
295
|
-
subject.username.
|
444
|
+
expect(subject.username).to eq username
|
296
445
|
end
|
297
446
|
|
298
447
|
it "uses provided password" do
|
299
|
-
subject.password.
|
448
|
+
expect(subject.password).to eq password
|
300
449
|
end
|
301
450
|
end
|
302
451
|
|
303
|
-
|
304
|
-
|
305
|
-
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
|
306
453
|
after :each do
|
307
454
|
subject.close if subject.open?
|
308
455
|
end
|
309
456
|
|
310
457
|
let(:host) { "127.0.0.1" }
|
311
|
-
# see ./bin/ci/before_build
|
458
|
+
# see ./bin/ci/before_build
|
312
459
|
let(:username) { "bunny_gem" }
|
313
460
|
let(:password) { "bunny_password" }
|
314
461
|
let(:vhost) { "bunny_testbed" }
|
315
462
|
let(:interval) { 1 }
|
316
463
|
|
317
464
|
subject do
|
318
|
-
described_class.new(:
|
465
|
+
described_class.new(hostname: host, username: username, password: password, vhost: vhost, heartbeat_timeout: interval)
|
319
466
|
end
|
320
467
|
|
321
468
|
it "successfully connects" do
|
322
469
|
subject.start
|
323
|
-
subject.
|
470
|
+
expect(subject).to be_connected
|
324
471
|
|
325
|
-
subject.server_properties.
|
326
|
-
subject.server_capabilities.
|
472
|
+
expect(subject.server_properties).not_to be_nil
|
473
|
+
expect(subject.server_capabilities).not_to be_nil
|
327
474
|
|
328
475
|
props = subject.server_properties
|
329
476
|
|
330
|
-
props["product"].
|
331
|
-
props["platform"].
|
332
|
-
props["version"].
|
333
|
-
props["capabilities"].
|
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
|
334
481
|
|
335
482
|
# this is negotiated with RabbitMQ, so we need to
|
336
483
|
# establish the connection first
|
337
|
-
subject.heartbeat.
|
484
|
+
expect(subject.heartbeat).to eq interval
|
338
485
|
end
|
339
486
|
end
|
340
487
|
|
341
|
-
|
342
|
-
|
343
|
-
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
|
344
489
|
let(:host) { "127.0.0.1" }
|
345
|
-
# see ./bin/ci/before_build
|
490
|
+
# see ./bin/ci/before_build
|
346
491
|
let(:username) { "bunny_gem#{Time.now.to_i}" }
|
347
492
|
let(:password) { "sdjkfhsdf8ysd8fy8" }
|
348
493
|
let(:vhost) { "___sd89aysd98789" }
|
349
494
|
|
350
495
|
subject do
|
351
|
-
described_class.new(:
|
496
|
+
described_class.new(hostname: host, username: username, password: password, vhost: vhost)
|
352
497
|
end
|
353
498
|
|
354
499
|
it "fails to connect" do
|
355
|
-
|
500
|
+
expect do
|
356
501
|
subject.start
|
357
|
-
end.
|
502
|
+
end.to raise_error(Bunny::PossibleAuthenticationFailureError)
|
358
503
|
end
|
359
504
|
|
360
505
|
it "uses provided username" do
|
361
|
-
subject.username.
|
506
|
+
expect(subject.username).to eq username
|
362
507
|
end
|
363
508
|
|
364
509
|
it "uses provided password" do
|
365
|
-
subject.password.
|
510
|
+
expect(subject.password).to eq password
|
366
511
|
end
|
367
512
|
end
|
368
513
|
|
369
|
-
|
370
514
|
context "initialized with unreachable host or port" do
|
371
515
|
it "fails to connect" do
|
372
|
-
|
373
|
-
c = described_class.new(:
|
516
|
+
expect do
|
517
|
+
c = described_class.new(port: 38000)
|
374
518
|
c.start
|
375
|
-
end.
|
519
|
+
end.to raise_error(Bunny::TCPConnectionFailed)
|
376
520
|
end
|
377
521
|
|
378
522
|
it "is not connected" do
|
379
523
|
begin
|
380
|
-
c = described_class.new(:
|
524
|
+
c = described_class.new(port: 38000)
|
381
525
|
c.start
|
382
526
|
rescue Bunny::TCPConnectionFailed => e
|
383
527
|
true
|
384
528
|
end
|
385
529
|
|
386
|
-
subject.status.
|
530
|
+
expect(subject.status).to eq :not_connected
|
387
531
|
end
|
388
532
|
|
389
533
|
it "is not open" do
|
390
534
|
begin
|
391
|
-
c = described_class.new(:
|
535
|
+
c = described_class.new(port: 38000)
|
392
536
|
c.start
|
393
537
|
rescue Bunny::TCPConnectionFailed => e
|
394
538
|
true
|
395
539
|
end
|
396
540
|
|
397
|
-
subject.
|
541
|
+
expect(subject).not_to be_open
|
398
542
|
end
|
399
543
|
end
|
400
544
|
|
401
|
-
|
402
545
|
context "initialized with a custom logger object" do
|
403
546
|
let(:io) { StringIO.new }
|
404
547
|
let(:logger) { ::Logger.new(io) }
|
405
548
|
|
406
549
|
it "uses provided logger" do
|
407
|
-
conn = described_class.new(:
|
550
|
+
conn = described_class.new(logger: logger)
|
408
551
|
conn.start
|
409
552
|
|
410
|
-
io.string.length.
|
553
|
+
expect(io.string.length).to be > 100
|
411
554
|
|
412
555
|
conn.close
|
413
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
|
414
588
|
end
|
415
589
|
end
|