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.
- checksums.yaml +5 -5
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/.gitignore +6 -1
- data/.rspec +1 -3
- data/.travis.yml +21 -14
- data/CONTRIBUTING.md +132 -0
- data/ChangeLog.md +745 -1
- data/Gemfile +13 -13
- data/LICENSE +1 -1
- data/README.md +41 -75
- data/Rakefile +54 -0
- data/bunny.gemspec +4 -10
- 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/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 +2 -0
- data/lib/bunny.rb +6 -2
- data/lib/bunny/channel.rb +192 -109
- 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 +29 -16
- data/lib/bunny/cruby/ssl_socket.rb +20 -7
- data/lib/bunny/exceptions.rb +7 -1
- data/lib/bunny/exchange.rb +11 -7
- 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 +12 -10
- data/lib/bunny/reader_loop.rb +31 -18
- data/lib/bunny/session.rb +389 -134
- data/lib/bunny/test_kit.rb +14 -0
- data/lib/bunny/timeout.rb +1 -12
- data/lib/bunny/transport.rb +114 -67
- data/lib/bunny/version.rb +1 -1
- data/repl +1 -1
- data/spec/config/rabbitmq.conf +13 -0
- data/spec/higher_level_api/integration/basic_ack_spec.rb +154 -22
- 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 +412 -286
- data/spec/higher_level_api/integration/connection_spec.rb +284 -134
- 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 +14 -14
- 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 +4 -4
- 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 +92 -27
- 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 +218 -112
- 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 -12
- data/spec/issues/issue141_spec.rb +13 -14
- data/spec/issues/issue202_spec.rb +1 -1
- data/spec/issues/issue224_spec.rb +5 -5
- 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 +2 -19
- data/spec/stress/channel_close_stress_spec.rb +3 -3
- data/spec/stress/channel_open_stress_spec.rb +4 -4
- 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/ca_certificate.pem +27 -16
- data/spec/tls/ca_key.pem +52 -27
- data/spec/tls/client_certificate.pem +27 -16
- 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_certificate.pem +27 -16
- 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 +42 -35
- data/lib/bunny/system_timer.rb +0 -20
- data/spec/config/rabbitmq.config +0 -18
- 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,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(:
|
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
|
138
137
|
end
|
139
138
|
|
140
139
|
it "uses port 5672" do
|
141
|
-
subject.port.
|
140
|
+
expect(subject.port).to eq port
|
142
141
|
end
|
143
142
|
|
144
143
|
it "uses username = guest" do
|
145
|
-
subject.username.
|
146
|
-
subject.user.
|
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
|
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(:
|
156
|
+
let(:subject) { described_class.new(hosts: hosts) }
|
158
157
|
|
159
|
-
it "uses hostname =
|
160
|
-
subject.host.
|
161
|
-
subject.hostname.
|
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.
|
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.
|
170
|
-
subject.user.
|
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 :
|
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(:
|
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.
|
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 :
|
320
|
+
context "initialized with ssl: true" do
|
194
321
|
let(:subject) do
|
195
|
-
described_class.new(:
|
196
|
-
:
|
197
|
-
:
|
198
|
-
:
|
199
|
-
:
|
200
|
-
:
|
201
|
-
:
|
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.
|
332
|
+
expect(subject.port).to eq tls_port
|
206
333
|
end
|
207
334
|
end
|
208
335
|
|
209
|
-
context "initialized with :
|
336
|
+
context "initialized with tls: true" do
|
210
337
|
let(:subject) do
|
211
|
-
described_class.new(:
|
212
|
-
:
|
213
|
-
:
|
214
|
-
:
|
215
|
-
:
|
216
|
-
:
|
217
|
-
:
|
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.
|
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
|
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(:
|
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.
|
370
|
+
expect(subject).to be_connected
|
245
371
|
|
246
|
-
subject.server_properties.
|
247
|
-
subject.server_capabilities.
|
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"].
|
252
|
-
props["platform"].
|
253
|
-
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
|
254
380
|
end
|
255
381
|
|
256
382
|
it "uses hostname = 127.0.0.1" do
|
257
|
-
subject.host.
|
258
|
-
subject.hostname.
|
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.
|
388
|
+
expect(subject.port).to eq port
|
263
389
|
end
|
264
390
|
|
265
391
|
it "uses provided vhost" do
|
266
|
-
subject.vhost.
|
267
|
-
subject.virtual_host.
|
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.
|
397
|
+
expect(subject.username).to eq username
|
272
398
|
end
|
273
399
|
|
274
400
|
it "uses provided password" do
|
275
|
-
subject.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
|
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(:
|
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.
|
422
|
+
expect(subject).to be_connected
|
298
423
|
|
299
|
-
subject.server_properties.
|
300
|
-
subject.server_capabilities.
|
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"].
|
305
|
-
props["platform"].
|
306
|
-
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
|
307
432
|
end
|
308
433
|
|
309
434
|
it "uses hostname = 127.0.0.1" do
|
310
|
-
subject.host.
|
311
|
-
subject.hostname.
|
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.
|
440
|
+
expect(subject.port).to eq port
|
316
441
|
end
|
317
442
|
|
318
443
|
it "uses provided username" do
|
319
|
-
subject.username.
|
444
|
+
expect(subject.username).to eq username
|
320
445
|
end
|
321
446
|
|
322
447
|
it "uses provided password" do
|
323
|
-
subject.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
|
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(:
|
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.
|
470
|
+
expect(subject).to be_connected
|
348
471
|
|
349
|
-
subject.server_properties.
|
350
|
-
subject.server_capabilities.
|
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"].
|
355
|
-
props["platform"].
|
356
|
-
props["version"].
|
357
|
-
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
|
358
481
|
|
359
482
|
# this is negotiated with RabbitMQ, so we need to
|
360
483
|
# establish the connection first
|
361
|
-
subject.heartbeat.
|
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
|
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(:
|
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
|
-
|
500
|
+
expect do
|
380
501
|
subject.start
|
381
|
-
end.
|
502
|
+
end.to raise_error(Bunny::PossibleAuthenticationFailureError)
|
382
503
|
end
|
383
504
|
|
384
505
|
it "uses provided username" do
|
385
|
-
subject.username.
|
506
|
+
expect(subject.username).to eq username
|
386
507
|
end
|
387
508
|
|
388
509
|
it "uses provided password" do
|
389
|
-
subject.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
|
-
|
397
|
-
c = described_class.new(:
|
516
|
+
expect do
|
517
|
+
c = described_class.new(port: 38000)
|
398
518
|
c.start
|
399
|
-
end.
|
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(:
|
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.
|
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(:
|
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.
|
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(:
|
550
|
+
conn = described_class.new(logger: logger)
|
432
551
|
conn.start
|
433
552
|
|
434
|
-
io.string.length.
|
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
|