bunny 2.17.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -11
  3. data/lib/bunny/channel.rb +1 -1
  4. data/lib/bunny/session.rb +22 -4
  5. data/lib/bunny/transport.rb +7 -6
  6. data/lib/bunny/version.rb +1 -1
  7. data/spec/higher_level_api/integration/basic_consume_spec.rb +14 -6
  8. data/spec/higher_level_api/integration/tls_connection_spec.rb +25 -32
  9. data/spec/issues/issue609_spec.rb +84 -0
  10. data/spec/lower_level_api/integration/basic_cancel_spec.rb +1 -1
  11. data/spec/lower_level_api/integration/basic_consume_spec.rb +8 -8
  12. metadata +28 -87
  13. data/.github/ISSUE_TEMPLATE.md +0 -18
  14. data/.gitignore +0 -28
  15. data/.rspec +0 -1
  16. data/.travis.yml +0 -33
  17. data/.yardopts +0 -8
  18. data/CONTRIBUTING.md +0 -132
  19. data/ChangeLog.md +0 -2129
  20. data/Gemfile +0 -55
  21. data/LICENSE +0 -21
  22. data/Rakefile +0 -54
  23. data/benchmarks/basic_publish/with_128K_messages.rb +0 -35
  24. data/benchmarks/basic_publish/with_1k_messages.rb +0 -35
  25. data/benchmarks/basic_publish/with_4K_messages.rb +0 -35
  26. data/benchmarks/basic_publish/with_64K_messages.rb +0 -35
  27. data/benchmarks/channel_open.rb +0 -28
  28. data/benchmarks/mutex_and_monitor.rb +0 -42
  29. data/benchmarks/queue_declare.rb +0 -29
  30. data/benchmarks/queue_declare_and_bind.rb +0 -29
  31. data/benchmarks/queue_declare_bind_and_delete.rb +0 -29
  32. data/benchmarks/synchronized_sorted_set.rb +0 -53
  33. data/benchmarks/write_vs_write_nonblock.rb +0 -49
  34. data/bunny.gemspec +0 -34
  35. data/docker/Dockerfile +0 -24
  36. data/docker/apt/preferences.d/erlang +0 -3
  37. data/docker/apt/sources.list.d/bintray.rabbitmq.list +0 -2
  38. data/docker/docker-entrypoint.sh +0 -26
  39. data/docker/rabbitmq.conf +0 -29
  40. data/docker-compose.yml +0 -28
  41. data/examples/connection/authentication_failure.rb +0 -16
  42. data/examples/connection/automatic_recovery_with_basic_get.rb +0 -40
  43. data/examples/connection/automatic_recovery_with_client_named_queues.rb +0 -36
  44. data/examples/connection/automatic_recovery_with_multiple_consumers.rb +0 -46
  45. data/examples/connection/automatic_recovery_with_republishing.rb +0 -109
  46. data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
  47. data/examples/connection/channel_level_exception.rb +0 -27
  48. data/examples/connection/disabled_automatic_recovery.rb +0 -34
  49. data/examples/connection/heartbeat.rb +0 -17
  50. data/examples/connection/manually_reconnecting_consumer.rb +0 -23
  51. data/examples/connection/manually_reconnecting_publisher.rb +0 -28
  52. data/examples/connection/unknown_host.rb +0 -16
  53. data/examples/consumers/high_and_low_priority.rb +0 -50
  54. data/examples/guides/exchanges/direct_exchange_routing.rb +0 -36
  55. data/examples/guides/exchanges/fanout_exchange_routing.rb +0 -28
  56. data/examples/guides/exchanges/headers_exchange_routing.rb +0 -31
  57. data/examples/guides/exchanges/mandatory_messages.rb +0 -30
  58. data/examples/guides/extensions/alternate_exchange.rb +0 -30
  59. data/examples/guides/extensions/basic_nack.rb +0 -33
  60. data/examples/guides/extensions/connection_blocked.rb +0 -35
  61. data/examples/guides/extensions/consumer_cancellation_notification.rb +0 -39
  62. data/examples/guides/extensions/dead_letter_exchange.rb +0 -32
  63. data/examples/guides/extensions/exchange_to_exchange_bindings.rb +0 -29
  64. data/examples/guides/extensions/per_message_ttl.rb +0 -36
  65. data/examples/guides/extensions/per_queue_message_ttl.rb +0 -36
  66. data/examples/guides/extensions/publisher_confirms.rb +0 -28
  67. data/examples/guides/extensions/queue_lease.rb +0 -26
  68. data/examples/guides/extensions/sender_selected_distribution.rb +0 -32
  69. data/examples/guides/getting_started/blabbr.rb +0 -27
  70. data/examples/guides/getting_started/hello_world.rb +0 -22
  71. data/examples/guides/getting_started/weathr.rb +0 -49
  72. data/examples/guides/queues/one_off_consumer.rb +0 -25
  73. data/examples/guides/queues/redeliveries.rb +0 -81
  74. data/profiling/basic_publish/with_4K_messages.rb +0 -33
  75. data/repl +0 -3
  76. data/spec/tls/ca_certificate.pem +0 -29
  77. data/spec/tls/ca_key.pem +0 -52
  78. data/spec/tls/client_certificate.pem +0 -29
  79. data/spec/tls/client_key.pem +0 -51
  80. data/spec/tls/generate-server-cert.sh +0 -8
  81. data/spec/tls/server-openssl.cnf +0 -10
  82. data/spec/tls/server.csr +0 -16
  83. data/spec/tls/server_certificate.pem +0 -29
  84. data/spec/tls/server_key.pem +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f3ba4a5565a42eace00f8789c1be953871d9dc57d42028a94a9dd70a586271e
