Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_messaging.py 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. from __future__ import absolute_import, unicode_literals
  2. import anyjson
  3. import pickle
  4. from collections import defaultdict
  5. from kombu import Connection, Consumer, Producer, Exchange, Queue
  6. from kombu.exceptions import MessageStateError
  7. from kombu.utils import ChannelPromise
  8. from .case import Case, Mock, patch
  9. from .mocks import Transport
  10. class test_Producer(Case):
  11. def setUp(self):
  12. self.exchange = Exchange('foo', 'direct')
  13. self.connection = Connection(transport=Transport)
  14. self.connection.connect()
  15. self.assertTrue(self.connection.connection.connected)
  16. self.assertFalse(self.exchange.is_bound)
  17. def test_repr(self):
  18. p = Producer(self.connection)
  19. self.assertTrue(repr(p))
  20. def test_pickle(self):
  21. chan = Mock()
  22. producer = Producer(chan, serializer='pickle')
  23. p2 = pickle.loads(pickle.dumps(producer))
  24. self.assertEqual(p2.serializer, producer.serializer)
  25. def test_no_channel(self):
  26. p = Producer(None)
  27. self.assertFalse(p._channel)
  28. @patch('kombu.messaging.maybe_declare')
  29. def test_maybe_declare(self, maybe_declare):
  30. p = self.connection.Producer()
  31. q = Queue('foo')
  32. p.maybe_declare(q)
  33. maybe_declare.assert_called_with(q, p.channel, False)
  34. @patch('kombu.common.maybe_declare')
  35. def test_maybe_declare_when_entity_false(self, maybe_declare):
  36. p = self.connection.Producer()
  37. p.maybe_declare(None)
  38. self.assertFalse(maybe_declare.called)
  39. def test_auto_declare(self):
  40. channel = self.connection.channel()
  41. p = Producer(channel, self.exchange, auto_declare=True)
  42. self.assertIsNot(p.exchange, self.exchange,
  43. 'creates Exchange clone at bind')
  44. self.assertTrue(p.exchange.is_bound)
  45. self.assertIn('exchange_declare', channel,
  46. 'auto_declare declares exchange')
  47. def test_manual_declare(self):
  48. channel = self.connection.channel()
  49. p = Producer(channel, self.exchange, auto_declare=False)
  50. self.assertTrue(p.exchange.is_bound)
  51. self.assertNotIn('exchange_declare', channel,
  52. 'auto_declare=False does not declare exchange')
  53. p.declare()
  54. self.assertIn('exchange_declare', channel,
  55. 'p.declare() declares exchange')
  56. def test_prepare(self):
  57. message = {'the quick brown fox': 'jumps over the lazy dog'}
  58. channel = self.connection.channel()
  59. p = Producer(channel, self.exchange, serializer='json')
  60. m, ctype, cencoding = p._prepare(message, headers={})
  61. self.assertDictEqual(message, anyjson.loads(m))
  62. self.assertEqual(ctype, 'application/json')
  63. self.assertEqual(cencoding, 'utf-8')
  64. def test_prepare_compression(self):
  65. message = {'the quick brown fox': 'jumps over the lazy dog'}
  66. channel = self.connection.channel()
  67. p = Producer(channel, self.exchange, serializer='json')
  68. headers = {}
  69. m, ctype, cencoding = p._prepare(message, compression='zlib',
  70. headers=headers)
  71. self.assertEqual(ctype, 'application/json')
  72. self.assertEqual(cencoding, 'utf-8')
  73. self.assertEqual(headers['compression'], 'application/x-gzip')
  74. import zlib
  75. self.assertEqual(
  76. anyjson.loads(zlib.decompress(m).decode('utf-8')),
  77. message,
  78. )
  79. def test_prepare_custom_content_type(self):
  80. message = 'the quick brown fox'.encode('utf-8')
  81. channel = self.connection.channel()
  82. p = Producer(channel, self.exchange, serializer='json')
  83. m, ctype, cencoding = p._prepare(message, content_type='custom')
  84. self.assertEqual(m, message)
  85. self.assertEqual(ctype, 'custom')
  86. self.assertEqual(cencoding, 'binary')
  87. m, ctype, cencoding = p._prepare(message, content_type='custom',
  88. content_encoding='alien')
  89. self.assertEqual(m, message)
  90. self.assertEqual(ctype, 'custom')
  91. self.assertEqual(cencoding, 'alien')
  92. def test_prepare_is_already_unicode(self):
  93. message = 'the quick brown fox'
  94. channel = self.connection.channel()
  95. p = Producer(channel, self.exchange, serializer='json')
  96. m, ctype, cencoding = p._prepare(message, content_type='text/plain')
  97. self.assertEqual(m, message.encode('utf-8'))
  98. self.assertEqual(ctype, 'text/plain')
  99. self.assertEqual(cencoding, 'utf-8')
  100. m, ctype, cencoding = p._prepare(message, content_type='text/plain',
  101. content_encoding='utf-8')
  102. self.assertEqual(m, message.encode('utf-8'))
  103. self.assertEqual(ctype, 'text/plain')
  104. self.assertEqual(cencoding, 'utf-8')
  105. def test_publish_with_Exchange_instance(self):
  106. p = self.connection.Producer()
  107. p.channel = Mock()
  108. p.publish('hello', exchange=Exchange('foo'), delivery_mode='transient')
  109. self.assertEqual(
  110. p._channel.basic_publish.call_args[1]['exchange'], 'foo',
  111. )
  112. def test_set_on_return(self):
  113. chan = Mock()
  114. chan.events = defaultdict(Mock)
  115. p = Producer(ChannelPromise(lambda: chan), on_return='on_return')
  116. p.channel
  117. chan.events['basic_return'].add.assert_called_with('on_return')
  118. def test_publish_retry_calls_ensure(self):
  119. p = Producer(Mock())
  120. p._connection = Mock()
  121. ensure = p.connection.ensure = Mock()
  122. p.publish('foo', exchange='foo', retry=True)
  123. self.assertTrue(ensure.called)
  124. def test_publish_retry_with_declare(self):
  125. p = self.connection.Producer()
  126. p.maybe_declare = Mock()
  127. p.connection.ensure = Mock()
  128. ex = Exchange('foo')
  129. p._publish('hello', 0, '', '', {}, {}, 'rk', 0, 0, ex, declare=[ex])
  130. p.maybe_declare.assert_called_with(ex)
  131. def test_revive_when_channel_is_connection(self):
  132. p = self.connection.Producer()
  133. p.exchange = Mock()
  134. new_conn = Connection('memory://')
  135. defchan = new_conn.default_channel
  136. p.revive(new_conn)
  137. self.assertIs(p.channel, defchan)
  138. p.exchange.revive.assert_called_with(defchan)
  139. def test_enter_exit(self):
  140. p = self.connection.Producer()
  141. p.release = Mock()
  142. self.assertIs(p.__enter__(), p)
  143. p.__exit__()
  144. p.release.assert_called_with()
  145. def test_connection_property_handles_AttributeError(self):
  146. p = self.connection.Producer()
  147. p.channel = object()
  148. p.__connection__ = None
  149. self.assertIsNone(p.connection)
  150. def test_publish(self):
  151. channel = self.connection.channel()
  152. p = Producer(channel, self.exchange, serializer='json')
  153. message = {'the quick brown fox': 'jumps over the lazy dog'}
  154. ret = p.publish(message, routing_key='process')
  155. self.assertIn('prepare_message', channel)
  156. self.assertIn('basic_publish', channel)
  157. m, exc, rkey = ret
  158. self.assertDictEqual(message, anyjson.loads(m['body']))
  159. self.assertDictContainsSubset({'content_type': 'application/json',
  160. 'content_encoding': 'utf-8',
  161. 'priority': 0}, m)
  162. self.assertDictContainsSubset({'delivery_mode': 2}, m['properties'])
  163. self.assertEqual(exc, p.exchange.name)
  164. self.assertEqual(rkey, 'process')
  165. def test_no_exchange(self):
  166. chan = self.connection.channel()
  167. p = Producer(chan)
  168. self.assertFalse(p.exchange.name)
  169. def test_revive(self):
  170. chan = self.connection.channel()
  171. p = Producer(chan)
  172. chan2 = self.connection.channel()
  173. p.revive(chan2)
  174. self.assertIs(p.channel, chan2)
  175. self.assertIs(p.exchange.channel, chan2)
  176. def test_on_return(self):
  177. chan = self.connection.channel()
  178. def on_return(exception, exchange, routing_key, message):
  179. pass
  180. p = Producer(chan, on_return=on_return)
  181. self.assertTrue(on_return in chan.events['basic_return'])
  182. self.assertTrue(p.on_return)
  183. class test_Consumer(Case):
  184. def setUp(self):
  185. self.connection = Connection(transport=Transport)
  186. self.connection.connect()
  187. self.assertTrue(self.connection.connection.connected)
  188. self.exchange = Exchange('foo', 'direct')
  189. def test_accept(self):
  190. a = Consumer(self.connection)
  191. self.assertIsNone(a.accept)
  192. b = Consumer(self.connection, accept=['json', 'pickle'])
  193. self.assertSetEqual(
  194. b.accept,
  195. set(['application/json', 'application/x-python-serialize']),
  196. )
  197. c = Consumer(self.connection, accept=b.accept)
  198. self.assertSetEqual(b.accept, c.accept)
  199. def test_enter_exit_cancel_raises(self):
  200. c = Consumer(self.connection)
  201. c.cancel = Mock(name='Consumer.cancel')
  202. c.cancel.side_effect = KeyError('foo')
  203. with c:
  204. pass
  205. c.cancel.assert_called_with()
  206. def test_receive_callback_accept(self):
  207. message = Mock(name='Message')
  208. message.errors = []
  209. callback = Mock(name='on_message')
  210. c = Consumer(self.connection, accept=['json'], on_message=callback)
  211. c.on_decode_error = None
  212. c.channel = Mock(name='channel')
  213. c.channel.message_to_python = None
  214. c._receive_callback(message)
  215. callback.assert_called_with(message)
  216. self.assertSetEqual(message.accept, c.accept)
  217. def test_accept__content_disallowed(self):
  218. conn = Connection('memory://')
  219. q = Queue('foo', exchange=self.exchange)
  220. p = conn.Producer()
  221. p.publish(
  222. {'complex': object()},
  223. declare=[q], exchange=self.exchange, serializer='pickle',
  224. )
  225. callback = Mock(name='callback')
  226. with conn.Consumer(queues=[q], callbacks=[callback]) as consumer:
  227. with self.assertRaises(consumer.ContentDisallowed):
  228. conn.drain_events(timeout=1)
  229. self.assertFalse(callback.called)
  230. def test_accept__content_allowed(self):
  231. conn = Connection('memory://')
  232. q = Queue('foo', exchange=self.exchange)
  233. p = conn.Producer()
  234. p.publish(
  235. {'complex': object()},
  236. declare=[q], exchange=self.exchange, serializer='pickle',
  237. )
  238. callback = Mock(name='callback')
  239. with conn.Consumer(queues=[q], accept=['pickle'],
  240. callbacks=[callback]):
  241. conn.drain_events(timeout=1)
  242. self.assertTrue(callback.called)
  243. body, message = callback.call_args[0]
  244. self.assertTrue(body['complex'])
  245. def test_set_no_channel(self):
  246. c = Consumer(None)
  247. self.assertIsNone(c.channel)
  248. c.revive(Mock())
  249. self.assertTrue(c.channel)
  250. def test_set_no_ack(self):
  251. channel = self.connection.channel()
  252. queue = Queue('qname', self.exchange, 'rkey')
  253. consumer = Consumer(channel, queue, auto_declare=True, no_ack=True)
  254. self.assertTrue(consumer.no_ack)
  255. def test_add_queue_when_auto_declare(self):
  256. consumer = self.connection.Consumer(auto_declare=True)
  257. q = Mock()
  258. q.return_value = q
  259. consumer.add_queue(q)
  260. self.assertIn(q, consumer.queues)
  261. q.declare.assert_called_with()
  262. def test_add_queue_when_not_auto_declare(self):
  263. consumer = self.connection.Consumer(auto_declare=False)
  264. q = Mock()
  265. q.return_value = q
  266. consumer.add_queue(q)
  267. self.assertIn(q, consumer.queues)
  268. self.assertFalse(q.declare.call_count)
  269. def test_consume_without_queues_returns(self):
  270. consumer = self.connection.Consumer()
  271. consumer.queues[:] = []
  272. self.assertIsNone(consumer.consume())
  273. def test_consuming_from(self):
  274. consumer = self.connection.Consumer()
  275. consumer.queues[:] = [Queue('a'), Queue('b'), Queue('d')]
  276. consumer._active_tags = {'a': 1, 'b': 2}
  277. self.assertFalse(consumer.consuming_from(Queue('c')))
  278. self.assertFalse(consumer.consuming_from('c'))
  279. self.assertFalse(consumer.consuming_from(Queue('d')))
  280. self.assertFalse(consumer.consuming_from('d'))
  281. self.assertTrue(consumer.consuming_from(Queue('a')))
  282. self.assertTrue(consumer.consuming_from(Queue('b')))
  283. self.assertTrue(consumer.consuming_from('b'))
  284. def test_receive_callback_without_m2p(self):
  285. channel = self.connection.channel()
  286. c = channel.Consumer()
  287. m2p = getattr(channel, 'message_to_python')
  288. channel.message_to_python = None
  289. try:
  290. message = Mock()
  291. message.errors = []
  292. message.decode.return_value = 'Hello'
  293. recv = c.receive = Mock()
  294. c._receive_callback(message)
  295. recv.assert_called_with('Hello', message)
  296. finally:
  297. channel.message_to_python = m2p
  298. def test_set_callbacks(self):
  299. channel = self.connection.channel()
  300. queue = Queue('qname', self.exchange, 'rkey')
  301. callbacks = [lambda x, y: x,
  302. lambda x, y: x]
  303. consumer = Consumer(channel, queue, auto_declare=True,
  304. callbacks=callbacks)
  305. self.assertEqual(consumer.callbacks, callbacks)
  306. def test_auto_declare(self):
  307. channel = self.connection.channel()
  308. queue = Queue('qname', self.exchange, 'rkey')
  309. consumer = Consumer(channel, queue, auto_declare=True)
  310. consumer.consume()
  311. consumer.consume() # twice is a noop
  312. self.assertIsNot(consumer.queues[0], queue)
  313. self.assertTrue(consumer.queues[0].is_bound)
  314. self.assertTrue(consumer.queues[0].exchange.is_bound)
  315. self.assertIsNot(consumer.queues[0].exchange, self.exchange)
  316. for meth in ('exchange_declare',
  317. 'queue_declare',
  318. 'queue_bind',
  319. 'basic_consume'):
  320. self.assertIn(meth, channel)
  321. self.assertEqual(channel.called.count('basic_consume'), 1)
  322. self.assertTrue(consumer._active_tags)
  323. consumer.cancel_by_queue(queue.name)
  324. consumer.cancel_by_queue(queue.name)
  325. self.assertFalse(consumer._active_tags)
  326. def test_consumer_tag_prefix(self):
  327. channel = self.connection.channel()
  328. queue = Queue('qname', self.exchange, 'rkey')
  329. consumer = Consumer(channel, queue, tag_prefix='consumer_')
  330. consumer.consume()
  331. self.assertTrue(
  332. consumer._active_tags[queue.name].startswith('consumer_'),
  333. )
  334. def test_manual_declare(self):
  335. channel = self.connection.channel()
  336. queue = Queue('qname', self.exchange, 'rkey')
  337. consumer = Consumer(channel, queue, auto_declare=False)
  338. self.assertIsNot(consumer.queues[0], queue)
  339. self.assertTrue(consumer.queues[0].is_bound)
  340. self.assertTrue(consumer.queues[0].exchange.is_bound)
  341. self.assertIsNot(consumer.queues[0].exchange, self.exchange)
  342. for meth in ('exchange_declare',
  343. 'queue_declare',
  344. 'basic_consume'):
  345. self.assertNotIn(meth, channel)
  346. consumer.declare()
  347. for meth in ('exchange_declare',
  348. 'queue_declare',
  349. 'queue_bind'):
  350. self.assertIn(meth, channel)
  351. self.assertNotIn('basic_consume', channel)
  352. consumer.consume()
  353. self.assertIn('basic_consume', channel)
  354. def test_consume__cancel(self):
  355. channel = self.connection.channel()
  356. queue = Queue('qname', self.exchange, 'rkey')
  357. consumer = Consumer(channel, queue, auto_declare=True)
  358. consumer.consume()
  359. consumer.cancel()
  360. self.assertIn('basic_cancel', channel)
  361. self.assertFalse(consumer._active_tags)
  362. def test___enter____exit__(self):
  363. channel = self.connection.channel()
  364. queue = Queue('qname', self.exchange, 'rkey')
  365. consumer = Consumer(channel, queue, auto_declare=True)
  366. context = consumer.__enter__()
  367. self.assertIs(context, consumer)
  368. self.assertTrue(consumer._active_tags)
  369. res = consumer.__exit__(None, None, None)
  370. self.assertFalse(res)
  371. self.assertIn('basic_cancel', channel)
  372. self.assertFalse(consumer._active_tags)
  373. def test_flow(self):
  374. channel = self.connection.channel()
  375. queue = Queue('qname', self.exchange, 'rkey')
  376. consumer = Consumer(channel, queue, auto_declare=True)
  377. consumer.flow(False)
  378. self.assertIn('flow', channel)
  379. def test_qos(self):
  380. channel = self.connection.channel()
  381. queue = Queue('qname', self.exchange, 'rkey')
  382. consumer = Consumer(channel, queue, auto_declare=True)
  383. consumer.qos(30, 10, False)
  384. self.assertIn('basic_qos', channel)
  385. def test_purge(self):
  386. channel = self.connection.channel()
  387. b1 = Queue('qname1', self.exchange, 'rkey')
  388. b2 = Queue('qname2', self.exchange, 'rkey')
  389. b3 = Queue('qname3', self.exchange, 'rkey')
  390. b4 = Queue('qname4', self.exchange, 'rkey')
  391. consumer = Consumer(channel, [b1, b2, b3, b4], auto_declare=True)
  392. consumer.purge()
  393. self.assertEqual(channel.called.count('queue_purge'), 4)
  394. def test_multiple_queues(self):
  395. channel = self.connection.channel()
  396. b1 = Queue('qname1', self.exchange, 'rkey')
  397. b2 = Queue('qname2', self.exchange, 'rkey')
  398. b3 = Queue('qname3', self.exchange, 'rkey')
  399. b4 = Queue('qname4', self.exchange, 'rkey')
  400. consumer = Consumer(channel, [b1, b2, b3, b4])
  401. consumer.consume()
  402. self.assertEqual(channel.called.count('exchange_declare'), 4)
  403. self.assertEqual(channel.called.count('queue_declare'), 4)
  404. self.assertEqual(channel.called.count('queue_bind'), 4)
  405. self.assertEqual(channel.called.count('basic_consume'), 4)
  406. self.assertEqual(len(consumer._active_tags), 4)
  407. consumer.cancel()
  408. self.assertEqual(channel.called.count('basic_cancel'), 4)
  409. self.assertFalse(len(consumer._active_tags))
  410. def test_receive_callback(self):
  411. channel = self.connection.channel()
  412. b1 = Queue('qname1', self.exchange, 'rkey')
  413. consumer = Consumer(channel, [b1])
  414. received = []
  415. def callback(message_data, message):
  416. received.append(message_data)
  417. message.ack()
  418. message.payload # trigger cache
  419. consumer.register_callback(callback)
  420. consumer._receive_callback({'foo': 'bar'})
  421. self.assertIn('basic_ack', channel)
  422. self.assertIn('message_to_python', channel)
  423. self.assertEqual(received[0], {'foo': 'bar'})
  424. def test_basic_ack_twice(self):
  425. channel = self.connection.channel()
  426. b1 = Queue('qname1', self.exchange, 'rkey')
  427. consumer = Consumer(channel, [b1])
  428. def callback(message_data, message):
  429. message.ack()
  430. message.ack()
  431. consumer.register_callback(callback)
  432. with self.assertRaises(MessageStateError):
  433. consumer._receive_callback({'foo': 'bar'})
  434. def test_basic_reject(self):
  435. channel = self.connection.channel()
  436. b1 = Queue('qname1', self.exchange, 'rkey')
  437. consumer = Consumer(channel, [b1])
  438. def callback(message_data, message):
  439. message.reject()
  440. consumer.register_callback(callback)
  441. consumer._receive_callback({'foo': 'bar'})
  442. self.assertIn('basic_reject', channel)
  443. def test_basic_reject_twice(self):
  444. channel = self.connection.channel()
  445. b1 = Queue('qname1', self.exchange, 'rkey')
  446. consumer = Consumer(channel, [b1])
  447. def callback(message_data, message):
  448. message.reject()
  449. message.reject()
  450. consumer.register_callback(callback)
  451. with self.assertRaises(MessageStateError):
  452. consumer._receive_callback({'foo': 'bar'})
  453. self.assertIn('basic_reject', channel)
  454. def test_basic_reject__requeue(self):
  455. channel = self.connection.channel()
  456. b1 = Queue('qname1', self.exchange, 'rkey')
  457. consumer = Consumer(channel, [b1])
  458. def callback(message_data, message):
  459. message.requeue()
  460. consumer.register_callback(callback)
  461. consumer._receive_callback({'foo': 'bar'})
  462. self.assertIn('basic_reject:requeue', channel)
  463. def test_basic_reject__requeue_twice(self):
  464. channel = self.connection.channel()
  465. b1 = Queue('qname1', self.exchange, 'rkey')
  466. consumer = Consumer(channel, [b1])
  467. def callback(message_data, message):
  468. message.requeue()
  469. message.requeue()
  470. consumer.register_callback(callback)
  471. with self.assertRaises(MessageStateError):
  472. consumer._receive_callback({'foo': 'bar'})
  473. self.assertIn('basic_reject:requeue', channel)
  474. def test_receive_without_callbacks_raises(self):
  475. channel = self.connection.channel()
  476. b1 = Queue('qname1', self.exchange, 'rkey')
  477. consumer = Consumer(channel, [b1])
  478. with self.assertRaises(NotImplementedError):
  479. consumer.receive(1, 2)
  480. def test_decode_error(self):
  481. channel = self.connection.channel()
  482. b1 = Queue('qname1', self.exchange, 'rkey')
  483. consumer = Consumer(channel, [b1])
  484. consumer.channel.throw_decode_error = True
  485. with self.assertRaises(ValueError):
  486. consumer._receive_callback({'foo': 'bar'})
  487. def test_on_decode_error_callback(self):
  488. channel = self.connection.channel()
  489. b1 = Queue('qname1', self.exchange, 'rkey')
  490. thrown = []
  491. def on_decode_error(msg, exc):
  492. thrown.append((msg.body, exc))
  493. consumer = Consumer(channel, [b1], on_decode_error=on_decode_error)
  494. consumer.channel.throw_decode_error = True
  495. consumer._receive_callback({'foo': 'bar'})
  496. self.assertTrue(thrown)
  497. m, exc = thrown[0]
  498. self.assertEqual(anyjson.loads(m), {'foo': 'bar'})
  499. self.assertIsInstance(exc, ValueError)
  500. def test_recover(self):
  501. channel = self.connection.channel()
  502. b1 = Queue('qname1', self.exchange, 'rkey')
  503. consumer = Consumer(channel, [b1])
  504. consumer.recover()
  505. self.assertIn('basic_recover', channel)
  506. def test_revive(self):
  507. channel = self.connection.channel()
  508. b1 = Queue('qname1', self.exchange, 'rkey')
  509. consumer = Consumer(channel, [b1])
  510. channel2 = self.connection.channel()
  511. consumer.revive(channel2)
  512. self.assertIs(consumer.channel, channel2)
  513. self.assertIs(consumer.queues[0].channel, channel2)
  514. self.assertIs(consumer.queues[0].exchange.channel, channel2)
  515. def test__repr__(self):
  516. channel = self.connection.channel()
  517. b1 = Queue('qname1', self.exchange, 'rkey')
  518. self.assertTrue(repr(Consumer(channel, [b1])))
  519. def test_connection_property_handles_AttributeError(self):
  520. p = self.connection.Consumer()
  521. p.channel = object()
  522. self.assertIsNone(p.connection)