bunny 0.8.0 → 0.9.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +7 -1
  2. data/.travis.yml +14 -4
  3. data/ChangeLog.md +72 -0
  4. data/Gemfile +17 -11
  5. data/README.md +82 -0
  6. data/bunny.gemspec +6 -13
  7. data/examples/connection/heartbeat.rb +17 -0
  8. data/lib/bunny.rb +40 -56
  9. data/lib/bunny/channel.rb +615 -19
  10. data/lib/bunny/channel_id_allocator.rb +59 -0
  11. data/lib/bunny/compatibility.rb +24 -0
  12. data/lib/bunny/concurrent/condition.rb +63 -0
  13. data/lib/bunny/consumer.rb +42 -26
  14. data/lib/bunny/consumer_tag_generator.rb +22 -0
  15. data/lib/bunny/consumer_work_pool.rb +67 -0
  16. data/lib/bunny/exceptions.rb +128 -0
  17. data/lib/bunny/exchange.rb +131 -136
  18. data/lib/bunny/framing.rb +53 -0
  19. data/lib/bunny/heartbeat_sender.rb +59 -0
  20. data/lib/bunny/main_loop.rb +70 -0
  21. data/lib/bunny/message_metadata.rb +126 -0
  22. data/lib/bunny/queue.rb +102 -275
  23. data/lib/bunny/session.rb +478 -0
  24. data/lib/bunny/socket.rb +44 -0
  25. data/lib/bunny/system_timer.rb +9 -9
  26. data/lib/bunny/transport.rb +179 -0
  27. data/lib/bunny/version.rb +1 -1
  28. data/spec/compatibility/queue_declare_spec.rb +40 -0
  29. data/spec/higher_level_api/integration/basic_ack_spec.rb +54 -0
  30. data/spec/higher_level_api/integration/basic_consume_spec.rb +51 -0
  31. data/spec/higher_level_api/integration/basic_get_spec.rb +47 -0
  32. data/spec/higher_level_api/integration/basic_nack_spec.rb +39 -0
  33. data/spec/higher_level_api/integration/basic_publish_spec.rb +105 -0
  34. data/spec/higher_level_api/integration/basic_qos_spec.rb +32 -0
  35. data/spec/higher_level_api/integration/basic_recover_spec.rb +18 -0
  36. data/spec/higher_level_api/integration/basic_reject_spec.rb +53 -0
  37. data/spec/higher_level_api/integration/basic_return_spec.rb +33 -0
  38. data/spec/higher_level_api/integration/channel_close_spec.rb +29 -0
  39. data/spec/higher_level_api/integration/channel_flow_spec.rb +24 -0
  40. data/spec/higher_level_api/integration/channel_open_spec.rb +57 -0
  41. data/spec/higher_level_api/integration/channel_open_stress_spec.rb +22 -0
  42. data/spec/higher_level_api/integration/confirm_select_spec.rb +19 -0
  43. data/spec/higher_level_api/integration/connection_spec.rb +340 -0
  44. data/spec/higher_level_api/integration/exchange_bind_spec.rb +31 -0
  45. data/spec/higher_level_api/integration/exchange_declare_spec.rb +183 -0
  46. data/spec/higher_level_api/integration/exchange_delete_spec.rb +37 -0
  47. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +40 -0
  48. data/spec/higher_level_api/integration/queue_bind_spec.rb +109 -0
  49. data/spec/higher_level_api/integration/queue_declare_spec.rb +129 -0
  50. data/spec/higher_level_api/integration/queue_delete_spec.rb +38 -0
  51. data/spec/higher_level_api/integration/queue_purge_spec.rb +30 -0
  52. data/spec/higher_level_api/integration/queue_unbind_spec.rb +33 -0
  53. data/spec/higher_level_api/integration/tx_commit_spec.rb +21 -0
  54. data/spec/higher_level_api/integration/tx_rollback_spec.rb +21 -0
  55. data/spec/lower_level_api/integration/basic_cancel_spec.rb +57 -0
  56. data/spec/lower_level_api/integration/basic_consume_spec.rb +100 -0
  57. data/spec/spec_helper.rb +64 -0
  58. data/spec/unit/bunny_spec.rb +15 -0
  59. data/spec/unit/concurrent/condition_spec.rb +66 -0
  60. metadata +135 -93
  61. data/CHANGELOG +0 -21
  62. data/README.textile +0 -76
  63. data/Rakefile +0 -14
  64. data/examples/simple.rb +0 -32
  65. data/examples/simple_ack.rb +0 -35
  66. data/examples/simple_consumer.rb +0 -55
  67. data/examples/simple_fanout.rb +0 -41
  68. data/examples/simple_headers.rb +0 -42
  69. data/examples/simple_publisher.rb +0 -29
  70. data/examples/simple_topic.rb +0 -61
  71. data/ext/amqp-0.9.1.json +0 -389
  72. data/ext/config.yml +0 -4
  73. data/ext/qparser.rb +0 -426
  74. data/lib/bunny/client.rb +0 -370
  75. data/lib/bunny/subscription.rb +0 -92
  76. data/lib/qrack/amq-client-url.rb +0 -165
  77. data/lib/qrack/channel.rb +0 -20
  78. data/lib/qrack/client.rb +0 -247
  79. data/lib/qrack/errors.rb +0 -5
  80. data/lib/qrack/protocol/protocol.rb +0 -135
  81. data/lib/qrack/protocol/spec.rb +0 -525
  82. data/lib/qrack/qrack.rb +0 -20
  83. data/lib/qrack/queue.rb +0 -40
  84. data/lib/qrack/subscription.rb +0 -152
  85. data/lib/qrack/transport/buffer.rb +0 -305
  86. data/lib/qrack/transport/frame.rb +0 -102
  87. data/spec/spec_09/amqp_url_spec.rb +0 -19
  88. data/spec/spec_09/bunny_spec.rb +0 -76
  89. data/spec/spec_09/connection_spec.rb +0 -34
  90. data/spec/spec_09/exchange_spec.rb +0 -173
  91. data/spec/spec_09/queue_spec.rb +0 -240