4
- data.tar.gz: c7d2fdf832b466a27c7ae884e6195729d31a6bf1cb6accde9818c2f72b46cdc6
3
+ metadata.gz: d6de535f1d386dbf46fd89a733c1c44915280af55c3cc3cc56467abe0ead9c24
4
+ data.tar.gz: 6048aea84078fb8995718ed774d9a3956dc91645b24c09382cd54283b444aabe
5
5
  SHA512:
6
- metadata.gz: 26a352492ca652429975e45ec36fad12ebfd3c94e66babb879afb0f09dcec0158affc820f8a29fd07a25d8db6ac9312fd31ebc5b1a3d4c315ecfeeb880a5a8f2
7
- data.tar.gz: 393fa99fb87c7784eccd0f5019fe3668b39064e15935d85f4134c85aa6b138849d0026addb814f49d00f606b9157b78878863c875d2ad6480b17b3053dcb98fb
6
+ metadata.gz: b3575710f81dabf6c116c92c4ac1807a29f0c0bcd1bd5fb35ae1fd9dd468df193efac49d0ad5e77ef04ecc53e97b9b4e13e70f4207972ba0c2335c28afcd6c9b
7
+ data.tar.gz: 8b90dd4da7dab28b529e78cf1282656ca1904432b1017ee5574545c1972315f975d175c718481372604b61796e9ae56b293a342dcba800fa0929e4b80cd7a3c4
data/README.md CHANGED
@@ -47,7 +47,7 @@ Specific examples:
47
47
 
48
48
  Modern Bunny versions support
49
49
 
50
- * CRuby 2.3 through 2.7 (inclusive)
50
+ * CRuby 2.5 through 3.0 (inclusive)
51
51
 
52
52
  Bunny works sufficiently well on JRuby but there are known
53
53
  JRuby bugs in versions prior to JRuby 9000 that cause high CPU burn. JRuby users should
@@ -70,10 +70,8 @@ a stable public API.
70
70
  Change logs per release series:
71
71
 
