Merge lp:~free.ekanayaka/txamqp/distinguish-channel-and-connection-errors into lp:txamqp
- distinguish-channel-and-connection-errors
- Merge into trunk
Proposed by
Free Ekanayaka
Status: | Merged |
---|---|
Merged at revision: | 77 |
Proposed branch: | lp:~free.ekanayaka/txamqp/distinguish-channel-and-connection-errors |
Merge into: | lp:txamqp |
Diff against target: |
450 lines (+129/-34) 8 files modified
setup.py (+1/-1) src/txamqp/client.py (+22/-1) src/txamqp/protocol.py (+13/-4) src/txamqp/test/test_basic.py (+23/-7) src/txamqp/test/test_broker.py (+3/-3) src/txamqp/test/test_exchange.py (+26/-5) src/txamqp/test/test_protocol.py (+29/-1) src/txamqp/test/test_queue.py (+12/-12) |
To merge this branch: | bzr merge lp:~free.ekanayaka/txamqp/distinguish-channel-and-connection-errors |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alberto Donato (community) | Approve | ||
Review via email: mp+311633@code.launchpad.net |
Commit message
Description of the change
Sub-class the generic txamqp.
Note that these are protocol-level errors, non transport-level ones (i.e. the TCP connection is still open after they happen).
While at it, some try/except blocks were migrated to py3-compatible syntax ("Exception, e:" vs "Exception as e:").
To post a comment you must log in.
- 90. By Free Ekanayaka
-
Use py3-compatible try/except syntax
Revision history for this message
Free Ekanayaka (free.ekanayaka) : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'setup.py' | |||
2 | --- setup.py 2013-03-03 13:40:48 +0000 | |||
3 | +++ setup.py 2016-11-23 16:38:57 +0000 | |||
4 | @@ -1,6 +1,6 @@ | |||
5 | 1 | setupdict= { | 1 | setupdict= { |
6 | 2 | 'name': 'txAMQP', | 2 | 'name': 'txAMQP', |
8 | 3 | 'version': '0.6.2', | 3 | 'version': '0.7.0', |
9 | 4 | 'author': 'Esteve Fernandez', | 4 | 'author': 'Esteve Fernandez', |
10 | 5 | 'author_email': 'esteve@fluidinfo.com', | 5 | 'author_email': 'esteve@fluidinfo.com', |
11 | 6 | 'url': 'https://launchpad.net/txamqp', | 6 | 'url': 'https://launchpad.net/txamqp', |
12 | 7 | 7 | ||
13 | === modified file 'src/txamqp/client.py' | |||
14 | --- src/txamqp/client.py 2016-06-06 07:09:04 +0000 | |||
15 | +++ src/txamqp/client.py 2016-11-23 16:38:57 +0000 | |||
16 | @@ -2,12 +2,33 @@ | |||
17 | 2 | from twisted.internet import defer | 2 | from twisted.internet import defer |
18 | 3 | from txamqp.delegate import Delegate | 3 | from txamqp.delegate import Delegate |
19 | 4 | 4 | ||
20 | 5 | |||
21 | 5 | class Closed(Exception): | 6 | class Closed(Exception): |
23 | 6 | pass | 7 | """Raised if either a channel or the whole connection got closed.""" |
24 | 8 | |||
25 | 9 | |||
26 | 10 | class ChannelClosed(Closed): | ||
27 | 11 | """Raised if a channel got closed because of a channel error. | ||
28 | 12 | |||
29 | 13 | This happens when the broker sends us a 'channel-close' method. | ||
30 | 14 | |||
31 | 15 | @see: The AMQP specification for possible channel error codes. | ||
32 | 16 | """ | ||
33 | 17 | |||
34 | 18 | |||
35 | 19 | class ConnectionClosed(Closed): | ||
36 | 20 | """Raised if the connection got closed because of a connection error. | ||
37 | 21 | |||
38 | 22 | This happens when the broker sends us a 'connection-close' method. | ||
39 | 23 | |||
40 | 24 | @see: The AMQP specification for possible connection error codes. | ||
41 | 25 | """ | ||
42 | 26 | |||
43 | 7 | 27 | ||
44 | 8 | class AlreadyFiredError(Exception): | 28 | class AlreadyFiredError(Exception): |
45 | 9 | pass | 29 | pass |
46 | 10 | 30 | ||
47 | 31 | |||
48 | 11 | class TwistedEvent(object): | 32 | class TwistedEvent(object): |
49 | 12 | """ | 33 | """ |
50 | 13 | An asynchronous event that is in one of three states: | 34 | An asynchronous event that is in one of three states: |
51 | 14 | 35 | ||
52 | === modified file 'src/txamqp/protocol.py' | |||
53 | --- src/txamqp/protocol.py 2016-11-22 13:31:30 +0000 | |||
54 | +++ src/txamqp/protocol.py 2016-11-23 16:38:57 +0000 | |||
55 | @@ -10,7 +10,7 @@ | |||
56 | 10 | from txamqp.message import Message | 10 | from txamqp.message import Message |
57 | 11 | from txamqp.content import Content | 11 | from txamqp.content import Content |
58 | 12 | from txamqp.queue import TimeoutDeferredQueue, Closed as QueueClosed | 12 | from txamqp.queue import TimeoutDeferredQueue, Closed as QueueClosed |
60 | 13 | from txamqp.client import TwistedEvent, Closed | 13 | from txamqp.client import TwistedEvent, Closed, ConnectionClosed, ChannelClosed |
61 | 14 | from cStringIO import StringIO | 14 | from cStringIO import StringIO |
62 | 15 | import struct | 15 | import struct |
63 | 16 | from time import time | 16 | from time import time |
64 | @@ -66,7 +66,7 @@ | |||
65 | 66 | @defer.inlineCallbacks | 66 | @defer.inlineCallbacks |
66 | 67 | def invoke(self, method, args, content=None): | 67 | def invoke(self, method, args, content=None): |
67 | 68 | if self.closed: | 68 | if self.closed: |
69 | 69 | raise Closed(self.reason) | 69 | self._raiseClosed(self.reason) |
70 | 70 | frame = Frame(self.id, Method(method, *args)) | 70 | frame = Frame(self.id, Method(method, *args)) |
71 | 71 | self.outgoing.put(frame) | 71 | self.outgoing.put(frame) |
72 | 72 | 72 | ||
73 | @@ -96,7 +96,7 @@ | |||
74 | 96 | raise ValueError(resp) | 96 | raise ValueError(resp) |
75 | 97 | except QueueClosed, e: | 97 | except QueueClosed, e: |
76 | 98 | if self.closed: | 98 | if self.closed: |
78 | 99 | raise Closed(self.reason) | 99 | self._raiseClosed(self.reason) |
79 | 100 | else: | 100 | else: |
80 | 101 | raise e | 101 | raise e |
81 | 102 | 102 | ||
82 | @@ -112,6 +112,15 @@ | |||
83 | 112 | chunk = content.body[i:i + maxChunkSize] | 112 | chunk = content.body[i:i + maxChunkSize] |
84 | 113 | queue.put(Frame(self.id, Body(chunk))) | 113 | queue.put(Frame(self.id, Body(chunk))) |
85 | 114 | 114 | ||
86 | 115 | def _raiseClosed(self, reason): | ||
87 | 116 | """Raise the appropriate Closed-based error for the given reason.""" | ||
88 | 117 | if isinstance(reason, Message): | ||
89 | 118 | if reason.method.klass.name == "channel": | ||
90 | 119 | raise ChannelClosed(reason) | ||
91 | 120 | elif reason.method.klass.name == "connection": | ||
92 | 121 | raise ConnectionClosed(reason) | ||
93 | 122 | raise Closed(reason) | ||
94 | 123 | |||
95 | 115 | 124 | ||
96 | 116 | class FrameReceiver(protocol.Protocol, basic._PauseableMixin): | 125 | class FrameReceiver(protocol.Protocol, basic._PauseableMixin): |
97 | 117 | 126 | ||
98 | @@ -318,7 +327,7 @@ | |||
99 | 318 | cleanly, by sending a "close" method and waiting for "close-ok". If | 327 | cleanly, by sending a "close" method and waiting for "close-ok". If |
100 | 319 | no reply is received within the given amount of seconds, the | 328 | no reply is received within the given amount of seconds, the |
101 | 320 | transport will be forcely shutdown. | 329 | transport will be forcely shutdown. |
103 | 321 | """ | 330 | """ |
104 | 322 | if self.closed: | 331 | if self.closed: |
105 | 323 | return | 332 | return |
106 | 324 | 333 | ||
107 | 325 | 334 | ||
108 | === modified file 'src/txamqp/test/test_basic.py' | |||
109 | --- src/txamqp/test/test_basic.py 2016-06-08 13:10:58 +0000 | |||
110 | +++ src/txamqp/test/test_basic.py 2016-11-23 16:38:57 +0000 | |||
111 | @@ -16,10 +16,11 @@ | |||
112 | 16 | # specific language governing permissions and limitations | 16 | # specific language governing permissions and limitations |
113 | 17 | # under the License. | 17 | # under the License. |
114 | 18 | # | 18 | # |
116 | 19 | from txamqp.client import Closed | 19 | from txamqp.client import ConnectionClosed, ChannelClosed |
117 | 20 | from txamqp.queue import Empty | 20 | from txamqp.queue import Empty |
118 | 21 | from txamqp.content import Content | 21 | from txamqp.content import Content |
120 | 22 | from txamqp.testlib import TestBase, supportedBrokers, QPID, OPENAMQ | 22 | from txamqp.testlib import ( |
121 | 23 | TestBase, supportedBrokers, QPID, OPENAMQ, RABBITMQ) | ||
122 | 23 | 24 | ||
123 | 24 | from twisted.internet.defer import inlineCallbacks | 25 | from twisted.internet.defer import inlineCallbacks |
124 | 25 | 26 | ||
125 | @@ -68,7 +69,7 @@ | |||
126 | 68 | try: | 69 | try: |
127 | 69 | yield channel.basic_consume(consumer_tag="second", queue="test-queue-2") | 70 | yield channel.basic_consume(consumer_tag="second", queue="test-queue-2") |
128 | 70 | self.fail("Expected consume request to fail due to previous exclusive consumer") | 71 | self.fail("Expected consume request to fail due to previous exclusive consumer") |
130 | 71 | except Closed, e: | 72 | except ChannelClosed as e: |
131 | 72 | self.assertChannelException(403, e.args[0]) | 73 | self.assertChannelException(403, e.args[0]) |
132 | 73 | 74 | ||
133 | 74 | #open new channel and cleanup last consumer: | 75 | #open new channel and cleanup last consumer: |
134 | @@ -80,7 +81,7 @@ | |||
135 | 80 | try: | 81 | try: |
136 | 81 | yield channel.basic_consume(consumer_tag="second", queue="test-queue-2", exclusive=True) | 82 | yield channel.basic_consume(consumer_tag="second", queue="test-queue-2", exclusive=True) |
137 | 82 | self.fail("Expected exclusive consume request to fail due to previous consumer") | 83 | self.fail("Expected exclusive consume request to fail due to previous consumer") |
139 | 83 | except Closed, e: | 84 | except ChannelClosed as e: |
140 | 84 | self.assertChannelException(403, e.args[0]) | 85 | self.assertChannelException(403, e.args[0]) |
141 | 85 | 86 | ||
142 | 86 | @inlineCallbacks | 87 | @inlineCallbacks |
143 | @@ -94,7 +95,7 @@ | |||
144 | 94 | #queue specified but doesn't exist: | 95 | #queue specified but doesn't exist: |
145 | 95 | yield channel.basic_consume(queue="invalid-queue") | 96 | yield channel.basic_consume(queue="invalid-queue") |
146 | 96 | self.fail("Expected failure when consuming from non-existent queue") | 97 | self.fail("Expected failure when consuming from non-existent queue") |
148 | 97 | except Closed, e: | 98 | except ChannelClosed as e: |
149 | 98 | self.assertChannelException(404, e.args[0]) | 99 | self.assertChannelException(404, e.args[0]) |
150 | 99 | 100 | ||
151 | 100 | @supportedBrokers(QPID, OPENAMQ) | 101 | @supportedBrokers(QPID, OPENAMQ) |
152 | @@ -109,9 +110,24 @@ | |||
153 | 109 | #queue not specified and none previously declared for channel: | 110 | #queue not specified and none previously declared for channel: |
154 | 110 | yield channel.basic_consume(queue="") | 111 | yield channel.basic_consume(queue="") |
155 | 111 | self.fail("Expected failure when consuming from unspecified queue") | 112 | self.fail("Expected failure when consuming from unspecified queue") |
157 | 112 | except Closed, e: | 113 | except ConnectionClosed, e: |
158 | 113 | self.assertConnectionException(530, e.args[0]) | 114 | self.assertConnectionException(530, e.args[0]) |
159 | 114 | 115 | ||
160 | 116 | @supportedBrokers(RABBITMQ) | ||
161 | 117 | @inlineCallbacks | ||
162 | 118 | def test_consume_queue_unspecified_rabbit(self): | ||
163 | 119 | """ | ||
164 | 120 | C{basic_consume} fails with a channel exception with a C{404} code | ||
165 | 121 | when no queue is specified. | ||
166 | 122 | """ | ||
167 | 123 | channel = self.channel | ||
168 | 124 | try: | ||
169 | 125 | #queue not specified and none previously declared for channel: | ||
170 | 126 | yield channel.basic_consume(queue="") | ||
171 | 127 | self.fail("Expected failure when consuming from unspecified queue") | ||
172 | 128 | except ChannelClosed as e: | ||
173 | 129 | self.assertChannelException(404, e.args[0]) | ||
174 | 130 | |||
175 | 115 | @inlineCallbacks | 131 | @inlineCallbacks |
176 | 116 | def test_consume_unique_consumers(self): | 132 | def test_consume_unique_consumers(self): |
177 | 117 | """ | 133 | """ |
178 | @@ -126,7 +142,7 @@ | |||
179 | 126 | try: | 142 | try: |
180 | 127 | yield channel.basic_consume(consumer_tag="first", queue="test-queue-3") | 143 | yield channel.basic_consume(consumer_tag="first", queue="test-queue-3") |
181 | 128 | self.fail("Expected consume request to fail due to non-unique tag") | 144 | self.fail("Expected consume request to fail due to non-unique tag") |
183 | 129 | except Closed, e: | 145 | except ConnectionClosed, e: |
184 | 130 | self.assertConnectionException(530, e.args[0]) | 146 | self.assertConnectionException(530, e.args[0]) |
185 | 131 | 147 | ||
186 | 132 | @inlineCallbacks | 148 | @inlineCallbacks |
187 | 133 | 149 | ||
188 | === modified file 'src/txamqp/test/test_broker.py' | |||
189 | --- src/txamqp/test/test_broker.py 2016-06-06 07:09:04 +0000 | |||
190 | +++ src/txamqp/test/test_broker.py 2016-11-23 16:38:57 +0000 | |||
191 | @@ -16,7 +16,7 @@ | |||
192 | 16 | # specific language governing permissions and limitations | 16 | # specific language governing permissions and limitations |
193 | 17 | # under the License. | 17 | # under the License. |
194 | 18 | # | 18 | # |
196 | 19 | from txamqp.client import Closed | 19 | from txamqp.client import ConnectionClosed |
197 | 20 | from txamqp.queue import Empty | 20 | from txamqp.queue import Empty |
198 | 21 | from txamqp.content import Content | 21 | from txamqp.content import Content |
199 | 22 | from txamqp.testlib import TestBase, supportedBrokers, QPID, OPENAMQ | 22 | from txamqp.testlib import TestBase, supportedBrokers, QPID, OPENAMQ |
200 | @@ -132,7 +132,7 @@ | |||
201 | 132 | try: | 132 | try: |
202 | 133 | yield channel.queue_declare(exclusive=True) | 133 | yield channel.queue_declare(exclusive=True) |
203 | 134 | self.fail("Expected error on queue_declare for invalid channel") | 134 | self.fail("Expected error on queue_declare for invalid channel") |
205 | 135 | except Closed, e: | 135 | except ConnectionClosed as e: |
206 | 136 | self.assertConnectionException(504, e.args[0]) | 136 | self.assertConnectionException(504, e.args[0]) |
207 | 137 | 137 | ||
208 | 138 | @inlineCallbacks | 138 | @inlineCallbacks |
209 | @@ -143,7 +143,7 @@ | |||
210 | 143 | try: | 143 | try: |
211 | 144 | yield channel.queue_declare(exclusive=True) | 144 | yield channel.queue_declare(exclusive=True) |
212 | 145 | self.fail("Expected error on queue_declare for closed channel") | 145 | self.fail("Expected error on queue_declare for closed channel") |
214 | 146 | except Closed, e: | 146 | except ConnectionClosed as e: |
215 | 147 | self.assertConnectionException(504, e.args[0]) | 147 | self.assertConnectionException(504, e.args[0]) |
216 | 148 | 148 | ||
217 | 149 | @supportedBrokers(QPID, OPENAMQ) | 149 | @supportedBrokers(QPID, OPENAMQ) |
218 | 150 | 150 | ||
219 | === modified file 'src/txamqp/test/test_exchange.py' | |||
220 | --- src/txamqp/test/test_exchange.py 2011-02-08 12:34:54 +0000 | |||
221 | +++ src/txamqp/test/test_exchange.py 2016-11-23 16:38:57 +0000 | |||
222 | @@ -24,9 +24,9 @@ | |||
223 | 24 | """ | 24 | """ |
224 | 25 | 25 | ||
225 | 26 | from txamqp.queue import Empty | 26 | from txamqp.queue import Empty |
227 | 27 | from txamqp.testlib import TestBase, supportedBrokers, QPID, OPENAMQ | 27 | from txamqp.testlib import TestBase, supportedBrokers, QPID, OPENAMQ, RABBITMQ |
228 | 28 | from txamqp.content import Content | 28 | from txamqp.content import Content |
230 | 29 | from txamqp.client import Closed | 29 | from txamqp.client import ChannelClosed, ConnectionClosed |
231 | 30 | 30 | ||
232 | 31 | from twisted.internet.defer import inlineCallbacks | 31 | from twisted.internet.defer import inlineCallbacks |
233 | 32 | 32 | ||
234 | @@ -238,7 +238,7 @@ | |||
235 | 238 | try: | 238 | try: |
236 | 239 | yield self.channel.exchange_declare(exchange="humpty_dumpty", passive=True) | 239 | yield self.channel.exchange_declare(exchange="humpty_dumpty", passive=True) |
237 | 240 | self.fail("Expected 404 for passive declaration of unknown exchange.") | 240 | self.fail("Expected 404 for passive declaration of unknown exchange.") |
239 | 241 | except Closed, e: | 241 | except ChannelClosed as e: |
240 | 242 | self.assertChannelException(404, e.args[0]) | 242 | self.assertChannelException(404, e.args[0]) |
241 | 243 | 243 | ||
242 | 244 | 244 | ||
243 | @@ -334,7 +334,7 @@ | |||
244 | 334 | try: | 334 | try: |
245 | 335 | yield self.channel.exchange_declare(exchange="test_type_not_known_exchange", type="invalid_type") | 335 | yield self.channel.exchange_declare(exchange="test_type_not_known_exchange", type="invalid_type") |
246 | 336 | self.fail("Expected 503 for declaration of unknown exchange type.") | 336 | self.fail("Expected 503 for declaration of unknown exchange type.") |
248 | 337 | except Closed, e: | 337 | except ConnectionClosed as e: |
249 | 338 | self.assertConnectionException(503, e.args[0]) | 338 | self.assertConnectionException(503, e.args[0]) |
250 | 339 | 339 | ||
251 | 340 | @supportedBrokers(QPID, OPENAMQ) | 340 | @supportedBrokers(QPID, OPENAMQ) |
252 | @@ -344,7 +344,7 @@ | |||
253 | 344 | try: | 344 | try: |
254 | 345 | yield self.channel.exchange_declare(exchange="test_different_declared_type_exchange", type="topic") | 345 | yield self.channel.exchange_declare(exchange="test_different_declared_type_exchange", type="topic") |
255 | 346 | self.fail("Expected 530 for redeclaration of exchange with different type.") | 346 | self.fail("Expected 530 for redeclaration of exchange with different type.") |
257 | 347 | except Closed, e: | 347 | except ConnectionClosed as e: |
258 | 348 | self.assertConnectionException(530, e.args[0]) | 348 | self.assertConnectionException(530, e.args[0]) |
259 | 349 | #cleanup | 349 | #cleanup |
260 | 350 | other = yield self.connect() | 350 | other = yield self.connect() |
261 | @@ -352,3 +352,24 @@ | |||
262 | 352 | yield c2.channel_open() | 352 | yield c2.channel_open() |
263 | 353 | yield c2.exchange_delete(exchange="test_different_declared_type_exchange") | 353 | yield c2.exchange_delete(exchange="test_different_declared_type_exchange") |
264 | 354 | 354 | ||
265 | 355 | @supportedBrokers(RABBITMQ) | ||
266 | 356 | @inlineCallbacks | ||
267 | 357 | def testDifferentDeclaredTypeRabbit(self): | ||
268 | 358 | """Test redeclaration of exchange with different type on RabbitMQ.""" | ||
269 | 359 | yield self.channel.exchange_declare( | ||
270 | 360 | exchange="test_different_declared_type_exchange", type="direct") | ||
271 | 361 | try: | ||
272 | 362 | yield self.channel.exchange_declare( | ||
273 | 363 | exchange="test_different_declared_type_exchange", type="topic") | ||
274 | 364 | self.fail( | ||
275 | 365 | "Expected 406 for redeclaration of exchange with " | ||
276 | 366 | "different type.") | ||
277 | 367 | except ChannelClosed as e: | ||
278 | 368 | self.assertChannelException(406, e.args[0]) | ||
279 | 369 | finally: | ||
280 | 370 | # cleanup | ||
281 | 371 | other = yield self.connect() | ||
282 | 372 | c2 = yield other.channel(1) | ||
283 | 373 | yield c2.channel_open() | ||
284 | 374 | yield c2.exchange_delete( | ||
285 | 375 | exchange="test_different_declared_type_exchange") | ||
286 | 355 | 376 | ||
287 | === modified file 'src/txamqp/test/test_protocol.py' | |||
288 | --- src/txamqp/test/test_protocol.py 2016-06-06 07:09:04 +0000 | |||
289 | +++ src/txamqp/test/test_protocol.py 2016-11-23 16:38:57 +0000 | |||
290 | @@ -4,7 +4,8 @@ | |||
291 | 4 | from twisted.logger import Logger | 4 | from twisted.logger import Logger |
292 | 5 | 5 | ||
293 | 6 | from txamqp.protocol import AMQClient | 6 | from txamqp.protocol import AMQClient |
295 | 7 | from txamqp.client import TwistedDelegate, Closed | 7 | from txamqp.client import ( |
296 | 8 | TwistedDelegate, Closed, ConnectionClosed, ChannelClosed) | ||
297 | 8 | from txamqp.testing import AMQPump | 9 | from txamqp.testing import AMQPump |
298 | 9 | from txamqp.spec import DEFAULT_SPEC, load | 10 | from txamqp.spec import DEFAULT_SPEC, load |
299 | 10 | from txamqp.queue import Closed as QueueClosed | 11 | from txamqp.queue import Closed as QueueClosed |
300 | @@ -34,6 +35,14 @@ | |||
301 | 34 | channel0 = self.successResultOf(self.protocol.channel(0)) | 35 | channel0 = self.successResultOf(self.protocol.channel(0)) |
302 | 35 | self.assertTrue(channel0.closed) | 36 | self.assertTrue(channel0.closed) |
303 | 36 | 37 | ||
304 | 38 | def test_connection_close_raises_error(self): | ||
305 | 39 | """Test receiving a connection-close method raises ConnectionClosed.""" | ||
306 | 40 | channel = self.successResultOf(self.protocol.channel(0)) | ||
307 | 41 | d = channel.basic_consume(queue="test-queue") | ||
308 | 42 | self.transport.channel(0).connection_close(reply_code=320) | ||
309 | 43 | failure = self.failureResultOf(d) | ||
310 | 44 | self.assertIsInstance(failure.value, ConnectionClosed) | ||
311 | 45 | |||
312 | 37 | def test_close(self): | 46 | def test_close(self): |
313 | 38 | """Test explicitely closing a client.""" | 47 | """Test explicitely closing a client.""" |
314 | 39 | d = self.protocol.close() | 48 | d = self.protocol.close() |
315 | @@ -106,6 +115,25 @@ | |||
316 | 106 | self.assertIsInstance(failure.value, Closed) | 115 | self.assertIsInstance(failure.value, Closed) |
317 | 107 | self.assertIsInstance(failure.value.args[0].value, ConnectionLost) | 116 | self.assertIsInstance(failure.value.args[0].value, ConnectionLost) |
318 | 108 | 117 | ||
319 | 118 | def test_channel_close(self): | ||
320 | 119 | """Test receiving a channel-close method raises ChannelClosed.""" | ||
321 | 120 | channel = self.successResultOf(self.protocol.channel(0)) | ||
322 | 121 | d = channel.basic_consume(queue="non-existing-queue") | ||
323 | 122 | self.transport.channel(0).channel_close(reply_code=404) | ||
324 | 123 | failure = self.failureResultOf(d) | ||
325 | 124 | self.assertIsInstance(failure.value, ChannelClosed) | ||
326 | 125 | |||
327 | 126 | def test_sending_method_on_closed_channel(self): | ||
328 | 127 | """Sending a method on a closed channel fails immediately.""" | ||
329 | 128 | channel = self.successResultOf(self.protocol.channel(0)) | ||
330 | 129 | self.transport.channel(0).connection_close(reply_code=320) | ||
331 | 130 | self.transport.outgoing.clear() | ||
332 | 131 | d = channel.basic_consume(queue="test-queue") | ||
333 | 132 | # No frames were sent | ||
334 | 133 | self.assertEqual({}, self.transport.outgoing) | ||
335 | 134 | failure = self.failureResultOf(d) | ||
336 | 135 | self.assertIsInstance(failure.value, ConnectionClosed) | ||
337 | 136 | |||
338 | 109 | def test_disconnected_event(self): | 137 | def test_disconnected_event(self): |
339 | 110 | """Test disconnected event fired after the connection is lost.""" | 138 | """Test disconnected event fired after the connection is lost.""" |
340 | 111 | deferred = self.protocol.disconnected.wait() | 139 | deferred = self.protocol.disconnected.wait() |
341 | 112 | 140 | ||
342 | === modified file 'src/txamqp/test/test_queue.py' | |||
343 | --- src/txamqp/test/test_queue.py 2016-05-23 14:41:22 +0000 | |||
344 | +++ src/txamqp/test/test_queue.py 2016-11-23 16:38:57 +0000 | |||
345 | @@ -64,7 +64,7 @@ | |||
346 | 64 | #queue specified but doesn't exist: | 64 | #queue specified but doesn't exist: |
347 | 65 | yield channel.queue_purge(queue="invalid-queue") | 65 | yield channel.queue_purge(queue="invalid-queue") |
348 | 66 | self.fail("Expected failure when purging non-existent queue") | 66 | self.fail("Expected failure when purging non-existent queue") |
350 | 67 | except Closed, e: | 67 | except Closed as e: |
351 | 68 | self.assertChannelException(404, e.args[0]) | 68 | self.assertChannelException(404, e.args[0]) |
352 | 69 | 69 | ||
353 | 70 | channel = yield self.client.channel(3) | 70 | channel = yield self.client.channel(3) |
354 | @@ -73,7 +73,7 @@ | |||
355 | 73 | #queue not specified and none previously declared for channel: | 73 | #queue not specified and none previously declared for channel: |
356 | 74 | yield channel.queue_purge() | 74 | yield channel.queue_purge() |
357 | 75 | self.fail("Expected failure when purging unspecified queue") | 75 | self.fail("Expected failure when purging unspecified queue") |
359 | 76 | except Closed, e: | 76 | except Closed as e: |
360 | 77 | self.assertConnectionException(530, e.args[0]) | 77 | self.assertConnectionException(530, e.args[0]) |
361 | 78 | 78 | ||
362 | 79 | #cleanup | 79 | #cleanup |
363 | @@ -100,7 +100,7 @@ | |||
364 | 100 | #other connection should not be allowed to declare this: | 100 | #other connection should not be allowed to declare this: |
365 | 101 | yield c2.queue_declare(queue="exclusive-queue", exclusive="True") | 101 | yield c2.queue_declare(queue="exclusive-queue", exclusive="True") |
366 | 102 | self.fail("Expected second exclusive queue_declare to raise a channel exception") | 102 | self.fail("Expected second exclusive queue_declare to raise a channel exception") |
368 | 103 | except Closed, e: | 103 | except Closed as e: |
369 | 104 | self.assertChannelException(405, e.args[0]) | 104 | self.assertChannelException(405, e.args[0]) |
370 | 105 | 105 | ||
371 | 106 | @inlineCallbacks | 106 | @inlineCallbacks |
372 | @@ -116,7 +116,7 @@ | |||
373 | 116 | #other connection should not be allowed to declare this: | 116 | #other connection should not be allowed to declare this: |
374 | 117 | yield channel.queue_declare(queue="passive-queue-2", passive="True") | 117 | yield channel.queue_declare(queue="passive-queue-2", passive="True") |
375 | 118 | self.fail("Expected passive declaration of non-existant queue to raise a channel exception") | 118 | self.fail("Expected passive declaration of non-existant queue to raise a channel exception") |
377 | 119 | except Closed, e: | 119 | except Closed as e: |
378 | 120 | self.assertChannelException(404, e.args[0]) | 120 | self.assertChannelException(404, e.args[0]) |
379 | 121 | 121 | ||
380 | 122 | @inlineCallbacks | 122 | @inlineCallbacks |
381 | @@ -140,7 +140,7 @@ | |||
382 | 140 | try: | 140 | try: |
383 | 141 | yield channel.queue_bind(queue="queue-1", exchange="an-invalid-exchange", routing_key="key1") | 141 | yield channel.queue_bind(queue="queue-1", exchange="an-invalid-exchange", routing_key="key1") |
384 | 142 | self.fail("Expected bind to non-existant exchange to fail") | 142 | self.fail("Expected bind to non-existant exchange to fail") |
386 | 143 | except Closed, e: | 143 | except Closed as e: |
387 | 144 | self.assertChannelException(404, e.args[0]) | 144 | self.assertChannelException(404, e.args[0]) |
388 | 145 | 145 | ||
389 | 146 | #need to reopen a channel: | 146 | #need to reopen a channel: |
390 | @@ -151,7 +151,7 @@ | |||
391 | 151 | try: | 151 | try: |
392 | 152 | yield channel.queue_bind(queue="queue-2", exchange="amq.direct", routing_key="key1") | 152 | yield channel.queue_bind(queue="queue-2", exchange="amq.direct", routing_key="key1") |
393 | 153 | self.fail("Expected bind of non-existant queue to fail") | 153 | self.fail("Expected bind of non-existant queue to fail") |
395 | 154 | except Closed, e: | 154 | except Closed as e: |
396 | 155 | self.assertChannelException(404, e.args[0]) | 155 | self.assertChannelException(404, e.args[0]) |
397 | 156 | 156 | ||
398 | 157 | @inlineCallbacks | 157 | @inlineCallbacks |
399 | @@ -172,7 +172,7 @@ | |||
400 | 172 | try: | 172 | try: |
401 | 173 | yield channel.queue_declare(queue="delete-me", passive="True") | 173 | yield channel.queue_declare(queue="delete-me", passive="True") |
402 | 174 | self.fail("Queue has not been deleted") | 174 | self.fail("Queue has not been deleted") |
404 | 175 | except Closed, e: | 175 | except Closed as e: |
405 | 176 | self.assertChannelException(404, e.args[0]) | 176 | self.assertChannelException(404, e.args[0]) |
406 | 177 | 177 | ||
407 | 178 | @inlineCallbacks | 178 | @inlineCallbacks |
408 | @@ -200,7 +200,7 @@ | |||
409 | 200 | result = yield channel.queue_delete(queue="i-dont-exist", if_empty="True") | 200 | result = yield channel.queue_delete(queue="i-dont-exist", if_empty="True") |
410 | 201 | print result | 201 | print result |
411 | 202 | self.fail("Expected delete of non-existant queue to fail") | 202 | self.fail("Expected delete of non-existant queue to fail") |
413 | 203 | except Closed, e: | 203 | except Closed as e: |
414 | 204 | self.assertChannelException(404, e.args[0]) | 204 | self.assertChannelException(404, e.args[0]) |
415 | 205 | 205 | ||
416 | 206 | @inlineCallbacks | 206 | @inlineCallbacks |
417 | @@ -219,7 +219,7 @@ | |||
418 | 219 | try: | 219 | try: |
419 | 220 | yield channel.queue_delete(queue="delete-me-2", if_empty="True") | 220 | yield channel.queue_delete(queue="delete-me-2", if_empty="True") |
420 | 221 | self.fail("Expected delete if_empty to fail for non-empty queue") | 221 | self.fail("Expected delete if_empty to fail for non-empty queue") |
422 | 222 | except Closed, e: | 222 | except Closed as e: |
423 | 223 | self.assertChannelException(406, e.args[0]) | 223 | self.assertChannelException(406, e.args[0]) |
424 | 224 | 224 | ||
425 | 225 | #need new channel now: | 225 | #need new channel now: |
426 | @@ -240,7 +240,7 @@ | |||
427 | 240 | try: | 240 | try: |
428 | 241 | yield channel.queue_declare(queue="delete-me-2", passive="True") | 241 | yield channel.queue_declare(queue="delete-me-2", passive="True") |
429 | 242 | self.fail("Queue has not been deleted") | 242 | self.fail("Queue has not been deleted") |
431 | 243 | except Closed, e: | 243 | except Closed as e: |
432 | 244 | self.assertChannelException(404, e.args[0]) | 244 | self.assertChannelException(404, e.args[0]) |
433 | 245 | 245 | ||
434 | 246 | @inlineCallbacks | 246 | @inlineCallbacks |
435 | @@ -262,7 +262,7 @@ | |||
436 | 262 | try: | 262 | try: |
437 | 263 | yield channel2.queue_delete(queue="delete-me-3", if_unused="True") | 263 | yield channel2.queue_delete(queue="delete-me-3", if_unused="True") |
438 | 264 | self.fail("Expected delete if_unused to fail for queue with existing consumer") | 264 | self.fail("Expected delete if_unused to fail for queue with existing consumer") |
440 | 265 | except Closed, e: | 265 | except Closed as e: |
441 | 266 | self.assertChannelException(406, e.args[0]) | 266 | self.assertChannelException(406, e.args[0]) |
442 | 267 | 267 | ||
443 | 268 | 268 | ||
444 | @@ -272,7 +272,7 @@ | |||
445 | 272 | try: | 272 | try: |
446 | 273 | yield channel.queue_declare(queue="delete-me-3", passive="True") | 273 | yield channel.queue_declare(queue="delete-me-3", passive="True") |
447 | 274 | self.fail("Queue has not been deleted") | 274 | self.fail("Queue has not been deleted") |
449 | 275 | except Closed, e: | 275 | except Closed as e: |
450 | 276 | self.assertChannelException(404, e.args[0]) | 276 | self.assertChannelException(404, e.args[0]) |
451 | 277 | 277 | ||
452 | 278 | 278 |
nice, +1
just a few nits inline