@@ -1,102 +0,0 @@
1
-
2
- # encoding: utf-8
3
-
4
-
5
- #:stopdoc:
6
- # this file was autogenerated on 2012-02-28 11:22:27 -0500
7
- #
8
- # DO NOT EDIT! (edit ext/qparser.rb and config.yml instead, and run 'ruby qparser.rb')
9
-
10
- module Qrack
11
- module Transport
12
- class Frame
13
-
14
- FOOTER = 206
15
- ID = 0
16
-
17
- @types = {
18
- 1 => 'Method',
19
- 2 => 'Header',
20
- 3 => 'Body',
21
- 8 => 'Heartbeat',
22
- }
23
-
24
- attr_accessor :channel, :payload
25
-
26
- def initialize payload = nil, channel = 0
27
- @channel, @payload = channel, payload
28
- end
29
-
30
- def id
31
- self.class::ID
32
- end
33
-
34
- def to_binary
35
- buf = Transport::Buffer.new
36
- buf.write :octet, id
37
- buf.write :short, channel
38
- buf.write :longstr, payload
39
- buf.write :octet, FOOTER
40
- buf.rewind
41
- buf
42
- end
43
-
44
- def to_s
45
- to_binary.to_s
46
- end
47
-
48
- def == frame
49
- [ :id, :channel, :payload ].inject(true) do |eql, field|
50
- eql and __send__(field) == frame.__send__(field)
51
- end
52
- end
53
-
54
- def self.parse(buf, opts)
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
-
61
- buf.extract do
62
- id, channel, payload, footer = buf.read(:octet, :short, :longstr, :octet)
63
- Qrack::Transport.const_get(@types[id]).new(payload, channel) if footer == FOOTER
64
- end
65
- end
66
-
67
- end
68
-
69
- class Method < Frame
70
-
71
- ID = 1
72
-
73
- def initialize payload = nil, channel = 0
74
- super
75
- unless @payload.is_a? Protocol::Class::Method or @payload.nil?
76
- @payload = Protocol.parse(@payload)
77
- end
78
- end
79
- end
80
-
81
- class Header < Frame
82
-
83
- ID = 2
84
-
85
- def initialize payload = nil, channel = 0
86
- super
87
- unless @payload.is_a? Protocol::Header or @payload.nil?
88
- @payload = Protocol::Header.new(@payload)
89
- end
90
- end
91
- end
92
-
93
- class Body < Frame
94
- ID = 3
95
- end
96
-
97
- class Heartbeat < Frame
98
- ID = 8
99
- end
100
-
101
- end
102
- end
@@ -1,19 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # Assumes that target message broker/server has a user called 'guest' with a password 'guest'
4
- # and that it is running on 'localhost'.
5
-
6
- # If this is not the case, please change the 'Bunny.new' call below to include
7
- # the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
8
-
9
- require "bunny"
10
-
11
- describe Bunny do
12
- context "AMQP URL parsing" do
13
- it "handles port properly" do
14
- bunny = Bunny.new("amqp://dev.rabbitmq.com:1212")
15
- bunny.port.should eql(1212)
16
- bunny.stop
17
- end
18
- end
19
- end
@@ -1,76 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # bunny_spec.rb
4
-
5
- # Assumes that target message broker/server has a user called 'guest' with a password 'guest'
6
- # and that it is running on 'localhost'.
7
-
8
- # If this is not the case, please change the 'Bunny.new' call below to include
9
- # the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
10
-
11
- require "bunny"
12
-
13
- describe Bunny do
14
-
15
- before(:each) do
16
- @b = Bunny.new
17
- @b.start
18
- end
19
-
20
- after(:each) do
21
- begin
22
- @b.stop
23
- rescue Exception
24
- ensure
25
- @b = nil
26
- end
27
- end
28
-
29
- it "should connect to an AMQP server" do
30
- @b.status.should == :connected
31
- end
32
-
33
- it "should be able to create and open a new channel" do
34
- c = @b.create_channel
35
- c.number.should == 2
36
- c.should be_an_instance_of(Bunny::Channel)
37
- @b.channels.size.should == 3
38
- c.open.should == :open_ok
39
- @b.channel.number.should == 2
40
- end
41
-
42
- it "should be able to switch between channels" do
43
- @b.channel.number.should == 1
44
- @b.switch_channel(0)
45
- @b.channel.number.should == 0
46
- end
47
-
48
- it "should raise an error if trying to switch to a non-existent channel" do
49
- lambda { @b.switch_channel(5) }.should raise_error(RuntimeError)
50
- end
51
-
52
- it "should be able to create an exchange" do
53
- exch = @b.exchange('test_exchange')
54
- exch.should be_an_instance_of(Bunny::Exchange)
55
- exch.name.should == 'test_exchange'
56
- @b.exchanges.has_key?('test_exchange').should be(true)
57
- end
58
-
59
- it "should be able to create a queue" do
60
- q = @b.queue('test1')
61
- q.should be_an_instance_of(Bunny::Queue)
62
- q.name.should == 'test1'
63
- @b.queues.has_key?('test1').should be(true)
64
- end
65
-
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
70
- end
71
-
72
- it "should be able to set QoS" do
73
- @b.qos.should == :qos_ok
74
- end
75
-
76
- end
@@ -1,34 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # connection_spec.rb
4
-
5
- require "bunny"
6
-
7
- describe Bunny do
8
-
9
- it "should raise an error if the wrong user name or password is used" do
10
- b = Bunny.new(:user => 'wrong')
11
- lambda { b.start}.should raise_error(Bunny::ProtocolError)
12
- end
13
-
14
- it "should merge custom settings from AMQP URL with default settings" do
15
- b = Bunny.new("amqp://tagadab")
16
- b.host.should eql("tagadab")
17
- end
18
-
19
- it "should be able to open a TCPSocket with a timeout" do
20
- b = Bunny.new
21
- connect_timeout = 5
22
- lambda {
23
- Bunny::Timer::timeout(connect_timeout, Qrack::ConnectionTimeout) do
24
- TCPSocket.new(b.host, b.port)
25
- end
26
- }.should_not raise_error(Exception)
27
- end
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
-
34
- end
@@ -1,173 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # exchange_spec.rb
4
-
5
- # Assumes that target message broker/server has a user called 'guest' with a password 'guest'
6
- # and that it is running on 'localhost'.
7
-
8
- # If this is not the case, please change the 'Bunny.new' call below to include
9
- # the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
10
-
11
- require "bunny"
12
-
13
- describe 'Exchange' do
14
-
15
- before(:each) do
16
- @b = Bunny.new
17
- @b.start
18
- end
19
-
20
- after(:each) do
21
- begin
22
- @b.stop
23
- rescue Exception
24
- ensure
25
- @b = nil
26
- end
27
- end
28
-
29
- it "should raise an error if instantiated as non-existent type" do
30
- lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error(Bunny::ForcedConnectionCloseError)
31
- @b.status.should == :not_connected
32
- end
33
-
34
- it "should allow a default direct exchange to be instantiated by specifying :type" do
35
- exch = @b.exchange('amq.direct', :type => :direct)
36
- exch.should be_an_instance_of(Bunny::Exchange)
37
- exch.name.should == 'amq.direct'
38
- exch.type.should == :direct
39
- @b.exchanges.has_key?('amq.direct').should be(true)
40
- end
41
-
42
- it "should allow a default direct exchange to be instantiated without specifying :type" do
43
- exch = @b.exchange('amq.direct')
44
- exch.should be_an_instance_of(Bunny::Exchange)
45
- exch.name.should == 'amq.direct'
46
- exch.type.should == :direct
47
- @b.exchanges.has_key?('amq.direct').should be(true)
48
- end
49
-
50
- it "should allow a default fanout exchange to be instantiated without specifying :type" do
51
- exch = @b.exchange('amq.fanout')
52
- exch.should be_an_instance_of(Bunny::Exchange)
53
- exch.name.should == 'amq.fanout'
54
- exch.type.should == :fanout
55
- @b.exchanges.has_key?('amq.fanout').should be(true)
56
- end
57
-
58
- it "should allow a default topic exchange to be instantiated without specifying :type" do
59
- exch = @b.exchange('amq.topic')
60
- exch.should be_an_instance_of(Bunny::Exchange)
61
- exch.name.should == 'amq.topic'
62
- exch.type.should == :topic
63
- @b.exchanges.has_key?('amq.topic').should be(true)
64
- end
65
-
66
- it "should allow a default headers (amq.match) exchange to be instantiated without specifying :type" do
67
- exch = @b.exchange('amq.match')
68
- exch.should be_an_instance_of(Bunny::Exchange)
69
- exch.name.should == 'amq.match'
70
- exch.type.should == :headers
71
- @b.exchanges.has_key?('amq.match').should be(true)
72
- end
73
-
74
- it "should allow a default headers (amq.headers) exchange to be instantiated without specifying :type" do
75
- exch = @b.exchange('amq.headers')
76
- exch.should be_an_instance_of(Bunny::Exchange)
77
- exch.name.should == 'amq.headers'
78
- exch.type.should == :headers
79
- @b.exchanges.has_key?('amq.headers').should be(true)
80
- end
81
-
82
- it "should create an exchange as direct by default" do
83
- exch = @b.exchange('direct_defaultex')
84
- exch.should be_an_instance_of(Bunny::Exchange)
85
- exch.name.should == 'direct_defaultex'
86
- exch.type.should == :direct
87
- @b.exchanges.has_key?('direct_defaultex').should be(true)
88
- end
89
-
90
- it "should be able to be instantiated as a direct exchange" do
91
- exch = @b.exchange('direct_exchange', :type => :direct)
92
- exch.should be_an_instance_of(Bunny::Exchange)
93
- exch.name.should == 'direct_exchange'
94
- exch.type.should == :direct
95
- @b.exchanges.has_key?('direct_exchange').should be(true)
96
- end
97
-
98
- it "should be able to be instantiated as a topic exchange" do
99
- exch = @b.exchange('topic_exchange', :type => :topic)
100
- exch.should be_an_instance_of(Bunny::Exchange)
101
- exch.name.should == 'topic_exchange'
102
- exch.type.should == :topic
103
- @b.exchanges.has_key?('topic_exchange').should be(true)
104
- end
105
-
106
- it "should be able to be instantiated as a fanout exchange" do
107
- exch = @b.exchange('fanout_exchange', :type => :fanout)
108
- exch.should be_an_instance_of(Bunny::Exchange)
109
- exch.name.should == 'fanout_exchange'
110
- exch.type.should == :fanout
111
- @b.exchanges.has_key?('fanout_exchange').should be(true)
112
- end
113
-
114
- it "should be able to be instantiated as a headers exchange" do
115
- exch = @b.exchange('headers_exchange', :type => :headers)
116
- exch.should be_an_instance_of(Bunny::Exchange)
117
- exch.name.should == 'headers_exchange'
118
- exch.type.should == :headers
119
- @b.exchanges.has_key?('headers_exchange').should be(true)
120
- end
121
-
122
- it "should ignore the :nowait option when instantiated" do
123
- exch = @b.exchange('direct2_exchange', :nowait => true)
124
- end
125
-
126
- it "should be able to publish a message" do
127
- exch = @b.exchange('direct_exchange')
128
- exch.publish('This is a published message')
129
- end
130
-
131
- it "should not modify the passed options hash when publishing a message" do
132
- exch = @b.exchange('direct_exchange')
133
- opts = {:key => 'a', :persistent => true}
134
- exch.publish('', opts)
135
- opts.should == {:key => 'a', :persistent => true}
136
- end
137
-
138
- it "should be able to return an undeliverable message" do
139
- exch = @b.exchange('return_exch')
140
- exch.publish('This message should be undeliverable', :immediate => true)
141
- ret_msg = @b.returned_message
142
- ret_msg.should be_an_instance_of(Hash)
143
- ret_msg[:payload].should == 'This message should be undeliverable'
144
- end
145
-
146
- it "should be able to return a message that exceeds maximum frame size" do
147
- exch = @b.exchange('return_exch')
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
153
- end
154
-
155
- it "should report an error if delete fails" do
156
- exch = @b.exchange('direct_exchange')
157
- lambda { exch.delete(:exchange => 'bogus_ex') }.should raise_error(Bunny::ForcedChannelCloseError)
158
- @b.channel.active.should == false
159
- end
160
-
161
- it "should be able to be deleted" do
162
- exch = @b.exchange('direct_exchange')
163
- res = exch.delete
164
- res.should == :delete_ok
165
- @b.exchanges.has_key?('direct_exchange').should be(false)
166
- end
167
-
168
- it "should ignore the :nowait option when deleted" do
169
- exch = @b.exchange('direct2_exchange')
170
- exch.delete(:nowait => true)
171
- end
172
-
173
- end
@@ -1,240 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # queue_spec.rb
4
-
5
- # Assumes that target message broker/server has a user called 'guest' with a password 'guest'
6
- # and that it is running on 'localhost'.
7
-
8
- # If this is not the case, please change the 'Bunny.new' call below to include
9
- # the relevant arguments e.g. @b = Bunny.new(:user => 'john', :pass => 'doe', :host => 'foobar')
10
-
11
- require "bunny"
12
-
13
- describe 'Queue' do
14
-
15
- before(:each) do
16
- @b = Bunny.new
17
- @b.start
18
-
19
- @default_exchange = @b.exchange("")
20
- end
21
-
22
- after(:each) do
23
- begin
24
- @b.stop
25
- rescue Exception
26
- ensure
27
- @b = nil
28
- end
29
- end
30
-
31
- def message_count(queue, sleep_time = 0.1)
32
- sleep sleep_time
33
- queue.message_count
34
- end
35
-
36
- it "should ignore the :nowait option when instantiated" do
37
- q = @b.queue('test0', :nowait => true)
38
- end
39
-
40
- it "should ignore the :nowait option when binding to an exchange" do
41
- exch = @b.exchange('direct_exch')
42
- q = @b.queue('test0')
43
- q.bind(exch, :nowait => true).should == :bind_ok
44
- end
45
-
46
- it "should raise an error when trying to bind to a non-existent exchange" do
47
- q = @b.queue('test1')
48
- lambda {q.bind('bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
49
- @b.channel.active.should == false
50
- end
51
-
52
- it "should be able to bind to an existing exchange" do
53
- exch = @b.exchange('direct_exch')
54
- q = @b.queue('test1')
55
- q.bind(exch).should == :bind_ok
56
- end
57
-
58
- it "should ignore the :nowait option when unbinding from an existing exchange" do
59
- exch = @b.exchange('direct_exch')
60
- q = @b.queue('test0')
61
- q.unbind(exch, :nowait => true).should == :unbind_ok
62
- end
63
-
64
- it "should raise an error if unbinding from a non-existent exchange" do
65
- q = @b.queue('test1')
66
- lambda {q.unbind('bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
67
- @b.channel.active.should == false
68
- end
69
-
70
- it "should be able to unbind from an exchange" do
71
- exch = @b.exchange('direct_exch')
72
- q = @b.queue('test1')
73
- q.unbind(exch).should == :unbind_ok
74
- end
75
-
76
- it "should be able to pop a message complete with header and delivery details" do
77
- q = @b.queue('test1')
78
- @default_exchange.publish('This is a test message', :key => 'test1')
79
- msg = q.pop()
80
- msg.should be_an_instance_of(Hash)
81
- msg[:header].should be_an_instance_of(Bunny::Protocol::Header)
82
- msg[:payload].should == 'This is a test message'
83
- msg[:delivery_details].should be_an_instance_of(Hash)
84
- message_count(q).should == 0
85
- end
86
-
87
- it "should be able to send reply_to, correlation_id and user_id headers " do
88
- q = @b.queue('test1')
89
- @default_exchange.publish('This is a test message', :key => 'test1',
90
- :reply_to => 'test_reply_to',
91
- :correlation_id => '987654',
92
- :user_id => 'guest')
93
- msg = q.pop()
94
- msg[:header].properties[:reply_to].should == 'test_reply_to'
95
- msg[:header].properties[:correlation_id].should == '987654'
96
- msg[:header].properties[:user_id].should == 'guest'
97
- end
98
-
99
- it "should be able to pop a message and just get the payload" do
100
- q = @b.queue('test1')
101
- @default_exchange.publish('This is another test message', :key => 'test1')
102
- msg = q.pop[:payload]
103
- msg.should == 'This is another test message'
104
- message_count(q).should == 0
105
- end
106
-
107
- it "should be able to pop a message where body length exceeds max frame size" do
108
- q = @b.queue('test1')
109
- lg_msg = 'z' * 142000
110
- @default_exchange.publish(lg_msg, :key => 'test1')
111
- msg = q.pop[:payload]
112
- msg.should == lg_msg
113
- end
114
-
115
- it "should be able call a block when popping a message" do
116
- q = @b.queue('test1')
117
- @default_exchange.publish('This is another test message', :key => 'test1')
118
- q.pop { |msg| msg[:payload].should == 'This is another test message' }
119
- q.pop { |msg| msg[:payload].should == :queue_empty }
120
- end
121
-
122
- it "should raise an error if purge fails" do
123
- q = @b.queue('test1')
124
- 5.times { @default_exchange.publish('This is another test message', :key => 'test1') }
125
- message_count(q).should == 5
126
- lambda {q.purge(:queue => 'bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
127
- end
128
-
129
- it "should be able to be purged to remove all of its messages" do
130
- q = @b.queue('test1')
131
- message_count(q).should == 5
132
- q.purge.should == :purge_ok
133
- message_count(q).should == 0
134
- end
135
-
136
- it "should return an empty message when popping an empty queue" do
137
- q = @b.queue('test1')
138
- @default_exchange.publish('This is another test message', :key => 'test1')
139
- q.pop
140
- msg = q.pop[:payload]
141
- msg.should == :queue_empty
142
- end
143
-
144
- it "should stop subscription without processing messages if max specified is 0" do
145
- q = @b.queue('test1')
146
- 5.times { @default_exchange.publish('Yet another test message', :key => 'test1') }
147
- message_count(q).should == 5
148
- q.subscribe(:message_max => 0)
149
- message_count(q).should == 5
150
- q.purge.should == :purge_ok
151
- end
152
-
153
- it "should stop subscription after processing number of messages specified > 0" do
154
- q = @b.queue('test1')
155
- 5.times { @default_exchange.publish('Yet another test message', :key => 'test1') }
156
- message_count(q).should == 5
157
- q.subscribe(:message_max => 5)
158
- end
159
-
160
- it "should stop subscription after processing message_max messages < total in queue" do
161
- q = @b.queue('test1')
162
- @b.qos()
163
- 10.times { @default_exchange.publish('Yet another test message', :key => 'test1') }
164
- message_count(q).should == 10
165
- q.subscribe(:message_max => 5, :ack => true)
166
- message_count(q).should == 5
167
- q.purge.should == :purge_ok
168
- end
169
-
170
- it "should raise an error when delete fails" do
171
- q = @b.queue('test1')
172
- lambda {q.delete(:queue => 'bogus')}.should raise_error(Bunny::ForcedChannelCloseError)
173
- @b.channel.active.should == false
174
- end
175
-
176
- it "should pass correct block parameters through on subscribe" do
177
- q = @b.queue('test1')
178
- @default_exchange.publish("messages pop'n", :key => 'test1')
179
-
180
- q.subscribe do |msg|
181
- msg[:header].should be_an_instance_of Qrack::Protocol::Header
182
- msg[:payload].should == "messages pop'n"
183
- msg[:delivery_details].should_not be_nil
184
-
185
- q.unsubscribe
186
- break
187
- end
188
- end
189
-
190
- specify "subscribe method should support cancellation through a cancellator IO object" do
191
- q = @b.queue('test1')
192
- a, b = IO.pipe
193
- b.close
194
- block_called = false
195
- q.subscribe(:cancellator => a) do |msg|
196
- block_called = true
197
- end
198
- block_called.should be_false
199
- end
200
-
201
- it "should finish processing subscription messages if break is called in block" do
202
- q = @b.queue('test1')
203
- @default_exchange.publish('messages in my quezen', :key => 'test1')
204
-
205
- q.subscribe do |msg|
206
- msg[:payload].should == 'messages in my quezen'
207
- q.unsubscribe
208
- break
209
- end
210
-
211
- 5.times {|i| @default_exchange.publish("#{i}", :key => 'test1') }
212
- q.subscribe do |msg|
213
- if msg[:payload] == '4'
214
- q.unsubscribe
215
- break
216
- end
217
- end
218
- end
219
-
220
- it "should be able to be deleted" do
221
- q = @b.queue('test1')
222
- res = q.delete
223
- res.should == :delete_ok
224
- @b.queues.has_key?('test1').should be(false)
225
- end
226
-
227
- it "should ignore the :nowait option when deleted" do
228
- q = @b.queue('test0')
229
- q.delete(:nowait => true)
230
- end
231
-
232
- it "should support server named queues" do
233
- q = @b.queue
234
- q.name.should_not == nil
235
-
236
- @b.queue(q.name).should == q
237
- q.delete
238
- end
239
-
240
- end