mirror of https://github.com/celery/kombu.git
243 lines
7.8 KiB
Python
243 lines
7.8 KiB
Python
import pytest
|
|
from queue import Empty
|
|
|
|
from case import skip, patch
|
|
from kombu import messaging
|
|
from kombu import Connection, Exchange, Queue
|
|
from kombu.transport import azureservicebus
|
|
|
|
try:
|
|
# azure-servicebus version >= 0.50.0
|
|
from azure.servicebus.control_client import Message, ServiceBusService
|
|
except ImportError:
|
|
try:
|
|
# azure-servicebus version <= 0.21.1
|
|
from azure.servicebus import Message, ServiceBusService
|
|
except ImportError:
|
|
ServiceBusService = Message = None
|
|
|
|
|
|
class QueueMock:
|
|
""" Hold information about a queue. """
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.messages = []
|
|
self.message_count = len(self.messages)
|
|
|
|
def __repr__(self):
|
|
return 'QueueMock: {} messages'.format(len(self.messages))
|
|
|
|
|
|
def _create_mock_connection(url='', **kwargs):
|
|
|
|
class _Channel(azureservicebus.Channel):
|
|
# reset _fanout_queues for each instance
|
|
queues = []
|
|
_queue_service = None
|
|
|
|
def list_queues(self):
|
|
return self.queues
|
|
|
|
@property
|
|
def queue_service(self):
|
|
if self._queue_service is None:
|
|
self._queue_service = AzureServiceBusClientMock()
|
|
return self._queue_service
|
|
|
|
class Transport(azureservicebus.Transport):
|
|
Channel = _Channel
|
|
|
|
return Connection(url, transport=Transport, **kwargs)
|
|
|
|
|
|
class AzureServiceBusClientMock:
|
|
|
|
def __init__(self):
|
|
"""
|
|
Imitate the ServiceBus Client.
|
|
"""
|
|
# queues doesn't exist on the real client, here for testing.
|
|
self.queues = []
|
|
self._queue_cache = {}
|
|
self.queues.append(self.create_queue(queue_name='unittest_queue'))
|
|
|
|
def create_queue(self, queue_name, queue=None, fail_on_exist=False):
|
|
queue = QueueMock(name=queue_name)
|
|
self.queues.append(queue)
|
|
self._queue_cache[queue_name] = queue
|
|
return queue
|
|
|
|
def get_queue(self, queue_name=None):
|
|
for queue in self.queues:
|
|
if queue.name == queue_name:
|
|
return queue
|
|
|
|
def list_queues(self):
|
|
return self.queues
|
|
|
|
def send_queue_message(self, queue_name=None, message=None):
|
|
queue = self.get_queue(queue_name)
|
|
queue.messages.append(message)
|
|
|
|
def receive_queue_message(self, queue_name, peek_lock=True, timeout=60):
|
|
queue = self.get_queue(queue_name)
|
|
if queue and len(queue.messages):
|
|
return queue.messages.pop(0)
|
|
return Message()
|
|
|
|
def read_delete_queue_message(self, queue_name, timeout='60'):
|
|
return self.receive_queue_message(queue_name, timeout=timeout)
|
|
|
|
def delete_queue(self, queue_name=None):
|
|
queue = self.get_queue(queue_name)
|
|
if queue:
|
|
del queue
|
|
|
|
|
|
@skip.unless_module('azure.servicebus')
|
|
class test_Channel:
|
|
|
|
def handleMessageCallback(self, message):
|
|
self.callback_message = message
|
|
|
|
def setup(self):
|
|
self.url = 'azureservicebus://'
|
|
self.queue_name = 'unittest_queue'
|
|
|
|
self.exchange = Exchange('test_servicebus', type='direct')
|
|
self.queue = Queue(self.queue_name, self.exchange, self.queue_name)
|
|
self.connection = _create_mock_connection(self.url)
|
|
self.channel = self.connection.default_channel
|
|
self.queue(self.channel).declare()
|
|
|
|
self.producer = messaging.Producer(self.channel,
|
|
self.exchange,
|
|
routing_key=self.queue_name)
|
|
|
|
self.channel.basic_consume(self.queue_name,
|
|
no_ack=False,
|
|
callback=self.handleMessageCallback,
|
|
consumer_tag='unittest')
|
|
|
|
def teardown(self):
|
|
# Removes QoS reserved messages so we don't restore msgs on shutdown.
|
|
try:
|
|
qos = self.channel._qos
|
|
except AttributeError:
|
|
pass
|
|
else:
|
|
if qos:
|
|
qos._dirty.clear()
|
|
qos._delivered.clear()
|
|
|
|
def test_queue_service(self):
|
|
# Test gettings queue service without credentials
|
|
conn = Connection(self.url, transport=azureservicebus.Transport)
|
|
with pytest.raises(ValueError) as exc:
|
|
conn.channel()
|
|
assert exc == 'You need to provide servicebus namespace'
|
|
|
|
# Test getting queue service when queue_service is not setted
|
|
with patch('kombu.transport.azureservicebus.ServiceBusService') as m:
|
|
channel = conn.channel()
|
|
|
|
# Remove queue service to get from service bus again
|
|
channel._queue_service = None
|
|
channel.queue_service
|
|
|
|
assert m.call_count == 2
|
|
|
|
# Calling queue_service again needs to reuse ServiceBus instance
|
|
channel.queue_service
|
|
assert m.call_count == 2
|
|
|
|
def test_conninfo(self):
|
|
conninfo = self.channel.conninfo
|
|
assert conninfo is self.connection
|
|
|
|
def test_transport_type(self):
|
|
transport_options = self.channel.transport_options
|
|
assert transport_options == {}
|
|
|
|
def test_visibility_timeout(self):
|
|
# Test getting default visibility timeout
|
|
assert (
|
|
self.channel.visibility_timeout ==
|
|
azureservicebus.Channel.default_visibility_timeout
|
|
)
|
|
|
|
# Test getting value setted in transport options
|
|
del self.channel.visibility_timeout
|
|
self.channel.transport_options['visibility_timeout'] = 10
|
|
assert self.channel.visibility_timeout == 10
|
|
|
|
def test_wait_timeout_seconds(self):
|
|
# Test getting default wait timeout seconds
|
|
assert (
|
|
self.channel.wait_time_seconds ==
|
|
azureservicebus.Channel.default_wait_time_seconds
|
|
)
|
|
|
|
# Test getting value setted in transport options
|
|
del self.channel.wait_time_seconds
|
|
self.channel.transport_options['wait_time_seconds'] = 10
|
|
assert self.channel.wait_time_seconds == 10
|
|
|
|
def test_peek_lock(self):
|
|
# Test getting default peek lock
|
|
assert (
|
|
self.channel.peek_lock ==
|
|
azureservicebus.Channel.default_peek_lock
|
|
)
|
|
|
|
# Test getting value setted in transport options
|
|
del self.channel.peek_lock
|
|
self.channel.transport_options['peek_lock'] = True
|
|
assert self.channel.peek_lock is True
|
|
|
|
def test_get_from_azure(self):
|
|
# Test getting a single message
|
|
message = 'my test message'
|
|
self.producer.publish(message)
|
|
result = self.channel._get(self.queue_name)
|
|
assert 'body' in result.keys()
|
|
|
|
# Test getting multiple messages
|
|
for i in range(3):
|
|
message = f'message: {i}'
|
|
self.producer.publish(message)
|
|
|
|
queue_service = self.channel.queue_service
|
|
assert len(queue_service.get_queue(self.queue_name).messages) == 3
|
|
|
|
for i in range(3):
|
|
result = self.channel._get(self.queue_name)
|
|
|
|
assert len(queue_service.get_queue(self.queue_name).messages) == 0
|
|
|
|
def test_get_with_empty_list(self):
|
|
with pytest.raises(Empty):
|
|
self.channel._get(self.queue_name)
|
|
|
|
def test_put_and_get(self):
|
|
message = 'my test message'
|
|
self.producer.publish(message)
|
|
results = self.queue(self.channel).get().payload
|
|
assert message == results
|
|
|
|
def test_delete_queue(self):
|
|
# Test deleting queue without message
|
|
queue_name = 'new_unittest_queue'
|
|
self.channel._new_queue(queue_name)
|
|
|
|
assert queue_name in self.channel._queue_cache
|
|
self.channel._delete(queue_name)
|
|
assert queue_name not in self.channel._queue_cache
|
|
|
|
# Test deleting queue with message
|
|
message = 'my test message'
|
|
self.producer.publish(message)
|
|
self.channel._delete(self.queue_name)
|
|
assert queue_name not in self.channel._queue_cache
|