kombu/t/unit/test_compat.py

336 lines
11 KiB
Python

from __future__ import annotations
from unittest.mock import Mock, patch
import pytest
from kombu import Connection, Exchange, Queue, compat
from t.mocks import Channel, Transport
class test_misc:
def test_iterconsume(self):
class MyConnection:
drained = 0
def drain_events(self, *args, **kwargs):
self.drained += 1
return self.drained
class Consumer:
active = False
def consume(self, *args, **kwargs):
self.active = True
conn = MyConnection()
consumer = Consumer()
it = compat._iterconsume(conn, consumer)
assert next(it) == 1
assert consumer.active
it2 = compat._iterconsume(conn, consumer, limit=10)
assert list(it2), [2, 3, 4, 5, 6, 7, 8, 9, 10 == 11]
def test_Queue_from_dict(self):
defs = {'binding_key': 'foo.#',
'exchange': 'fooex',
'exchange_type': 'topic',
'durable': True,
'auto_delete': False}
q1 = Queue.from_dict('foo', **dict(defs))
assert q1.name == 'foo'
assert q1.routing_key == 'foo.#'
assert q1.exchange.name == 'fooex'
assert q1.exchange.type == 'topic'
assert q1.durable
assert q1.exchange.durable
assert not q1.auto_delete
assert not q1.exchange.auto_delete
q2 = Queue.from_dict('foo', **dict(defs,
exchange_durable=False))
assert q2.durable
assert not q2.exchange.durable
q3 = Queue.from_dict('foo', **dict(defs,
exchange_auto_delete=True))
assert not q3.auto_delete
assert q3.exchange.auto_delete
q4 = Queue.from_dict('foo', **dict(defs,
queue_durable=False))
assert not q4.durable
assert q4.exchange.durable
q5 = Queue.from_dict('foo', **dict(defs,
queue_auto_delete=True))
assert q5.auto_delete
assert not q5.exchange.auto_delete
assert (Queue.from_dict('foo', **dict(defs)) ==
Queue.from_dict('foo', **dict(defs)))
class test_Publisher:
def setup(self):
self.connection = Connection(transport=Transport)
def test_constructor(self):
pub = compat.Publisher(self.connection,
exchange='test_Publisher_constructor',
routing_key='rkey')
assert isinstance(pub.backend, Channel)
assert pub.exchange.name == 'test_Publisher_constructor'
assert pub.exchange.durable
assert not pub.exchange.auto_delete
assert pub.exchange.type == 'direct'
pub2 = compat.Publisher(self.connection,
exchange='test_Publisher_constructor2',
routing_key='rkey',
auto_delete=True,
durable=False)
assert pub2.exchange.auto_delete
assert not pub2.exchange.durable
explicit = Exchange('test_Publisher_constructor_explicit',
type='topic')
pub3 = compat.Publisher(self.connection,
exchange=explicit)
assert pub3.exchange == explicit
compat.Publisher(self.connection,
exchange='test_Publisher_constructor3',
channel=self.connection.default_channel)
def test_send(self):
pub = compat.Publisher(self.connection,
exchange='test_Publisher_send',
routing_key='rkey')
pub.send({'foo': 'bar'})
assert 'basic_publish' in pub.backend
pub.close()
def test__enter__exit__(self):
pub = compat.Publisher(
self.connection,
exchange='test_Publisher_send',
routing_key='rkey'
)
with pub as x:
assert x is pub
assert pub._closed
class test_Consumer:
def setup(self):
self.connection = Connection(transport=Transport)
@patch('kombu.compat._iterconsume')
def test_iterconsume_calls__iterconsume(self, it, n='test_iterconsume'):
c = compat.Consumer(self.connection, queue=n, exchange=n)
c.iterconsume(limit=10, no_ack=True)
it.assert_called_with(c.connection, c, True, 10)
def test_constructor(self, n='test_Consumer_constructor'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
assert isinstance(c.backend, Channel)
q = c.queues[0]
assert q.durable
assert q.exchange.durable
assert not q.auto_delete
assert not q.exchange.auto_delete
assert q.name == n
assert q.exchange.name == n
c2 = compat.Consumer(self.connection, queue=n + '2',
exchange=n + '2',
routing_key='rkey', durable=False,
auto_delete=True, exclusive=True)
q2 = c2.queues[0]
assert not q2.durable
assert not q2.exchange.durable
assert q2.auto_delete
assert q2.exchange.auto_delete
def test__enter__exit__(self, n='test__enter__exit__'):
c = compat.Consumer(
self.connection,
queue=n,
exchange=n,
routing_key='rkey'
)
with c as x:
assert x is c
assert c._closed
def test_revive(self, n='test_revive'):
c = compat.Consumer(self.connection, queue=n, exchange=n)
with self.connection.channel() as c2:
c.revive(c2)
assert c.backend is c2
def test__iter__(self, n='test__iter__'):
c = compat.Consumer(self.connection, queue=n, exchange=n)
c.iterqueue = Mock()
c.__iter__()
c.iterqueue.assert_called_with(infinite=True)
def test_iter(self, n='test_iterqueue'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
c.close()
def test_process_next(self, n='test_process_next'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
with pytest.raises(NotImplementedError):
c.process_next()
c.close()
def test_iterconsume(self, n='test_iterconsume'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
c.close()
def test_discard_all(self, n='test_discard_all'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
c.discard_all()
assert 'queue_purge' in c.backend
def test_fetch(self, n='test_fetch'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
assert c.fetch() is None
assert c.fetch(no_ack=True) is None
assert 'basic_get' in c.backend
callback_called = [False]
def receive(payload, message):
callback_called[0] = True
c.backend.to_deliver.append('42')
payload = c.fetch().payload
assert payload == '42'
c.backend.to_deliver.append('46')
c.register_callback(receive)
assert c.fetch(enable_callbacks=True).payload == '46'
assert callback_called[0]
def test_discard_all_filterfunc_not_supported(self, n='xjf21j21'):
c = compat.Consumer(self.connection, queue=n, exchange=n,
routing_key='rkey')
with pytest.raises(NotImplementedError):
c.discard_all(filterfunc=lambda x: x)
c.close()
def test_wait(self, n='test_wait'):
class C(compat.Consumer):
def iterconsume(self, limit=None):
yield from range(limit)
c = C(self.connection,
queue=n, exchange=n, routing_key='rkey')
assert c.wait(10) == list(range(10))
c.close()
def test_iterqueue(self, n='test_iterqueue'):
i = [0]
class C(compat.Consumer):
def fetch(self, limit=None):
z = i[0]
i[0] += 1
return z
c = C(self.connection,
queue=n, exchange=n, routing_key='rkey')
assert list(c.iterqueue(limit=10)) == list(range(10))
c.close()
class test_ConsumerSet:
def setup(self):
self.connection = Connection(transport=Transport)
def test_providing_channel(self):
chan = Mock(name='channel')
cs = compat.ConsumerSet(self.connection, channel=chan)
assert cs._provided_channel
assert cs.backend is chan
cs.cancel = Mock(name='cancel')
cs.close()
chan.close.assert_not_called()
@patch('kombu.compat._iterconsume')
def test_iterconsume(self, _iterconsume, n='test_iterconsume'):
c = compat.Consumer(self.connection, queue=n, exchange=n)
cs = compat.ConsumerSet(self.connection, consumers=[c])
cs.iterconsume(limit=10, no_ack=True)
_iterconsume.assert_called_with(c.connection, cs, True, 10)
def test_revive(self, n='test_revive'):
c = compat.Consumer(self.connection, queue=n, exchange=n)
cs = compat.ConsumerSet(self.connection, consumers=[c])
with self.connection.channel() as c2:
cs.revive(c2)
assert cs.backend is c2
def test_constructor(self, prefix='0daf8h21'):
dcon = {'%s.xyx' % prefix: {'exchange': '%s.xyx' % prefix,
'routing_key': 'xyx'},
'%s.xyz' % prefix: {'exchange': '%s.xyz' % prefix,
'routing_key': 'xyz'}}
consumers = [compat.Consumer(self.connection, queue=prefix + str(i),
exchange=prefix + str(i))
for i in range(3)]
c = compat.ConsumerSet(self.connection, consumers=consumers)
c2 = compat.ConsumerSet(self.connection, from_dict=dcon)
assert len(c.queues) == 3
assert len(c2.queues) == 2
c.add_consumer(compat.Consumer(self.connection,
queue=prefix + 'xaxxxa',
exchange=prefix + 'xaxxxa'))
assert len(c.queues) == 4
for cq in c.queues:
assert cq.channel is c.channel
c2.add_consumer_from_dict(
'%s.xxx' % prefix,
exchange='%s.xxx' % prefix,
routing_key='xxx',
)
assert len(c2.queues) == 3
for c2q in c2.queues:
assert c2q.channel is c2.channel
c.discard_all()
assert c.channel.called.count('queue_purge') == 4
c.consume()
c.close()
c2.close()
assert 'basic_cancel' in c.channel
assert 'close' in c.channel
assert 'close' in c2.channel