bunny 0.7.13 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|