bunny 0.7.13 → 0.8.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.
- data/.gitignore +2 -2
- data/.travis.yml +7 -16
- data/CHANGELOG +3 -21
- data/Gemfile +2 -4
- data/README.textile +31 -9
- data/Rakefile +3 -3
- data/bunny.gemspec +6 -3
- data/examples/{simple_08.rb → simple.rb} +1 -1
- data/examples/{simple_ack_08.rb → simple_ack.rb} +1 -1
- data/examples/{simple_consumer_08.rb → simple_consumer.rb} +4 -4
- data/examples/{simple_fanout_08.rb → simple_fanout.rb} +1 -1
- data/examples/{simple_headers_08.rb → simple_headers.rb} +2 -2
- data/examples/{simple_publisher_09.rb → simple_publisher.rb} +1 -1
- data/examples/{simple_topic_09.rb → simple_topic.rb} +2 -2
- data/ext/amqp-0.9.1.json +1 -0
- data/ext/config.yml +3 -3
- data/ext/qparser.rb +9 -52
- data/lib/bunny/{client09.rb → client.rb} +34 -46
- data/lib/bunny/{exchange09.rb → exchange.rb} +16 -15
- data/lib/bunny/{queue09.rb → queue.rb} +26 -23
- data/lib/bunny/{subscription09.rb → subscription.rb} +11 -6
- data/lib/bunny/version.rb +1 -1
- data/lib/bunny.rb +15 -33
- data/lib/qrack/client.rb +31 -22
- data/lib/qrack/protocol/{protocol08.rb → protocol.rb} +2 -1
- data/lib/qrack/protocol/{spec09.rb → spec.rb} +8 -7
- data/lib/qrack/{qrack08.rb → qrack.rb} +4 -4
- data/lib/qrack/subscription.rb +58 -9
- data/lib/qrack/transport/{buffer08.rb → buffer.rb} +9 -1
- data/lib/qrack/transport/{frame08.rb → frame.rb} +7 -22
- data/spec/spec_09/amqp_url_spec.rb +1 -1
- data/spec/spec_09/bunny_spec.rb +11 -9
- data/spec/spec_09/connection_spec.rb +9 -4
- data/spec/spec_09/exchange_spec.rb +23 -25
- data/spec/spec_09/queue_spec.rb +33 -19
- metadata +71 -81
- checksums.yaml +0 -7
- data/examples/simple_09.rb +0 -32
- data/examples/simple_ack_09.rb +0 -35
- data/examples/simple_consumer_09.rb +0 -55
- data/examples/simple_fanout_09.rb +0 -41
- data/examples/simple_headers_09.rb +0 -42
- data/examples/simple_publisher_08.rb +0 -29
- data/examples/simple_topic_08.rb +0 -61
- data/ext/amqp-0.8.json +0 -616
- data/lib/bunny/channel09.rb +0 -39
- data/lib/bunny/client08.rb +0 -480
- data/lib/bunny/exchange08.rb +0 -177
- data/lib/bunny/queue08.rb +0 -403
- data/lib/bunny/subscription08.rb +0 -87
- data/lib/qrack/protocol/protocol09.rb +0 -135
- data/lib/qrack/protocol/spec08.rb +0 -828
- data/lib/qrack/qrack09.rb +0 -20
- data/lib/qrack/transport/buffer09.rb +0 -305
- data/lib/qrack/transport/frame09.rb +0 -97
- data/spec/spec_08/bunny_spec.rb +0 -75
- data/spec/spec_08/connection_spec.rb +0 -24
- data/spec/spec_08/exchange_spec.rb +0 -175
- data/spec/spec_08/queue_spec.rb +0 -239
- data/spec/spec_helper.rb +0 -8
- /data/lib/bunny/{channel08.rb → channel.rb} +0 -0
data/lib/qrack/client.rb
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
# try loading AMQ::Client::Setttings form the amq client gem, if it has been already loaded
|
5
|
-
# this avoids "warning: already initialized constant AMQP_PORTS"
|
6
|
-
require "amq/client/settings"
|
7
|
-
rescue LoadError
|
8
|
-
require "qrack/amq-client-url"
|
9
|
-
end
|
3
|
+
require "qrack/amq-client-url"
|
10
4
|
|
11
5
|
module Qrack
|
12
6
|
|
@@ -20,12 +14,9 @@ module Qrack
|
|
20
14
|
CONNECT_TIMEOUT = 5.0
|
21
15
|
RETRY_DELAY = 10.0
|
22
16
|
|
23
|
-
attr_reader :status, :host, :vhost, :port, :logging, :spec, :heartbeat, :
|
17
|
+
attr_reader :status, :host, :vhost, :port, :logging, :spec, :heartbeat, :last_method
|
24
18
|
attr_accessor :channel, :logfile, :exchanges, :queues, :channels, :message_in, :message_out, :connecting
|
25
19
|
|
26
|
-
# Temporary hack to make Bunny 0.7 work with port number in AMQP URL.
|
27
|
-
# This is not necessary on Bunny 0.8 as it removes support of AMQP 0.8.
|
28
|
-
attr_reader :__opts__
|
29
20
|
|
30
21
|
def initialize(connection_string_or_opts = Hash.new, opts = Hash.new)
|
31
22
|
opts = case connection_string_or_opts
|
@@ -37,22 +28,22 @@ module Qrack
|
|
37
28
|
Hash.new
|
38
29
|
end.merge(opts)
|
39
30
|
|
40
|
-
# Temporary hack to make Bunny 0.7 work with port number in AMQP URL.
|
41
|
-
# This is not necessary on Bunny 0.8 as it removes support of AMQP 0.8.
|
42
|
-
@__opts__ = opts
|
43
|
-
|
44
|
-
|
45
31
|
@host = opts[:host] || 'localhost'
|
32
|
+
@port = opts[:port] || (opts[:ssl] ? Qrack::Protocol::SSL_PORT : Qrack::Protocol::PORT)
|
46
33
|
@user = opts[:user] || 'guest'
|
47
34
|
@pass = opts[:pass] || 'guest'
|
48
35
|
@vhost = opts[:vhost] || '/'
|
49
36
|
@logfile = opts[:logfile] || nil
|
50
37
|
@logging = opts[:logging] || false
|
51
38
|
@ssl = opts[:ssl] || false
|
39
|
+
@ssl_cert = opts[:ssl_cert] || nil
|
40
|
+
@ssl_key = opts[:ssl_key] || nil
|
41
|
+
@ssl_cert_string = opts[:ssl_cert_string] || nil
|
42
|
+
@ssl_key_string = opts[:ssl_key_string] || nil
|
52
43
|
@verify_ssl = opts[:verify_ssl].nil? || opts[:verify_ssl]
|
53
44
|
@status = :not_connected
|
54
45
|
@frame_max = opts[:frame_max] || 131072
|
55
|
-
@channel_max = opts[:channel_max] ||
|
46
|
+
@channel_max = opts[:channel_max] || 0
|
56
47
|
@heartbeat = opts[:heartbeat] || 0
|
57
48
|
@connect_timeout = opts[:connect_timeout] || CONNECT_TIMEOUT
|
58
49
|
@read_write_timeout = opts[:socket_timeout]
|
@@ -62,6 +53,7 @@ module Qrack
|
|
62
53
|
create_logger if @logging
|
63
54
|
@message_in = false
|
64
55
|
@message_out = false
|
56
|
+
@last_method = nil
|
65
57
|
@connecting = false
|
66
58
|
@channels ||= []
|
67
59
|
# Create channel 0
|
@@ -79,7 +71,7 @@ module Qrack
|
|
79
71
|
|
80
72
|
# Close all active channels
|
81
73
|
channels.each do |c|
|
82
|
-
Bunny::Timer::timeout(@
|
74
|
+
Bunny::Timer::timeout(@disconnect_timeout) { c.close } if c.open?
|
83
75
|
end
|
84
76
|
|
85
77
|
# Close connection to AMQP server
|
@@ -142,9 +134,6 @@ module Qrack
|
|
142
134
|
end
|
143
135
|
|
144
136
|
method = frame.payload
|
145
|
-
# at this point, we can receive a channel or connection close, which we need to check for
|
146
|
-
check_returned_message(method)
|
147
|
-
|
148
137
|
header = next_payload
|
149
138
|
|
150
139
|
# If maximum frame size is smaller than message payload body then message
|
@@ -171,6 +160,11 @@ module Qrack
|
|
171
160
|
send_command(:write, *args)
|
172
161
|
end
|
173
162
|
|
163
|
+
def read_ready?(timeout, cancelator = nil)
|
164
|
+
io = IO.select([ @socket, cancelator ].compact, nil, nil, timeout)
|
165
|
+
io and io[0].include?(@socket)
|
166
|
+
end
|
167
|
+
|
174
168
|
private
|
175
169
|
|
176
170
|
def close_socket(reason=nil)
|
@@ -219,7 +213,9 @@ module Qrack
|
|
219
213
|
|
220
214
|
if @ssl
|
221
215
|
require 'openssl' unless defined? OpenSSL::SSL
|
222
|
-
|
216
|
+
sslctx = OpenSSL::SSL::SSLContext.new
|
217
|
+
initialize_client_pair(sslctx)
|
218
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@socket, sslctx)
|
223
219
|
@socket.sync_close = true
|
224
220
|
@socket.connect
|
225
221
|
@socket.post_connection_check(host) if @verify_ssl
|
@@ -233,6 +229,19 @@ module Qrack
|
|
233
229
|
@socket
|
234
230
|
end
|
235
231
|
|
232
|
+
def initialize_client_pair(sslctx)
|
233
|
+
if @ssl_cert
|
234
|
+
@ssl_cert_string = File.read(@ssl_cert)
|
235
|
+
end
|
236
|
+
if @ssl_key
|
237
|
+
@ssl_key_string = File.read(@ssl_key)
|
238
|
+
end
|
239
|
+
|
240
|
+
sslctx.cert = OpenSSL::X509::Certificate.new(@ssl_cert_string) if @ssl_cert_string
|
241
|
+
sslctx.key = OpenSSL::PKey::RSA.new(@ssl_key_string) if @ssl_key_string
|
242
|
+
sslctx
|
243
|
+
end
|
244
|
+
|
236
245
|
end
|
237
246
|
|
238
247
|
end
|
@@ -120,7 +120,8 @@ module Qrack
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def method_missing meth, *args, &blk
|
123
|
-
@properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
|
123
|
+
@properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
|
124
|
+
super
|
124
125
|
end
|
125
126
|
end
|
126
127
|
|
@@ -3,18 +3,19 @@
|
|
3
3
|
|
4
4
|
|
5
5
|
#:stopdoc:
|
6
|
-
# this file was autogenerated on
|
7
|
-
# using amqp-0.9.1.json (mtime:
|
6
|
+
# this file was autogenerated on 2012-02-28 11:22:27 -0500
|
7
|
+
# using amqp-0.9.1.json (mtime: 2012-02-28 10:50:44 -0500)
|
8
8
|
#
|
9
9
|
# DO NOT EDIT! (edit ext/qparser.rb and config.yml instead, and run 'ruby qparser.rb')
|
10
10
|
|
11
11
|
module Qrack
|
12
|
-
module
|
12
|
+
module Protocol
|
13
13
|
HEADER = "AMQP".freeze
|
14
14
|
VERSION_MAJOR = 0
|
15
15
|
VERSION_MINOR = 9
|
16
16
|
REVISION = 1
|
17
17
|
PORT = 5672
|
18
|
+
SSL_PORT = 5671
|
18
19
|
|
19
20
|
RESPONSES = {
|
20
21
|
200 => :REPLY_SUCCESS,
|
@@ -79,7 +80,7 @@ module Qrack
|
|
79
80
|
|
80
81
|
def arguments() @arguments ||= [] end
|
81
82
|
|
82
|
-
def parent()
|
83
|
+
def parent() Protocol.const_get(self.to_s[/Protocol::(.+?)::/,1]) end
|
83
84
|
def id() self::ID end
|
84
85
|
def name() self::NAME.to_s end
|
85
86
|
end
|
@@ -117,8 +118,8 @@ module Qrack
|
|
117
118
|
def self.inherited klass
|
118
119
|
klass.const_set(:ID, #{id})
|
119
120
|
klass.const_set(:NAME, :#{name.to_s})
|
120
|
-
|
121
|
-
|
121
|
+
Protocol.classes[#{id}] = klass
|
122
|
+
Protocol.classes[klass::NAME] = klass
|
122
123
|
end
|
123
124
|
]
|
124
125
|
end
|
@@ -127,7 +128,7 @@ module Qrack
|
|
127
128
|
end
|
128
129
|
|
129
130
|
module Qrack
|
130
|
-
module
|
131
|
+
module Protocol
|
131
132
|
class Connection < Class( 10, :connection ); end
|
132
133
|
class Channel < Class( 20, :channel ); end
|
133
134
|
class Exchange < Class( 40, :exchange ); end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
$: << File.expand_path(File.dirname(__FILE__))
|
4
4
|
|
5
|
-
require 'protocol/
|
6
|
-
require 'protocol/
|
5
|
+
require 'protocol/spec'
|
6
|
+
require 'protocol/protocol'
|
7
7
|
|
8
|
-
require 'transport/
|
9
|
-
require 'transport/
|
8
|
+
require 'transport/buffer'
|
9
|
+
require 'transport/frame'
|
10
10
|
|
11
11
|
require 'qrack/client'
|
12
12
|
require 'qrack/channel'
|
data/lib/qrack/subscription.rb
CHANGED
@@ -39,6 +39,9 @@ module Qrack
|
|
39
39
|
# Initialize message counter
|
40
40
|
@message_count = 0
|
41
41
|
|
42
|
+
# Store cancellator
|
43
|
+
@cancellator = opts[:cancellator]
|
44
|
+
|
42
45
|
# Store options
|
43
46
|
@opts = opts
|
44
47
|
end
|
@@ -52,14 +55,30 @@ module Qrack
|
|
52
55
|
# Notify server about new consumer
|
53
56
|
setup_consumer
|
54
57
|
|
58
|
+
# We need to keep track of three possible subscription states
|
59
|
+
# :subscribed, :pending, and :unsubscribed
|
60
|
+
# 'pending' occurs because of network latency, where we tried to unsubscribe but were already given a message
|
61
|
+
subscribe_state = :subscribed
|
62
|
+
|
55
63
|
# Start subscription loop
|
56
64
|
loop do
|
57
65
|
|
58
66
|
begin
|
59
|
-
method = client.next_method(:timeout => timeout)
|
67
|
+
method = client.next_method(:timeout => timeout, :cancellator => @cancellator)
|
60
68
|
rescue Qrack::FrameTimeout
|
61
|
-
|
62
|
-
|
69
|
+
begin
|
70
|
+
queue.unsubscribe
|
71
|
+
subscribe_state = :unsubscribed
|
72
|
+
|
73
|
+
break
|
74
|
+
rescue Bunny::ProtocolError
|
75
|
+
# Unsubscribe failed because we actually got a message, so we're in a weird state.
|
76
|
+
# We have to keep processing the message or else it may be lost...
|
77
|
+
# ...and there is also a CancelOk method floating around that we need to consume from the socket
|
78
|
+
|
79
|
+
method = client.last_method
|
80
|
+
subscribe_state = :pending
|
81
|
+
end
|
63
82
|
end
|
64
83
|
|
65
84
|
# Increment message counter
|
@@ -67,25 +86,55 @@ module Qrack
|
|
67
86
|
|
68
87
|
# get delivery tag to use for acknowledge
|
69
88
|
queue.delivery_tag = method.delivery_tag if @ack
|
70
|
-
|
71
89
|
header = client.next_payload
|
72
90
|
|
91
|
+
# The unsubscribe ok may be sprinked into the payload
|
92
|
+
if subscribe_state == :pending and header.is_a?(Qrack::Protocol::Basic::CancelOk)
|
93
|
+
# We popped off the CancelOk, so we don't have to keep looking for it
|
94
|
+
subscribe_state = :unsubscribed
|
95
|
+
|
96
|
+
# Get the actual header now
|
97
|
+
header = client.next_payload
|
98
|
+
end
|
99
|
+
|
73
100
|
# If maximum frame size is smaller than message payload body then message
|
74
101
|
# will have a message header and several message bodies
|
75
102
|
msg = ''
|
76
103
|
while msg.length < header.size
|
77
|
-
|
104
|
+
message = client.next_payload
|
105
|
+
|
106
|
+
# The unsubscribe ok may be sprinked into the payload
|
107
|
+
if subscribe_state == :pending and message.is_a?(Qrack::Protocol::Basic::CancelOk)
|
108
|
+
# We popped off the CancelOk, so we don't have to keep looking for it
|
109
|
+
subscribe_state = :unsubscribed
|
110
|
+
next
|
111
|
+
end
|
112
|
+
|
113
|
+
msg << message
|
78
114
|
end
|
79
115
|
|
80
116
|
# If block present, pass the message info to the block for processing
|
81
117
|
blk.call({:header => header, :payload => msg, :delivery_details => method.arguments}) if !blk.nil?
|
82
118
|
|
83
|
-
#
|
84
|
-
if
|
85
|
-
|
86
|
-
|
119
|
+
# Unsubscribe if we've encountered the maximum number of messages
|
120
|
+
if subscribe_state == :subscribed and !message_max.nil? and message_count == message_max
|
121
|
+
queue.unsubscribe
|
122
|
+
subscribe_state = :unsubscribed
|
123
|
+
end
|
124
|
+
|
125
|
+
# Exit the loop if we've unsubscribed
|
126
|
+
if subscribe_state != :subscribed
|
127
|
+
# We still haven't found the CancelOk, so it's the next method
|
128
|
+
if subscribe_state == :pending
|
129
|
+
method = client.next_method
|
130
|
+
client.check_response(method, Qrack::Protocol::Basic::CancelOk, "Error unsubscribing from queue #{queue.name}, got #{method.class}")
|
131
|
+
|
132
|
+
subscribe_state = :unsubscribed
|
133
|
+
end
|
134
|
+
|
87
135
|
# Acknowledge receipt of the final message
|
88
136
|
queue.ack() if @ack
|
137
|
+
|
89
138
|
# Quit the loop
|
90
139
|
break
|
91
140
|
end
|
@@ -194,7 +194,7 @@ module Qrack
|
|
194
194
|
when String
|
195
195
|
table.write(:octet, 83) # 'S'
|
196
196
|
table.write(:longstr, value.to_s)
|
197
|
-
when
|
197
|
+
when Fixnum
|
198
198
|
table.write(:octet, 73) # 'I'
|
199
199
|
table.write(:long, value)
|
200
200
|
when Float
|
@@ -267,6 +267,14 @@ module Qrack
|
|
267
267
|
end
|
268
268
|
end
|
269
269
|
|
270
|
+
def read_ready?(timeout, cancellator)
|
271
|
+
if @data.is_a?(Qrack::Client)
|
272
|
+
@data.read_ready?(timeout, cancellator)
|
273
|
+
else
|
274
|
+
true
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
270
278
|
def _read(size, pack = nil)
|
271
279
|
if @data.is_a?(Qrack::Client)
|
272
280
|
raw = @data.read(size)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
|
5
5
|
#:stopdoc:
|
6
|
-
# this file was autogenerated on
|
6
|
+
# this file was autogenerated on 2012-02-28 11:22:27 -0500
|
7
7
|
#
|
8
8
|
# DO NOT EDIT! (edit ext/qparser.rb and config.yml instead, and run 'ruby qparser.rb')
|
9
9
|
|
@@ -18,10 +18,6 @@ module Qrack
|
|
18
18
|
1 => 'Method',
|
19
19
|
2 => 'Header',
|
20
20
|
3 => 'Body',
|
21
|
-
4 => 'OobMethod',
|
22
|
-
5 => 'OobHeader',
|
23
|
-
6 => 'OobBody',
|
24
|
-
7 => 'Trace',
|
25
21
|
8 => 'Heartbeat',
|
26
22
|
}
|
27
23
|
|
@@ -55,8 +51,13 @@ module Qrack
|
|
55
51
|
end
|
56
52
|
end
|
57
53
|
|
58
|
-
def self.parse
|
54
|
+
def self.parse(buf, opts)
|
59
55
|
buf = Transport::Buffer.new(buf) unless buf.is_a? Transport::Buffer
|
56
|
+
|
57
|
+
if opts[:timeout] or opts[:cancellator]
|
58
|
+
raise Qrack::FrameTimeout unless buf.read_ready?(opts[:timeout], opts[:cancellator])
|
59
|
+
end
|
60
|
+
|
60
61
|
buf.extract do
|
61
62
|
id, channel, payload, footer = buf.read(:octet, :short, :longstr, :octet)
|
62
63
|
Qrack::Transport.const_get(@types[id]).new(payload, channel) if footer == FOOTER
|
@@ -93,22 +94,6 @@ module Qrack
|
|
93
94
|
ID = 3
|
94
95
|
end
|
95
96
|
|
96
|
-
class OobMethod < Frame
|
97
|
-
ID = 4
|
98
|
-
end
|
99
|
-
|
100
|
-
class OobHeader < Frame
|
101
|
-
ID = 5
|
102
|
-
end
|
103
|
-
|
104
|
-
class OobBody < Frame
|
105
|
-
ID = 6
|
106
|
-
end
|
107
|
-
|
108
|
-
class Trace < Frame
|
109
|
-
ID = 7
|
110
|
-
end
|
111
|
-
|
112
97
|
class Heartbeat < Frame
|
113
98
|
ID = 8
|
114
99
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# If this is not the case, please change the 'Bunny.new' call below to include
|
7
7
|
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
|
8
8
|
|
9
|
-
|
9
|
+
require "bunny"
|
10
10
|
|
11
11
|
describe Bunny do
|
12
12
|
context "AMQP URL parsing" do
|
data/spec/spec_09/bunny_spec.rb
CHANGED
@@ -8,12 +8,12 @@
|
|
8
8
|
# If this is not the case, please change the 'Bunny.new' call below to include
|
9
9
|
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
|
10
10
|
|
11
|
-
|
11
|
+
require "bunny"
|
12
12
|
|
13
13
|
describe Bunny do
|
14
14
|
|
15
15
|
before(:each) do
|
16
|
-
@b = Bunny.new
|
16
|
+
@b = Bunny.new
|
17
17
|
@b.start
|
18
18
|
end
|
19
19
|
|
@@ -33,7 +33,7 @@ describe Bunny do
|
|
33
33
|
it "should be able to create and open a new channel" do
|
34
34
|
c = @b.create_channel
|
35
35
|
c.number.should == 2
|
36
|
-
c.should be_an_instance_of(Bunny::
|
36
|
+
c.should be_an_instance_of(Bunny::Channel)
|
37
37
|
@b.channels.size.should == 3
|
38
38
|
c.open.should == :open_ok
|
39
39
|
@b.channel.number.should == 2
|
@@ -51,24 +51,26 @@ describe Bunny do
|
|
51
51
|
|
52
52
|
it "should be able to create an exchange" do
|
53
53
|
exch = @b.exchange('test_exchange')
|
54
|
-
exch.should be_an_instance_of(Bunny::
|
54
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
55
55
|
exch.name.should == 'test_exchange'
|
56
56
|
@b.exchanges.has_key?('test_exchange').should be(true)
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should be able to create a queue" do
|
60
60
|
q = @b.queue('test1')
|
61
|
-
q.should be_an_instance_of(Bunny::
|
61
|
+
q.should be_an_instance_of(Bunny::Queue)
|
62
62
|
q.name.should == 'test1'
|
63
63
|
@b.queues.has_key?('test1').should be(true)
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
66
|
+
# Current RabbitMQ has not implemented some functionality
|
67
|
+
it "should raise an error if setting of QoS fails" do
|
68
|
+
lambda { @b.qos(:global => true) }.should raise_error(Bunny::ForcedConnectionCloseError)
|
69
|
+
@b.status.should == :not_connected
|
68
70
|
end
|
69
71
|
|
70
|
-
it "should be able to set QoS
|
71
|
-
@b.qos
|
72
|
+
it "should be able to set QoS" do
|
73
|
+
@b.qos.should == :qos_ok
|
72
74
|
end
|
73
75
|
|
74
76
|
end
|
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
# connection_spec.rb
|
4
4
|
|
5
|
-
|
5
|
+
require "bunny"
|
6
6
|
|
7
7
|
describe Bunny do
|
8
8
|
|
9
9
|
it "should raise an error if the wrong user name or password is used" do
|
10
|
-
b = Bunny.new(:
|
10
|
+
b = Bunny.new(:user => 'wrong')
|
11
11
|
lambda { b.start}.should raise_error(Bunny::ProtocolError)
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should merge custom settings from AMQP URL with default settings" do
|
15
|
-
b = Bunny.new("amqp://tagadab"
|
15
|
+
b = Bunny.new("amqp://tagadab")
|
16
16
|
b.host.should eql("tagadab")
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should be able to open a TCPSocket with a timeout" do
|
20
|
-
b = Bunny.new
|
20
|
+
b = Bunny.new
|
21
21
|
connect_timeout = 5
|
22
22
|
lambda {
|
23
23
|
Bunny::Timer::timeout(connect_timeout, Qrack::ConnectionTimeout) do
|
@@ -26,4 +26,9 @@ describe Bunny do
|
|
26
26
|
}.should_not raise_error(Exception)
|
27
27
|
end
|
28
28
|
|
29
|
+
it "should know the default port of a SSL connection" do
|
30
|
+
b = Bunny.new(:ssl => true)
|
31
|
+
b.port.should eql(5671)
|
32
|
+
end
|
33
|
+
|
29
34
|
end
|
@@ -8,12 +8,12 @@
|
|
8
8
|
# If this is not the case, please change the 'Bunny.new' call below to include
|
9
9
|
# the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
|
10
10
|
|
11
|
-
|
11
|
+
require "bunny"
|
12
12
|
|
13
13
|
describe 'Exchange' do
|
14
14
|
|
15
15
|
before(:each) do
|
16
|
-
@b = Bunny.new
|
16
|
+
@b = Bunny.new
|
17
17
|
@b.start
|
18
18
|
end
|
19
19
|
|
@@ -33,7 +33,7 @@ describe 'Exchange' do
|
|
33
33
|
|
34
34
|
it "should allow a default direct exchange to be instantiated by specifying :type" do
|
35
35
|
exch = @b.exchange('amq.direct', :type => :direct)
|
36
|
-
exch.should be_an_instance_of(Bunny::
|
36
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
37
37
|
exch.name.should == 'amq.direct'
|
38
38
|
exch.type.should == :direct
|
39
39
|
@b.exchanges.has_key?('amq.direct').should be(true)
|
@@ -41,7 +41,7 @@ describe 'Exchange' do
|
|
41
41
|
|
42
42
|
it "should allow a default direct exchange to be instantiated without specifying :type" do
|
43
43
|
exch = @b.exchange('amq.direct')
|
44
|
-
exch.should be_an_instance_of(Bunny::
|
44
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
45
45
|
exch.name.should == 'amq.direct'
|
46
46
|
exch.type.should == :direct
|
47
47
|
@b.exchanges.has_key?('amq.direct').should be(true)
|
@@ -49,7 +49,7 @@ describe 'Exchange' do
|
|
49
49
|
|
50
50
|
it "should allow a default fanout exchange to be instantiated without specifying :type" do
|
51
51
|
exch = @b.exchange('amq.fanout')
|
52
|
-
exch.should be_an_instance_of(Bunny::
|
52
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
53
53
|
exch.name.should == 'amq.fanout'
|
54
54
|
exch.type.should == :fanout
|
55
55
|
@b.exchanges.has_key?('amq.fanout').should be(true)
|
@@ -57,7 +57,7 @@ describe 'Exchange' do
|
|
57
57
|
|
58
58
|
it "should allow a default topic exchange to be instantiated without specifying :type" do
|
59
59
|
exch = @b.exchange('amq.topic')
|
60
|
-
exch.should be_an_instance_of(Bunny::
|
60
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
61
61
|
exch.name.should == 'amq.topic'
|
62
62
|
exch.type.should == :topic
|
63
63
|
@b.exchanges.has_key?('amq.topic').should be(true)
|
@@ -65,7 +65,7 @@ describe 'Exchange' do
|
|
65
65
|
|
66
66
|
it "should allow a default headers (amq.match) exchange to be instantiated without specifying :type" do
|
67
67
|
exch = @b.exchange('amq.match')
|
68
|
-
exch.should be_an_instance_of(Bunny::
|
68
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
69
69
|
exch.name.should == 'amq.match'
|
70
70
|
exch.type.should == :headers
|
71
71
|
@b.exchanges.has_key?('amq.match').should be(true)
|
@@ -73,7 +73,7 @@ describe 'Exchange' do
|
|
73
73
|
|
74
74
|
it "should allow a default headers (amq.headers) exchange to be instantiated without specifying :type" do
|
75
75
|
exch = @b.exchange('amq.headers')
|
76
|
-
exch.should be_an_instance_of(Bunny::
|
76
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
77
77
|
exch.name.should == 'amq.headers'
|
78
78
|
exch.type.should == :headers
|
79
79
|
@b.exchanges.has_key?('amq.headers').should be(true)
|
@@ -81,7 +81,7 @@ describe 'Exchange' do
|
|
81
81
|
|
82
82
|
it "should create an exchange as direct by default" do
|
83
83
|
exch = @b.exchange('direct_defaultex')
|
84
|
-
exch.should be_an_instance_of(Bunny::
|
84
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
85
85
|
exch.name.should == 'direct_defaultex'
|
86
86
|
exch.type.should == :direct
|
87
87
|
@b.exchanges.has_key?('direct_defaultex').should be(true)
|
@@ -89,7 +89,7 @@ describe 'Exchange' do
|
|
89
89
|
|
90
90
|
it "should be able to be instantiated as a direct exchange" do
|
91
91
|
exch = @b.exchange('direct_exchange', :type => :direct)
|
92
|
-
exch.should be_an_instance_of(Bunny::
|
92
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
93
93
|
exch.name.should == 'direct_exchange'
|
94
94
|
exch.type.should == :direct
|
95
95
|
@b.exchanges.has_key?('direct_exchange').should be(true)
|
@@ -97,7 +97,7 @@ describe 'Exchange' do
|
|
97
97
|
|
98
98
|
it "should be able to be instantiated as a topic exchange" do
|
99
99
|
exch = @b.exchange('topic_exchange', :type => :topic)
|
100
|
-
exch.should be_an_instance_of(Bunny::
|
100
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
101
101
|
exch.name.should == 'topic_exchange'
|
102
102
|
exch.type.should == :topic
|
103
103
|
@b.exchanges.has_key?('topic_exchange').should be(true)
|
@@ -105,7 +105,7 @@ describe 'Exchange' do
|
|
105
105
|
|
106
106
|
it "should be able to be instantiated as a fanout exchange" do
|
107
107
|
exch = @b.exchange('fanout_exchange', :type => :fanout)
|
108
|
-
exch.should be_an_instance_of(Bunny::
|
108
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
109
109
|
exch.name.should == 'fanout_exchange'
|
110
110
|
exch.type.should == :fanout
|
111
111
|
@b.exchanges.has_key?('fanout_exchange').should be(true)
|
@@ -113,7 +113,7 @@ describe 'Exchange' do
|
|
113
113
|
|
114
114
|
it "should be able to be instantiated as a headers exchange" do
|
115
115
|
exch = @b.exchange('headers_exchange', :type => :headers)
|
116
|
-
exch.should be_an_instance_of(Bunny::
|
116
|
+
exch.should be_an_instance_of(Bunny::Exchange)
|
117
117
|
exch.name.should == 'headers_exchange'
|
118
118
|
exch.type.should == :headers
|
119
119
|
@b.exchanges.has_key?('headers_exchange').should be(true)
|
@@ -128,11 +128,6 @@ describe 'Exchange' do
|
|
128
128
|
exch.publish('This is a published message')
|
129
129
|
end
|
130
130
|
|
131
|
-
it "should be able to publish a message with headers containing integer values" do
|
132
|
-
exch = @b.exchange('direct_exchange')
|
133
|
-
exch.publish('This is a published message', :headers => {:a => 1})
|
134
|
-
end
|
135
|
-
|
136
131
|
it "should not modify the passed options hash when publishing a message" do
|
137
132
|
exch = @b.exchange('direct_exchange')
|
138
133
|
opts = {:key => 'a', :persistent => true}
|
@@ -142,22 +137,25 @@ describe 'Exchange' do
|
|
142
137
|
|
143
138
|
it "should be able to return an undeliverable message" do
|
144
139
|
exch = @b.exchange('return_exch')
|
145
|
-
exch.publish('This message should be undeliverable', :
|
140
|
+
exch.publish('This message should be undeliverable', :immediate => true)
|
146
141
|
ret_msg = @b.returned_message
|
147
142
|
ret_msg.should be_an_instance_of(Hash)
|
148
143
|
ret_msg[:payload].should == 'This message should be undeliverable'
|
149
144
|
end
|
150
145
|
|
151
|
-
it "should be able to
|
146
|
+
it "should be able to return a message that exceeds maximum frame size" do
|
152
147
|
exch = @b.exchange('return_exch')
|
153
|
-
|
154
|
-
|
148
|
+
lg_msg = 'z' * 142000
|
149
|
+
exch.publish(lg_msg, :immediate => true)
|
150
|
+
ret_msg = @b.returned_message
|
151
|
+
ret_msg.should be_an_instance_of(Hash)
|
152
|
+
ret_msg[:payload].should == lg_msg
|
155
153
|
end
|
156
154
|
|
157
|
-
it "should
|
155
|
+
it "should report an error if delete fails" do
|
158
156
|
exch = @b.exchange('direct_exchange')
|
159
|
-
exch.delete(:exchange => 'bogus_ex').should
|
160
|
-
@b.channel.active.should ==
|
157
|
+
lambda { exch.delete(:exchange => 'bogus_ex') }.should raise_error(Bunny::ForcedChannelCloseError)
|
158
|
+
@b.channel.active.should == false
|
161
159
|
end
|
162
160
|
|
163
161
|
it "should be able to be deleted" do
|