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_connection.py 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. from __future__ import absolute_import
  2. import pickle
  3. import socket
  4. from copy import copy, deepcopy
  5. from kombu import Connection, Consumer, Producer, parse_url
  6. from kombu.connection import Resource
  7. from kombu.five import items, range
  8. from .case import Case, Mock, SkipTest, patch, skip_if_not_module
  9. from .mocks import Transport
  10. class test_connection_utils(Case):
  11. def setUp(self):
  12. self.url = 'amqp://user:pass@localhost:5672/my/vhost'
  13. self.nopass = 'amqp://user:**@localhost:5672/my/vhost'
  14. self.expected = {
  15. 'transport': 'amqp',
  16. 'userid': 'user',
  17. 'password': 'pass',
  18. 'hostname': 'localhost',
  19. 'port': 5672,
  20. 'virtual_host': 'my/vhost',
  21. }
  22. def test_parse_url(self):
  23. result = parse_url(self.url)
  24. self.assertDictEqual(result, self.expected)
  25. def test_parse_generated_as_uri(self):
  26. conn = Connection(self.url)
  27. info = conn.info()
  28. for k, v in self.expected.items():
  29. self.assertEqual(info[k], v)
  30. # by default almost the same- no password
  31. self.assertEqual(conn.as_uri(), self.nopass)
  32. self.assertEqual(conn.as_uri(include_password=True), self.url)
  33. def test_as_uri_when_prefix(self):
  34. conn = Connection('redis+socket:///var/spool/x/y/z/redis.sock')
  35. self.assertEqual(
  36. conn.as_uri(), 'redis+socket:///var/spool/x/y/z/redis.sock',
  37. )
  38. @skip_if_not_module('pymongo')
  39. def test_as_uri_when_mongodb(self):
  40. x = Connection('mongodb://localhost')
  41. self.assertTrue(x.as_uri())
  42. def test_bogus_scheme(self):
  43. with self.assertRaises(KeyError):
  44. Connection('bogus://localhost:7421').transport
  45. def assert_info(self, conn, **fields):
  46. info = conn.info()
  47. for field, expected in items(fields):
  48. self.assertEqual(info[field], expected)
  49. def test_rabbitmq_example_urls(self):
  50. # see Appendix A of http://www.rabbitmq.com/uri-spec.html
  51. self.assert_info(
  52. Connection('amqp://user:pass@host:10000/vhost'),
  53. userid='user', password='pass', hostname='host',
  54. port=10000, virtual_host='vhost',
  55. )
  56. self.assert_info(
  57. Connection('amqp://user%61:%61pass@ho%61st:10000/v%2fhost'),
  58. userid='usera', password='apass', hostname='hoast',
  59. port=10000, virtual_host='v/host',
  60. )
  61. self.assert_info(
  62. Connection('amqp://'),
  63. userid='guest', password='guest', hostname='localhost',
  64. port=5672, virtual_host='/',
  65. )
  66. self.assert_info(
  67. Connection('amqp://:@/'),
  68. userid='guest', password='guest', hostname='localhost',
  69. port=5672, virtual_host='/',
  70. )
  71. self.assert_info(
  72. Connection('amqp://user@/'),
  73. userid='user', password='guest', hostname='localhost',
  74. port=5672, virtual_host='/',
  75. )
  76. self.assert_info(
  77. Connection('amqp://user:pass@/'),
  78. userid='user', password='pass', hostname='localhost',
  79. port=5672, virtual_host='/',
  80. )
  81. self.assert_info(
  82. Connection('amqp://host'),
  83. userid='guest', password='guest', hostname='host',
  84. port=5672, virtual_host='/',
  85. )
  86. self.assert_info(
  87. Connection('amqp://:10000'),
  88. userid='guest', password='guest', hostname='localhost',
  89. port=10000, virtual_host='/',
  90. )
  91. self.assert_info(
  92. Connection('amqp:///vhost'),
  93. userid='guest', password='guest', hostname='localhost',
  94. port=5672, virtual_host='vhost',
  95. )
  96. self.assert_info(
  97. Connection('amqp://host/'),
  98. userid='guest', password='guest', hostname='host',
  99. port=5672, virtual_host='/',
  100. )
  101. self.assert_info(
  102. Connection('amqp://host/%2f'),
  103. userid='guest', password='guest', hostname='host',
  104. port=5672, virtual_host='/',
  105. )
  106. def test_url_IPV6(self):
  107. raise SkipTest("urllib can't parse ipv6 urls")
  108. self.assert_info(
  109. Connection('amqp://[::1]'),
  110. userid='guest', password='guest', hostname='[::1]',
  111. port=5672, virtual_host='/',
  112. )
  113. def test_connection_copy(self):
  114. conn = Connection(self.url, alternates=['amqp://host'])
  115. clone = deepcopy(conn)
  116. self.assertEqual(clone.alt, ['amqp://host'])
  117. class test_Connection(Case):
  118. def setUp(self):
  119. self.conn = Connection(port=5672, transport=Transport)
  120. def test_establish_connection(self):
  121. conn = self.conn
  122. conn.connect()
  123. self.assertTrue(conn.connection.connected)
  124. self.assertEqual(conn.host, 'localhost:5672')
  125. channel = conn.channel()
  126. self.assertTrue(channel.open)
  127. self.assertEqual(conn.drain_events(), 'event')
  128. _connection = conn.connection
  129. conn.close()
  130. self.assertFalse(_connection.connected)
  131. self.assertIsInstance(conn.transport, Transport)
  132. def test_multiple_urls(self):
  133. conn1 = Connection('amqp://foo;amqp://bar')
  134. self.assertEqual(conn1.hostname, 'foo')
  135. self.assertListEqual(conn1.alt, ['amqp://foo', 'amqp://bar'])
  136. conn2 = Connection(['amqp://foo', 'amqp://bar'])
  137. self.assertEqual(conn2.hostname, 'foo')
  138. self.assertListEqual(conn2.alt, ['amqp://foo', 'amqp://bar'])
  139. def test_collect(self):
  140. connection = Connection('memory://')
  141. trans = connection._transport = Mock(name='transport')
  142. _collect = trans._collect = Mock(name='transport._collect')
  143. _close = connection._close = Mock(name='connection._close')
  144. connection.declared_entities = Mock(name='decl_entities')
  145. uconn = connection._connection = Mock(name='_connection')
  146. connection.collect()
  147. self.assertFalse(_close.called)
  148. _collect.assert_called_with(uconn)
  149. connection.declared_entities.clear.assert_called_with()
  150. self.assertIsNone(trans.client)
  151. self.assertIsNone(connection._transport)
  152. self.assertIsNone(connection._connection)
  153. def test_collect_no_transport(self):
  154. connection = Connection('memory://')
  155. connection._transport = None
  156. connection._close = Mock()
  157. connection.collect()
  158. connection._close.assert_called_with()
  159. connection._close.side_effect = socket.timeout()
  160. connection.collect()
  161. def test_collect_transport_gone(self):
  162. connection = Connection('memory://')
  163. uconn = connection._connection = Mock(name='conn._conn')
  164. trans = connection._transport = Mock(name='transport')
  165. collect = trans._collect = Mock(name='transport._collect')
  166. def se(conn):
  167. connection._transport = None
  168. collect.side_effect = se
  169. connection.collect()
  170. collect.assert_called_with(uconn)
  171. self.assertIsNone(connection._transport)
  172. def test_uri_passthrough(self):
  173. transport = Mock(name='transport')
  174. with patch('kombu.connection.get_transport_cls') as gtc:
  175. gtc.return_value = transport
  176. transport.can_parse_url = True
  177. with patch('kombu.connection.parse_url') as parse_url:
  178. c = Connection('foo+mysql://some_host')
  179. self.assertEqual(c.transport_cls, 'foo')
  180. self.assertFalse(parse_url.called)
  181. self.assertEqual(c.hostname, 'mysql://some_host')
  182. self.assertTrue(c.as_uri().startswith('foo+'))
  183. with patch('kombu.connection.parse_url') as parse_url:
  184. c = Connection('mysql://some_host', transport='foo')
  185. self.assertEqual(c.transport_cls, 'foo')
  186. self.assertFalse(parse_url.called)
  187. self.assertEqual(c.hostname, 'mysql://some_host')
  188. c = Connection('pyamqp+sqlite://some_host')
  189. self.assertTrue(c.as_uri().startswith('pyamqp+'))
  190. def test_default_ensure_callback(self):
  191. with patch('kombu.connection.logger') as logger:
  192. c = Connection(transport=Mock)
  193. c._default_ensure_callback(KeyError(), 3)
  194. self.assertTrue(logger.error.called)
  195. def test_ensure_connection_on_error(self):
  196. c = Connection('amqp://A;amqp://B')
  197. with patch('kombu.connection.retry_over_time') as rot:
  198. c.ensure_connection()
  199. self.assertTrue(rot.called)
  200. args = rot.call_args[0]
  201. cb = args[4]
  202. intervals = iter([1, 2, 3, 4, 5])
  203. self.assertEqual(cb(KeyError(), intervals, 0), 0)
  204. self.assertEqual(cb(KeyError(), intervals, 1), 1)
  205. self.assertEqual(cb(KeyError(), intervals, 2), 0)
  206. self.assertEqual(cb(KeyError(), intervals, 3), 2)
  207. self.assertEqual(cb(KeyError(), intervals, 4), 0)
  208. self.assertEqual(cb(KeyError(), intervals, 5), 3)
  209. self.assertEqual(cb(KeyError(), intervals, 6), 0)
  210. self.assertEqual(cb(KeyError(), intervals, 7), 4)
  211. errback = Mock()
  212. c.ensure_connection(errback=errback)
  213. args = rot.call_args[0]
  214. cb = args[4]
  215. self.assertEqual(cb(KeyError(), intervals, 0), 0)
  216. self.assertTrue(errback.called)
  217. def test_supports_heartbeats(self):
  218. c = Connection(transport=Mock)
  219. c.transport.supports_heartbeats = False
  220. self.assertFalse(c.supports_heartbeats)
  221. def test_is_evented(self):
  222. c = Connection(transport=Mock)
  223. c.transport.supports_ev = False
  224. self.assertFalse(c.is_evented)
  225. def test_register_with_event_loop(self):
  226. c = Connection(transport=Mock)
  227. loop = Mock(name='loop')
  228. c.register_with_event_loop(loop)
  229. c.transport.register_with_event_loop.assert_called_with(
  230. c.connection, loop,
  231. )
  232. def test_manager(self):
  233. c = Connection(transport=Mock)
  234. self.assertIs(c.manager, c.transport.manager)
  235. def test_copy(self):
  236. c = Connection('amqp://example.com')
  237. self.assertEqual(copy(c).info(), c.info())
  238. def test_copy_multiples(self):
  239. c = Connection('amqp://A.example.com;amqp://B.example.com')
  240. self.assertTrue(c.alt)
  241. d = copy(c)
  242. self.assertEqual(d.alt, c.alt)
  243. def test_switch(self):
  244. c = Connection('amqp://foo')
  245. c._closed = True
  246. c.switch('redis://example.com//3')
  247. self.assertFalse(c._closed)
  248. self.assertEqual(c.hostname, 'example.com')
  249. self.assertEqual(c.transport_cls, 'redis')
  250. self.assertEqual(c.virtual_host, '/3')
  251. def test_maybe_switch_next(self):
  252. c = Connection('amqp://foo;redis://example.com//3')
  253. c.maybe_switch_next()
  254. self.assertFalse(c._closed)
  255. self.assertEqual(c.hostname, 'example.com')
  256. self.assertEqual(c.transport_cls, 'redis')
  257. self.assertEqual(c.virtual_host, '/3')
  258. def test_maybe_switch_next_no_cycle(self):
  259. c = Connection('amqp://foo')
  260. c.maybe_switch_next()
  261. self.assertFalse(c._closed)
  262. self.assertEqual(c.hostname, 'foo')
  263. self.assertIn(c.transport_cls, ('librabbitmq', 'pyamqp', 'amqp'))
  264. def test_heartbeat_check(self):
  265. c = Connection(transport=Transport)
  266. c.transport.heartbeat_check = Mock()
  267. c.heartbeat_check(3)
  268. c.transport.heartbeat_check.assert_called_with(c.connection, rate=3)
  269. def test_completes_cycle_no_cycle(self):
  270. c = Connection('amqp://')
  271. self.assertTrue(c.completes_cycle(0))
  272. self.assertTrue(c.completes_cycle(1))
  273. def test_completes_cycle(self):
  274. c = Connection('amqp://a;amqp://b;amqp://c')
  275. self.assertFalse(c.completes_cycle(0))
  276. self.assertFalse(c.completes_cycle(1))
  277. self.assertTrue(c.completes_cycle(2))
  278. def test__enter____exit__(self):
  279. conn = self.conn
  280. context = conn.__enter__()
  281. self.assertIs(context, conn)
  282. conn.connect()
  283. self.assertTrue(conn.connection.connected)
  284. conn.__exit__()
  285. self.assertIsNone(conn.connection)
  286. conn.close() # again
  287. def test_close_survives_connerror(self):
  288. class _CustomError(Exception):
  289. pass
  290. class MyTransport(Transport):
  291. connection_errors = (_CustomError, )
  292. def close_connection(self, connection):
  293. raise _CustomError('foo')
  294. conn = Connection(transport=MyTransport)
  295. conn.connect()
  296. conn.close()
  297. self.assertTrue(conn._closed)
  298. def test_close_when_default_channel(self):
  299. conn = self.conn
  300. conn._default_channel = Mock()
  301. conn._close()
  302. conn._default_channel.close.assert_called_with()
  303. def test_close_when_default_channel_close_raises(self):
  304. class Conn(Connection):
  305. @property
  306. def connection_errors(self):
  307. return (KeyError, )
  308. conn = Conn('memory://')
  309. conn._default_channel = Mock()
  310. conn._default_channel.close.side_effect = KeyError()
  311. conn._close()
  312. conn._default_channel.close.assert_called_with()
  313. def test_revive_when_default_channel(self):
  314. conn = self.conn
  315. defchan = conn._default_channel = Mock()
  316. conn.revive(Mock())
  317. defchan.close.assert_called_with()
  318. self.assertIsNone(conn._default_channel)
  319. def test_ensure_connection(self):
  320. self.assertTrue(self.conn.ensure_connection())
  321. def test_ensure_success(self):
  322. def publish():
  323. return 'foobar'
  324. ensured = self.conn.ensure(None, publish)
  325. self.assertEqual(ensured(), 'foobar')
  326. def test_ensure_failure(self):
  327. class _CustomError(Exception):
  328. pass
  329. def publish():
  330. raise _CustomError('bar')
  331. ensured = self.conn.ensure(None, publish)
  332. with self.assertRaises(_CustomError):
  333. ensured()
  334. def test_ensure_connection_failure(self):
  335. class _ConnectionError(Exception):
  336. pass
  337. def publish():
  338. raise _ConnectionError('failed connection')
  339. self.conn.transport.connection_errors = (_ConnectionError,)
  340. ensured = self.conn.ensure(self.conn, publish)
  341. with self.assertRaises(_ConnectionError):
  342. ensured()
  343. def test_autoretry(self):
  344. myfun = Mock()
  345. self.conn.transport.connection_errors = (KeyError, )
  346. def on_call(*args, **kwargs):
  347. myfun.side_effect = None
  348. raise KeyError('foo')
  349. myfun.side_effect = on_call
  350. insured = self.conn.autoretry(myfun)
  351. insured()
  352. self.assertTrue(myfun.called)
  353. def test_SimpleQueue(self):
  354. conn = self.conn
  355. q = conn.SimpleQueue('foo')
  356. self.assertIs(q.channel, conn.default_channel)
  357. chan = conn.channel()
  358. q2 = conn.SimpleQueue('foo', channel=chan)
  359. self.assertIs(q2.channel, chan)
  360. def test_SimpleBuffer(self):
  361. conn = self.conn
  362. q = conn.SimpleBuffer('foo')
  363. self.assertIs(q.channel, conn.default_channel)
  364. chan = conn.channel()
  365. q2 = conn.SimpleBuffer('foo', channel=chan)
  366. self.assertIs(q2.channel, chan)
  367. def test_Producer(self):
  368. conn = self.conn
  369. self.assertIsInstance(conn.Producer(), Producer)
  370. self.assertIsInstance(conn.Producer(conn.default_channel), Producer)
  371. def test_Consumer(self):
  372. conn = self.conn
  373. self.assertIsInstance(conn.Consumer(queues=[]), Consumer)
  374. self.assertIsInstance(conn.Consumer(queues=[],
  375. channel=conn.default_channel), Consumer)
  376. def test__repr__(self):
  377. self.assertTrue(repr(self.conn))
  378. def test__reduce__(self):
  379. x = pickle.loads(pickle.dumps(self.conn))
  380. self.assertDictEqual(x.info(), self.conn.info())
  381. def test_channel_errors(self):
  382. class MyTransport(Transport):
  383. channel_errors = (KeyError, ValueError)
  384. conn = Connection(transport=MyTransport)
  385. self.assertTupleEqual(conn.channel_errors, (KeyError, ValueError))
  386. def test_connection_errors(self):
  387. class MyTransport(Transport):
  388. connection_errors = (KeyError, ValueError)
  389. conn = Connection(transport=MyTransport)
  390. self.assertTupleEqual(conn.connection_errors, (KeyError, ValueError))
  391. class test_Connection_with_transport_options(Case):
  392. transport_options = {'pool_recycler': 3600, 'echo': True}
  393. def setUp(self):
  394. self.conn = Connection(port=5672, transport=Transport,
  395. transport_options=self.transport_options)
  396. def test_establish_connection(self):
  397. conn = self.conn
  398. self.assertEqual(conn.transport_options, self.transport_options)
  399. class xResource(Resource):
  400. def setup(self):
  401. pass
  402. class ResourceCase(Case):
  403. abstract = True
  404. def create_resource(self, limit, preload):
  405. raise NotImplementedError('subclass responsibility')
  406. def assertState(self, P, avail, dirty):
  407. self.assertEqual(P._resource.qsize(), avail)
  408. self.assertEqual(len(P._dirty), dirty)
  409. def test_setup(self):
  410. if self.abstract:
  411. with self.assertRaises(NotImplementedError):
  412. Resource()
  413. def test_acquire__release(self):
  414. if self.abstract:
  415. return
  416. P = self.create_resource(10, 0)
  417. self.assertState(P, 10, 0)
  418. chans = [P.acquire() for _ in range(10)]
  419. self.assertState(P, 0, 10)
  420. with self.assertRaises(P.LimitExceeded):
  421. P.acquire()
  422. chans.pop().release()
  423. self.assertState(P, 1, 9)
  424. [chan.release() for chan in chans]
  425. self.assertState(P, 10, 0)
  426. def test_acquire_prepare_raises(self):
  427. if self.abstract:
  428. return
  429. P = self.create_resource(10, 0)
  430. self.assertEqual(len(P._resource.queue), 10)
  431. P.prepare = Mock()
  432. P.prepare.side_effect = IOError()
  433. with self.assertRaises(IOError):
  434. P.acquire(block=True)
  435. self.assertEqual(len(P._resource.queue), 10)
  436. def test_acquire_no_limit(self):
  437. if self.abstract:
  438. return
  439. P = self.create_resource(None, 0)
  440. P.acquire().release()
  441. def test_replace_when_limit(self):
  442. if self.abstract:
  443. return
  444. P = self.create_resource(10, 0)
  445. r = P.acquire()
  446. P._dirty = Mock()
  447. P.close_resource = Mock()
  448. P.replace(r)
  449. P._dirty.discard.assert_called_with(r)
  450. P.close_resource.assert_called_with(r)
  451. def test_replace_no_limit(self):
  452. if self.abstract:
  453. return
  454. P = self.create_resource(None, 0)
  455. r = P.acquire()
  456. P._dirty = Mock()
  457. P.close_resource = Mock()
  458. P.replace(r)
  459. self.assertFalse(P._dirty.discard.called)
  460. P.close_resource.assert_called_with(r)
  461. def test_interface_prepare(self):
  462. if not self.abstract:
  463. return
  464. x = xResource()
  465. self.assertEqual(x.prepare(10), 10)
  466. def test_force_close_all_handles_AttributeError(self):
  467. if self.abstract:
  468. return
  469. P = self.create_resource(10, 10)
  470. cr = P.collect_resource = Mock()
  471. cr.side_effect = AttributeError('x')
  472. P.acquire()
  473. self.assertTrue(P._dirty)
  474. P.force_close_all()
  475. def test_force_close_all_no_mutex(self):
  476. if self.abstract:
  477. return
  478. P = self.create_resource(10, 10)
  479. P.close_resource = Mock()
  480. m = P._resource = Mock()
  481. m.mutex = None
  482. m.queue.pop.side_effect = IndexError
  483. P.force_close_all()
  484. def test_add_when_empty(self):
  485. if self.abstract:
  486. return
  487. P = self.create_resource(None, None)
  488. P._resource.queue[:] = []
  489. self.assertFalse(P._resource.queue)
  490. P._add_when_empty()
  491. self.assertTrue(P._resource.queue)
  492. class test_ConnectionPool(ResourceCase):
  493. abstract = False
  494. def create_resource(self, limit, preload):
  495. return Connection(port=5672, transport=Transport).Pool(limit, preload)
  496. def test_setup(self):
  497. P = self.create_resource(10, 2)
  498. q = P._resource.queue
  499. self.assertIsNotNone(q[0]._connection)
  500. self.assertIsNotNone(q[1]._connection)
  501. self.assertIsNone(q[2]()._connection)
  502. def test_acquire_raises_evaluated(self):
  503. P = self.create_resource(1, 0)
  504. # evaluate the connection first
  505. r = P.acquire()
  506. r.release()
  507. P.prepare = Mock()
  508. P.prepare.side_effect = MemoryError()
  509. P.release = Mock()
  510. with self.assertRaises(MemoryError):
  511. with P.acquire():
  512. assert False
  513. P.release.assert_called_with(r)
  514. def test_release_no__debug(self):
  515. P = self.create_resource(10, 2)
  516. R = Mock()
  517. R._debug.side_effect = AttributeError()
  518. P.release_resource(R)
  519. def test_setup_no_limit(self):
  520. P = self.create_resource(None, None)
  521. self.assertFalse(P._resource.queue)
  522. self.assertIsNone(P.limit)
  523. def test_prepare_not_callable(self):
  524. P = self.create_resource(None, None)
  525. conn = Connection('memory://')
  526. self.assertIs(P.prepare(conn), conn)
  527. def test_acquire_channel(self):
  528. P = self.create_resource(10, 0)
  529. with P.acquire_channel() as (conn, channel):
  530. self.assertIs(channel, conn.default_channel)
  531. class test_ChannelPool(ResourceCase):
  532. abstract = False
  533. def create_resource(self, limit, preload):
  534. return Connection(port=5672, transport=Transport) \
  535. .ChannelPool(limit, preload)
  536. def test_setup(self):
  537. P = self.create_resource(10, 2)
  538. q = P._resource.queue
  539. self.assertTrue(q[0].basic_consume)
  540. self.assertTrue(q[1].basic_consume)
  541. with self.assertRaises(AttributeError):
  542. getattr(q[2], 'basic_consume')
  543. def test_setup_no_limit(self):
  544. P = self.create_resource(None, None)
  545. self.assertFalse(P._resource.queue)
  546. self.assertIsNone(P.limit)
  547. def test_prepare_not_callable(self):
  548. P = self.create_resource(10, 0)
  549. conn = Connection('memory://')
  550. chan = conn.default_channel
  551. self.assertIs(P.prepare(chan), chan)