72
72
  * [master](https://github.com/ruby-amqp/bunny/blob/master/ChangeLog.md)
73
- * [2.16.x](https://github.com/ruby-amqp/bunny/blob/2.16.x-stable/ChangeLog.md)
74
- * [2.15.x](https://github.com/ruby-amqp/bunny/blob/2.15.x-stable/ChangeLog.md)
75
- * [2.14.x](https://github.com/ruby-amqp/bunny/blob/2.14.x-stable/ChangeLog.md)
76
- * [2.13.x](https://github.com/ruby-amqp/bunny/blob/2.13.x-stable/ChangeLog.md)
73
+ * [2.18.x](https://github.com/ruby-amqp/bunny/blob/2.18.x-stable/ChangeLog.md)
74
+ * [2.17.x](https://github.com/ruby-amqp/bunny/blob/2.17.x-stable/ChangeLog.md)
77
75
 
78
76
 
79
77
 
@@ -96,7 +94,7 @@ gem install bunny
96
94
  To use Bunny in a project managed with Bundler:
97
95
 
98
96
  ``` ruby
99
- gem "bunny", ">= 2.16.1"
97
+ gem "bunny", ">= 2.18.0"
100
98
  ```
101
99
 
102
100
 
@@ -116,20 +114,31 @@ conn.start
116
114
 
117
115
  # open a channel
118
116
  ch = conn.create_channel
117
+ ch.confirm_select
119
118
 
120
119
  # declare a queue
121
120
  q = ch.queue("test1")
121
+ q.subscribe(manual_ack: true) do |delivery_info, metadata, payload|
122
+ puts "This is the message: #{payload}"
123
+ # acknowledge the delivery so that RabbitMQ can mark it for deletion
124
+ ch.ack(delivery_info.delivery_tag)
125
+ end
122
126
 
123
127
  # publish a message to the default exchange which then gets routed to this queue
124
128
  q.publish("Hello, everybody!")
125
129
 
126
- # fetch a message from the queue
127
- delivery_info, metadata, payload = q.pop
130
+ # await confirmations from RabbitMQ, see
131
+ # https://www.rabbitmq.com/publishers.html#data-safety for details
132
+ ch.wait_for_confirms
128
133
 
129
- puts "This is the message: #{payload}"
134
+ # give the above consumer some time consume the delivery and print out the message
135
+ sleep 1
130
136
 
137
+ puts "Done"
138
+
139
+ ch.close
131
140
  # close the connection
132
- conn.stop
141
+ conn.close
133
142
  ```
134
143
 
135
144
 
@@ -141,7 +150,7 @@ For a 15 minute tutorial using more practical examples, see [Getting Started wit
141
150
 
142
151
  ### Guides
143
152
 
144
- Other documentation guides are available at [rubybunny.info](http://rubybunny.info):
153
+ Bunny documentation guides are available at [rubybunny.info](http://rubybunny.info):
145
154
 
146
155
  * [Queues and Consumers](http://rubybunny.info/articles/queues.html)
147
156
  * [Exchanges and Publishers](http://rubybunny.info/articles/exchanges.html)
@@ -153,6 +162,16 @@ Other documentation guides are available at [rubybunny.info](http://rubybunny.in
153
162
  * [Using RabbitMQ Extensions with Bunny](http://rubybunny.info/articles/extensions.html)
154
163
  * [Durability and Related Matters](http://rubybunny.info/articles/durability.html)
155
164
 
165
+ Some highly relevant RabbitMQ documentation guides:
166
+
167
+ * [Connections](https://www.rabbitmq.com/connections.html)
168
+ * [Channels](https://www.rabbitmq.com/channels.html)
169
+ * [Queues](https://www.rabbitmq.com/queues.html)
170
+ * [Publishers](https://www.rabbitmq.com/publishers.html)
171
+ * [Consumers](https://www.rabbitmq.com/consumers.html)
172
+ * Data safety: publisher and consumer [Confirmations](https://www.rabbitmq.com/confirms.html)
173
+ * [Production Checklist](https://www.rabbitmq.com/production-checklist.html)
174
+
156
175
  ### API Reference
157
176
 
158
177
  [Bunny API Reference](http://reference.rubybunny.info/).
data/lib/bunny/channel.rb CHANGED
@@ -1789,7 +1789,7 @@ module Bunny
1789
1789
  # @private
1790
1790
  def handle_ack_or_nack(delivery_tag_before_offset, multiple, nack)
1791
1791
  delivery_tag = delivery_tag_before_offset + @delivery_tag_offset
1792
- confirmed_range_start = multiple ? @delivery_tag_offset + 1 : delivery_tag
1792
+ confirmed_range_start = multiple ? @delivery_tag_offset + @unconfirmed_set.min : delivery_tag
1793
1793
  confirmed_range_end = delivery_tag
1794
1794
  confirmed_range = (confirmed_range_start..confirmed_range_end)
1795
1795
 
data/lib/bunny/session.rb CHANGED
@@ -124,6 +124,8 @@ module Bunny
124
124
  # @option connection_string_or_opts [Boolean] :automatically_recover (true) Should automatically recover from network failures?
125
125
  # @option connection_string_or_opts [Integer] :recovery_attempts (nil) Max number of recovery attempts, nil means forever
126
126
  # @option connection_string_or_opts [Integer] :reset_recovery_attempts_after_reconnection (true) Should recovery attempt counter be reset after successful reconnection? When set to false, the attempt counter will last through the entire lifetime of the connection object.
127
+ # @option connection_string_or_opts [Proc] :recovery_attempt_started (nil) Will be called before every connection recovery attempt
128
+ # @option connection_string_or_opts [Proc] :recovery_completed (nil) Will be called after successful connection recovery
127
129
  # @option connection_string_or_opts [Boolean] :recover_from_connection_close (true) Should this connection recover after receiving a server-sent connection.close (e.g. connection was force closed)?
128
130
  # @option connection_string_or_opts [Object] :session_error_handler (Thread.current) Object which responds to #raise that will act as a session error handler. Defaults to Thread.current, which will raise asynchronous exceptions in the thread that created the session.
129
131
  #
@@ -172,7 +174,7 @@ module Bunny
172
174
  @automatically_recover = if opts[:automatically_recover].nil? && opts[:automatic_recovery].nil?
173
175
  true
174
176
  else
175
- opts[:automatically_recover] || opts[:automatic_recovery]
177
+ opts[:automatically_recover] | opts[:automatic_recovery]
176
178
  end
177
179
  @recovering_from_network_failure = false
178
180
  @max_recovery_attempts = opts[:recovery_attempts]
@@ -218,7 +220,9 @@ module Bunny
218
220
  @address_index_mutex = @mutex_impl.new
219
221
 
220
222
  @channels = Hash.new
221
- @recovery_completed = opts[:recovery_completed]
223
+
224
+ @recovery_attempt_started = opts[:recovery_attempt_started]
225
+ @recovery_completed = opts[:recovery_completed]
222
226
 
223
227
  @session_error_handler = opts.fetch(:session_error_handler, Thread.current)
224
228
 
@@ -533,6 +537,18 @@ module Bunny
533
537
  end
534
538
  end
535
539
 
540
+ # Defines a callable (e.g. a block) that will be called
541
+ # before every connection recovery attempt.
542
+ def before_recovery_attempt_starts(&block)
543
+ @recovery_attempt_started = block
544
+ end
545
+
546
+ # Defines a callable (e.g. a block) that will be called
547
+ # after successful connection recovery.
548
+ def after_recovery_completed(&block)
549
+ @recovery_completed = block
550
+ end
551
+
536
552
 
537
553
  #
538
554
  # Implementation
@@ -750,6 +766,7 @@ module Bunny
750
766
  def recover_from_network_failure
751
767
  sleep @network_recovery_interval
752
768
  @logger.debug "Will attempt connection recovery..."
769
+ notify_of_recovery_attempt_start
753
770
 
754
771
  self.initialize_transport
755
772
 
@@ -823,8 +840,9 @@ module Bunny
823
840
  end
824
841
  end
825
842
 
826
- def after_recovery_completed(&block)
827
- @recovery_completed = block
843
+ # @private
844
+ def notify_of_recovery_attempt_start
845
+ @recovery_attempt_started.call if @recovery_attempt_started
828
846
  end
829
847
 
830
848
  # @private
@@ -453,9 +453,9 @@ module Bunny
453
453
  end
454
454
  end
455
455
 
456
- def initialize_tls_context(ctx, opts={})
456
+ def initialize_tls_context(ctx, opts = {})
457
457
  ctx.cert = OpenSSL::X509::Certificate.new(@tls_certificate) if @tls_certificate
458
- ctx.key = OpenSSL::PKey::RSA.new(@tls_key) if @tls_key
458
+ ctx.key = OpenSSL::PKey.read(@tls_key) if @tls_key
459
459
  ctx.cert_store = if @tls_certificate_store
460
460
  @tls_certificate_store
461
461
  else
@@ -463,8 +463,9 @@ module Bunny
463
463
  @tls_ca_certificates = tls_ca_certificates_paths_from(opts)
464
464
  initialize_tls_certificate_store(@tls_ca_certificates)
465
465
  end
466
+ should_silence_warnings = opts.fetch(:tls_silence_warnings, false)
466
467
 
467
- if !@tls_certificate
468
+ if !@tls_certificate && !should_silence_warnings
468
469
  @logger.warn <<-MSG
469
470
  Using TLS but no client certificate is provided. If RabbitMQ is configured to require & verify peer
470
471
  certificate, connection will be rejected. Learn more at https://www.rabbitmq.com/ssl.html
@@ -482,14 +483,14 @@ certificate, connection will be rejected. Learn more at https://www.rabbitmq.com
482
483
  @logger.debug { "Will use peer verification mode #{verify_mode}" }
483
484
  ctx.verify_mode = verify_mode
484
485
 
485
- if !@verify_peer
486
+ if !@verify_peer && !should_silence_warnings
486
487
  @logger.warn <<-MSG
487
488
  Using TLS but peer hostname verification is disabled. This is convenient for local development
488
489
  but prone to man-in-the-middle attacks. Please set verify_peer: true in production. Learn more at https://www.rabbitmq.com/ssl.html
489
490
  MSG
490
491
  end
491
492
 
492
- ssl_version = opts[:tls_protocol] || opts[:ssl_version]
493
+ ssl_version = opts[:tls_protocol] || opts[:ssl_version] || :TLSv1_2
493
494
  ctx.ssl_version = ssl_version if ssl_version
494
495
 
495
496
  ctx
@@ -501,7 +502,7 @@ but prone to man-in-the-middle attacks. Please set verify_peer: true in producti
501
502
  certs.each do |cert|
502
503
  # if it starts with / or C:/ then it's a file path that may or may not
503
504
  # exist (e.g. a default OpenSSL path). MK.
504
- if File.readable?(cert) || cert =~ /^([a-z]:?)?\//i
505
+ if File.readable?(cert) || cert =~ /\A([a-z]:?)?\//i
505
506
  cert_files.push(cert)
506
507
  else
507
508
  cert_inlines.push(cert)
data/lib/bunny/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "2.17.0"
5
+ VERSION = "2.19.0"
6
6
  end
@@ -62,8 +62,10 @@ describe Bunny::Queue, "#subscribe" do
62
62
  x.publish("hello", routing_key: queue_name)
63
63
  end
64
64
 
65
- sleep 1.0
66
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
65
+ sleep 1.5
66
+ 100.times do |i|
67
+ expect(delivery_tags).to include(i + 1)
68
+ end
67
69
 
68
70
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
69
71
 
@@ -95,7 +97,9 @@ describe Bunny::Queue, "#subscribe" do
95
97
  end
96
98
 
97
99
  sleep 1.5
98
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
100
+ 100.times do |i|
101
+ expect(delivery_tags).to include(i + 1)
102
+ end
99
103
 
100
104
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
101
105
 
@@ -305,8 +309,10 @@ describe Bunny::Queue, "#subscribe" do
305
309
  x.publish("hello", routing_key: queue_name)
306
310
  end
307
311
 
308
- sleep 1.0
309
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
312
+ sleep 1.5
313
+ 100.times do |i|
314
+ expect(delivery_tags).to include(i + 1)
315
+ end
310
316
 
311
317
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
312
318
 
@@ -338,7 +344,9 @@ describe Bunny::Queue, "#subscribe" do
338
344
  end
339
345
 
340
346
  sleep 1.5
341
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
347
+ 100.times do |i|
348
+ expect(delivery_tags).to include(i + 1)
349
+ end
342
350
 
343
351
  expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
344
352
 
@@ -39,20 +39,6 @@ def local_hostname
39
39
  ENV.fetch("BUNNY_RABBITMQ_HOSTNAME", "localhost")
40
40
  end
41
41
 
42
- def no_tls12_supported?
43
- not tls12_supported?
44
- end
45
-
46
- def tls12_supported?
47
- begin
48
- ctx = OpenSSL::SSL::SSLContext.new
49
- ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
50
- true
51
- rescue
52
- false
53
- end
54
- end
55
-
56
42
  context "initialized with tls: true", skip: ENV["CI"] do
57
43
  let(:subject) do
58
44
  Bunny.new(
@@ -102,6 +88,7 @@ describe "TLS connection to RabbitMQ with client certificates", skip: ENV["CI"]
102
88
  password: "bunny_password",
103
89
  vhost: "bunny_testbed",
104
90
  tls: true,
91
+ tls_protocol: :TLSv1_2,
105
92
  tls_cert: "#{CERTIFICATE_DIR}/client_certificate.pem",
106
93
  tls_key: "#{CERTIFICATE_DIR}/client_key.pem",
107
94
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
@@ -126,6 +113,7 @@ describe "TLS connection to RabbitMQ without client certificates", skip: ENV["CI
126
113
  password: "bunny_password",
127
114
  vhost: "bunny_testbed",
128
115
  tls: true,
116
+ tls_protocol: :TLSv1_2,
129
117
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
130
118
  verify_peer: false)
131
119
  c.start
@@ -143,6 +131,7 @@ end
143
131
  describe "TLS connection to RabbitMQ with a connection string", skip: ENV["CI"] do
144
132
  let(:subject) do
145
133
  c = Bunny.new("amqps://bunny_gem:bunny_password@#{local_hostname()}/bunny_testbed",
134
+ tls_protocol: :TLSv1_2,
146
135
  tls_cert: "#{CERTIFICATE_DIR}/client_certificate.pem",
147
136
  tls_key: "#{CERTIFICATE_DIR}/client_key.pem",
148
137
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
@@ -179,6 +168,7 @@ describe "TLS connection to RabbitMQ with a connection string and w/o client cer
179
168
  let(:subject) do
180
169
  c = Bunny.new("amqps://bunny_gem:bunny_password@#{local_hostname()}/bunny_testbed",
181
170
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
171
+ tls_protocol: :TLSv1_2,
182
172
  verify_peer: verify_peer)
183
173
  c.start
184
174
  c
@@ -211,19 +201,13 @@ describe "TLS connection to RabbitMQ with a connection string and w/o client cer
211
201
  end
212
202
  end
213
203
 
214
-
215
- describe "TLS connection to RabbitMQ with client certificates provided inline", skip: ENV["CI"] do
204
+ describe "TLS connection to RabbitMQ w/o client certificate", skip: ENV["CI"] do
216
205
  let(:subject) do
217
- c = Bunny.new(
218
- hostname: local_hostname(),
219
- username: "bunny_gem",
220
- password: "bunny_password",
221
- vhost: "bunny_testbed",
222
- tls: true,
223
- tls_cert: File.read("#{CERTIFICATE_DIR}/client_certificate.pem"),
224
- tls_key: File.read("#{CERTIFICATE_DIR}/client_key.pem"),
206
+ c = Bunny.new("amqps://bunny_gem:bunny_password@#{local_hostname()}/bunny_testbed",
225
207
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
226
- verify_peer: false)
208
+ tls_protocol: :TLSv1_2,
209
+ verify_peer: false,
210
+ tls_silence_warnings: should_silence_warnings)
227
211
  c.start
228
212
  c
229
213
  end
@@ -232,10 +216,21 @@ describe "TLS connection to RabbitMQ with client certificates provided inline",
232
216
  subject.close
233
217
  end
234
218
 
235
- include_examples "successful TLS connection"
219
+ context "TLS-related warnings are enabled" do
220
+ let(:should_silence_warnings) { false }
221
+
222
+ include_examples "successful TLS connection"
223
+ end
224
+
225
+ context "TLS-related warnings are silenced" do
226
+ let(:should_silence_warnings) { true }
227
+
228
+ include_examples "successful TLS connection"
229
+ end
236
230
  end
237
231
 
238
- describe "TLS connection to RabbitMQ with tls_version TLSv1.2 specified", skip: ENV["CI"] do
232
+
233
+ describe "TLS connection to RabbitMQ with client certificates provided inline", skip: ENV["CI"] do
239
234
  let(:subject) do
240
235
  c = Bunny.new(
241
236
  hostname: local_hostname(),
@@ -243,8 +238,10 @@ describe "TLS connection to RabbitMQ with tls_version TLSv1.2 specified", skip:
243
238
  password: "bunny_password",
244
239
  vhost: "bunny_testbed",
245
240
  tls: true,
246
- tls_protocol: :TLSv1_2,
241
+ tls_cert: File.read("#{CERTIFICATE_DIR}/client_certificate.pem"),
242
+ tls_key: File.read("#{CERTIFICATE_DIR}/client_key.pem"),
247
243
  tls_ca_certificates: ["#{CERTIFICATE_DIR}/ca_certificate.pem"],
244
+ tls_protocol: :TLSv1_2,
248
245
  verify_peer: false)
249
246
  c.start
250
247
  c
@@ -255,8 +252,4 @@ describe "TLS connection to RabbitMQ with tls_version TLSv1.2 specified", skip:
255
252
  end
256
253
 
257
254
  include_examples "successful TLS connection"
258
-
259
- it "connects using TLSv1.2", skip: no_tls12_supported? do
260
- expect(subject.transport.socket.ssl_version).to eq "TLSv1.2"
261
- end
262
255
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Bunny::Session, 'TLS certificate store' do
6
+ subject { described_class.new tls: true, tls_ca_certificates: [certificate], logger: logger }
7
+
8
+ let(:logger) { Logger.new(io).tap { |l| l.level = :debug } }
9
+ let(:io) { StringIO.new }
10
+
11
+ context 'when a Windows path given' do
12
+ let(:certificate) { 'C:/some/path/cacert.pem' }
13
+
14
+ # skipping actual work with file by Windows path as this spec runs in Linux
15
+ before do
16
+ allow(File).to receive(:readable?).with(certificate).and_return(true)
17
+ allow_any_instance_of(OpenSSL::X509::Store).to receive(:add_file)
18
+ end
19
+
20
+ it 'uses the certificate by path' do
21
+ subject
22
+
23
+ expect(log_content).to include('Using CA certificates at C:/some/path/cacert.pem')
24
+ end
25
+ end
26
+
27
+ context 'when a POSIX path given' do
28
+ let(:certificate) { './spec/tls/ca_certificate.pem' }
29
+
30
+ it 'uses the certificate by path' do
31
+ subject
32
+
33
+ expect(log_content).to include('Using CA certificates at ./spec/tls/ca_certificate.pem')
34
+ end
35
+ end
36
+
37
+ context 'when an inline certificate given' do
38
+ let(:certificate) do
39
+ <<~CERT
40
+ -----BEGIN CERTIFICATE-----
41
+ MIIFUDCCAzigAwIBAgIUSnyXq9nGYlkEvmGK0D/vfDW+B0QwDQYJKoZIhvcNAQEL
42
+ BQAwMTEgMB4GA1UEAwwXVExTR2VuU2VsZlNpZ25lZHRSb290Q0ExDTALBgNVBAcM
43
+ BCQkJCQwHhcNMjEwNDEyMTcwNzIxWhcNMzEwNDEwMTcwNzIxWjAxMSAwHgYDVQQD
44
+ DBdUTFNHZW5TZWxmU2lnbmVkdFJvb3RDQTENMAsGA1UEBwwEJCQkJDCCAiIwDQYJ
45
+ KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKgPkKUIOi3RJZn0j/TkknErop/N1ylp
46
+ qb4A6O9yMjRt7gSui+mouEe6SqcQubhm6n3cQzr0LxmtPO96ShHDUh8SJwzN419Q
47
+ HS4x5IyCm4GMWvj4XPWb0LDVPdgbF9JdDSsv+zJPJ5oCh3wxbGrbzWIdClHE3ERm
48
+ Fx59P4hgT5aa21LuB/Is/U5ybkUdrmYLP6ZiwYhH6A2mdL8VdqI53/tChrimNDcH
49
+ I7dy9gqU75uDVF5DkchELFLPBTOYHS7OPS7sWHw4prQ6X+fZ/YG8Sql0+FAPf3Ro
50
+ h2RSIiaGCLiuKpBjF3zK20ZvV+m6p+sYX3YyY3R9PDTctHYl6IW0iXpXjbStY//+
51
+ bBK56B74+OgRlWRqQDs/xfTDzm3GXRy6N/Z19ghoQYFST1FrHH04lBhoknNiSmRC
52
+ Qf0AuwllLs9p1BLk/yEyoeAjMLA9ZDw0UjAvEaRgIwCFUJ3n2NZ/q+d2bTA00W4z
53
+ 2pw6Hju//kkwWKBpAQBnPWRUhi4R3XDHKTa4lwkTjRzwfiyOM7y0JiPTj96WCKDo
54
+ xIGEXbWwqZi/z7JTsXaxwxTnwC3ySStSz8SwgE4VjyK9DWeuT/4B6RWy+1sPLhOx
55
+ ZXrCdUAd43ZGZp2SOZQrjPG89G3eUtfWQh2gigOabxEJoJmSDQW7LPXDQ64wElE5
56
+ I5vR6XcclCM7AgMBAAGjYDBeMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUUdmmGXiv
57
+ pidfAl85xXxPAFTDnUowHwYDVR0jBBgwFoAUUdmmGXivpidfAl85xXxPAFTDnUow
58
+ DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAobJS8Ej4ZUpqtjWs
59
+ OVWGNXja0HdwuKP/IHmBWkcwrjJmMk5R8kGd+REIvCPz4ngofGMgYXLtj1omNkfh
60
+ FDmUQWP0GRWZFgKCp5kNX+uaQk/KULEYc5W/+vYrpFPwOQi1uruRSyRKMddw3BJa
61
+ I799hskkD8UFEfgHaAhdr9aZikYjCUYX0MIYHWef4e/H/ty/DYnKoGmUmVJEp45g
62
+ JLXOUAQCD1EeZhUqkZddVckCR5oZQIfaJZbXRNKhQKcg9yllvDT2xY9tAty8D+v4
63
+ U/uoVcCbsXvE8BpEUYHuDYvLGutPYPLqTSGVxxTa4P/x/gEd1XlCtEoHThrv2YpF
64
+ O5gME43xtBbwsEvBKWEaGl4hNLjlsTelM7uZsea58aIbs2nhUJQwcBUcugMa/Bxe
65
+ KNgCiJ8M6ESa4FDV75Oe1LFZcC92Ie8zq5JTfvJJdEDqYdgAe05CH53USdRYKFRI
66
+ QejzCS50kRx/wZgrokAXSSyuhXcEDoHqJ46Ufp5hnEVZCytCLRC58adPeBpcrLkN
67
+ b4ZRbtyrZHDFkU/M49OxXUYBVaXztzK/EfkSXP4WHVNLlcb6U/fmlssfTaXu6ovg
68
+ IOKPOq09C3id77JsXRwEb7hkkXpTp5i63bmVvCKRDKtHMUfxfnRiZkuu79fB4y8v
69
+ eYEXqywYlmGZite4N3qb3qQnyGw=
70
+ -----END CERTIFICATE-----
71
+ CERT
72
+ end
73
+
74
+ it 'uses the inline certificate' do
75
+ subject
76
+
77
+ expect(log_content).to include('Using 1 inline CA certificates')
78
+ end
79
+ end
80
+
81
+ def log_content
82
+ io.tap(&:rewind).read
83
+ end
84
+ end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel, "#basic_cancel" do
4
4
  before(:all) do
5
- @connection = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
5
+ @connection = Bunny.new(:user => "bunny_gem", password: "bunny_password", :vhost => "bunny_testbed")
6
6
  @connection.start
7
7
  end
8
8
 
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel, "#basic_consume" do
4
4
  before(:all) do
5
- @connection = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
5
+ @connection = Bunny.new(:user => "bunny_gem", password: "bunny_password", :vhost => "bunny_testbed")
6
6
  @connection.start
7
7
  end
8
8
 
@@ -12,7 +12,7 @@ describe Bunny::Channel, "#basic_consume" do
12
12
 
13
13
  it "returns basic.consume-ok when it is received" do
14
14
  ch = @connection.create_channel
15
- q = ch.queue("", :exclusive => true)
15
+ q = ch.queue("", exclusive: true)
16
16
 
17
17
  consume_ok = ch.basic_consume(q)
18
18
  expect(consume_ok).to be_instance_of AMQ::Protocol::Basic::ConsumeOk
@@ -23,7 +23,7 @@ describe Bunny::Channel, "#basic_consume" do
23
23
 
24
24
  it "carries server-generated consumer tag with basic.consume-ok" do
25
25
  ch = @connection.create_channel
26
- q = ch.queue("", :exclusive => true)
26
+ q = ch.queue("", exclusive: true)
27
27
 
28
28
  consume_ok = ch.basic_consume(q, "")
29
29
  expect(consume_ok.consumer_tag).to match /amq\.ctag.*/
@@ -51,13 +51,13 @@ describe Bunny::Channel, "#basic_consume" do
51
51
 
52
52
  ch = @connection.create_channel
53
53
  x = ch.default_exchange
54
- x.publish("hello", :routing_key => queue_name)
54
+ x.publish("hello", routing_key: queue_name)
55
55
 
56
56
  sleep 0.7
57
57
  expect(delivered_keys).to include queue_name
58
58
  expect(delivered_data).to include "hello"
59
59
 
60
- expect(ch.queue(queue_name, :auto_delete => true, :durable => false).message_count).to eq 0
60
+ expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
61
61
 
62
62
  ch.close
63
63
  end
@@ -72,7 +72,7 @@ describe Bunny::Channel, "#basic_consume" do
72
72
 
73
73
  t = Thread.new do
74
74
  ch = @connection.create_channel
75
- q = ch.queue(queue_name, :auto_delete => true, :durable => false)
75
+ q = ch.queue(queue_name, auto_delete: true, durable: false)
76
76
  ch.basic_consume(q, "", false, false) do |delivery_info, properties, payload|
77
77
  delivered_keys << delivery_info.routing_key
78
78
  delivered_data << payload
@@ -85,13 +85,13 @@ describe Bunny::Channel, "#basic_consume" do
85
85
 
86
86
  ch = @connection.create_channel
87
87
  x = ch.default_exchange
88
- x.publish("hello", :routing_key => queue_name)
88
+ x.publish("hello", routing_key: queue_name)
89
89
 
90
90
  sleep 0.7
91
91
  expect(delivered_keys).to include queue_name
92
92
  expect(delivered_data).to include "hello"
93
93
 
94
- expect(ch.queue(queue_name, :auto_delete => true, :durable => false).message_count).to eq 0
94
+ expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
95
95
 
96
96
  ch.close
97
97
  end