Innovenergy_trunk/NodeRed/NodeRedFiles/pika-0.13.1/tests/unit/channel_tests.py

1438 lines
60 KiB
Python
Raw Normal View History

2024-06-05 10:33:44 +00:00
"""
Tests for pika.channel.Channel
"""
import collections
import logging
import sys
import unittest
import warnings
import mock
from pika import channel, connection, exceptions, frame, spec
class ConnectionTemplate(connection.Connection):
"""Template for using as mock spec_set for the pika Connection class. It
defines members accessed by the code under test that would be defined in
the base class's constructor.
"""
callbacks = None
# Suppress pylint warnings about specific abstract methods not being
# overridden
_adapter_connect = connection.Connection._adapter_connect
_adapter_disconnect = connection.Connection._adapter_disconnect
_flush_outbound = connection.Connection._flush_outbound
add_timeout = connection.Connection.add_timeout
remove_timeout = connection.Connection.remove_timeout
class ChannelTests(unittest.TestCase):
@staticmethod
@mock.patch('pika.connection.Connection', autospec=ConnectionTemplate)
def _create_connection(connection_class_mock=None):
return connection_class_mock()
def setUp(self):
self.connection = self._create_connection()
self._on_openok_callback = mock.Mock()
self.obj = channel.Channel(self.connection, 1,
self._on_openok_callback)
warnings.resetwarnings()
def tearDown(self):
del self.connection
del self._on_openok_callback
del self.obj
warnings.resetwarnings()
def test_init_invalid_channel_number(self):
self.assertRaises(exceptions.InvalidChannelNumber, channel.Channel,
'Foo', self.connection, lambda *args: None)
def test_init_channel_number(self):
self.assertEqual(self.obj.channel_number, 1)
def test_init_callbacks(self):
self.assertEqual(self.obj.callbacks, self.connection.callbacks)
def test_init_connection(self):
self.assertEqual(self.obj.connection, self.connection)
def test_init_content_frame_assembler(self):
self.assertIsInstance(self.obj._content_assembler,
channel.ContentFrameAssembler)
def test_init_blocked(self):
self.assertIsInstance(self.obj._blocked, collections.deque)
def test_init_blocking(self):
self.assertEqual(self.obj._blocking, None)
def test_init_on_flowok_callback(self):
self.assertEqual(self.obj._on_flowok_callback, None)
def test_init_has_on_flow_callback(self):
self.assertEqual(self.obj._has_on_flow_callback, False)
def test_init_on_openok_callback(self):
self.assertEqual(self.obj._on_openok_callback,
self._on_openok_callback)
def test_init_state(self):
self.assertEqual(self.obj._state, channel.Channel.CLOSED)
def test_init_cancelled(self):
self.assertIsInstance(self.obj._cancelled, set)
def test_init_consumers(self):
self.assertEqual(self.obj._consumers, dict())
def test_init_flow(self):
self.assertEqual(self.obj.flow_active, True)
def test_init_on_getok_callback(self):
self.assertEqual(self.obj._on_getok_callback, None)
def test_add_callback(self):
mock_callback = mock.Mock()
self.obj.add_callback(mock_callback, [spec.Basic.Qos])
self.connection.callbacks.add.assert_called_once_with(
self.obj.channel_number, spec.Basic.Qos, mock_callback, True)
def test_add_callback_multiple_replies(self):
mock_callback = mock.Mock()
self.obj.add_callback(mock_callback,
[spec.Basic.Qos, spec.Basic.QosOk])
calls = [
mock.call(self.obj.channel_number, spec.Basic.Qos, mock_callback,
True),
mock.call(self.obj.channel_number, spec.Basic.QosOk, mock_callback,
True)
]
self.connection.callbacks.add.assert_has_calls(calls)
def test_add_on_cancel_callback(self):
mock_callback = mock.Mock()
self.obj.add_on_cancel_callback(mock_callback)
self.connection.callbacks.add.assert_called_once_with(
self.obj.channel_number, spec.Basic.Cancel, mock_callback, False)
def test_add_on_close_callback(self):
mock_callback = mock.Mock()
self.obj.add_on_close_callback(mock_callback)
self.connection.callbacks.add.assert_called_once_with(
self.obj.channel_number, '_on_channel_close', mock_callback, False,
self.obj)
def test_add_on_flow_callback(self):
mock_callback = mock.Mock()
self.obj.add_on_flow_callback(mock_callback)
self.connection.callbacks.add.assert_called_once_with(
self.obj.channel_number, spec.Channel.Flow, mock_callback, False)
def test_add_on_return_callback(self):
mock_callback = mock.Mock()
self.obj.add_on_return_callback(mock_callback)
self.connection.callbacks.add.assert_called_once_with(
self.obj.channel_number, '_on_return', mock_callback, False)
def test_basic_ack_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_ack)
@mock.patch('pika.spec.Basic.Ack')
@mock.patch('pika.channel.Channel._send_method')
def test_basic_ack_calls_send_method(self, send_method, _unused):
self.obj._set_state(self.obj.OPEN)
self.obj.basic_ack(1, False)
send_method.assert_called_once_with(spec.Basic.Ack(1, False))
def test_basic_cancel_asynch(self):
self.obj._set_state(self.obj.OPEN)
self.obj._consumers['ctag0'] = logging.debug
self.obj._rpc = mock.Mock(wraps=self.obj._rpc)
self.obj.basic_cancel(consumer_tag='ctag0', nowait=True)
self.assertTrue(self.obj._rpc.called)
self.assertFalse(self.obj.callbacks.add.called)
def test_basic_cancel_asynch_with_user_callback_raises_value_error(self):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag0'
callback_mock = mock.Mock()
self.obj._consumers[consumer_tag] = callback_mock
self.assertRaises(
ValueError,
self.obj.basic_cancel,
callback_mock,
consumer_tag,
nowait=True)
@mock.patch('pika.channel.Channel._validate_channel_and_callback')
def test_basic_cancel_calls_validate(self, validate):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag0'
callback_mock = mock.Mock()
self.obj._consumers[consumer_tag] = mock.Mock()
self.obj.basic_cancel(callback_mock, consumer_tag)
validate.assert_called_once_with(callback_mock)
def test_basic_cancel_synch(self):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag0'
callback_mock = mock.Mock()
self.obj._consumers[consumer_tag] = mock.Mock()
self.obj.basic_cancel(callback_mock, consumer_tag)
# Verify consumer tag added to the cancelled list
self.assertListEqual(list(self.obj._cancelled), [consumer_tag])
# Verify user completion callback registered
self.obj.callbacks.add.assert_any_call(
self.obj.channel_number, spec.Basic.CancelOk, callback_mock)
# Verify Channel._on_cancelok callback registered
self.obj.callbacks.add.assert_any_call(
self.obj.channel_number,
spec.Basic.CancelOk,
self.obj._on_cancelok,
arguments={
'consumer_tag': 'ctag0'
})
# Verify Channel._on_synchronous_complete callback registered
self.obj.callbacks.add.assert_any_call(
self.obj.channel_number,
spec.Basic.CancelOk,
self.obj._on_synchronous_complete,
arguments={
'consumer_tag': 'ctag0'
})
def test_basic_cancel_synch_no_user_callback_raises_value_error(self):
self.obj._set_state(self.obj.OPEN)
self.obj._consumers['ctag0'] = mock.Mock()
with self.assertRaises(ValueError):
self.obj.basic_cancel(consumer_tag='ctag0')
# Verify arg error detected raised without making state changes
self.assertIn('ctag0', self.obj._consumers)
self.assertEqual(len(self.obj._cancelled), 0)
def test_basic_cancel_then_close(self):
self.obj._set_state(self.obj.OPEN)
callback_mock = mock.Mock()
consumer_tag = 'ctag0'
self.obj._consumers[consumer_tag] = mock.Mock()
self.obj.basic_cancel(callback_mock, consumer_tag)
try:
self.obj.close()
except exceptions.ChannelClosed:
self.fail('unable to cancel consumers as channel is closing')
self.assertTrue(self.obj.is_closing)
@mock.patch('pika.channel.Channel._rpc')
def test_basic_cancel_unknown_consumer_tag(self, rpc):
self.obj._set_state(self.obj.OPEN)
callback_mock = mock.Mock()
consumer_tag = 'ctag0'
self.obj.basic_cancel(callback_mock, consumer_tag)
self.assertFalse(rpc.called)
def test_basic_consume_channel_closed(self):
mock_callback = mock.Mock()
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_consume,
mock_callback, 'test-queue')
@mock.patch('pika.channel.Channel._validate_channel_and_callback')
def test_basic_consume_calls_validate(self, validate):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.basic_consume(mock_callback, 'test-queue')
validate.assert_called_once_with(mock_callback)
def test_basic_consume_consumer_tag(self):
self.obj._set_state(self.obj.OPEN)
expectation = 'ctag1.'
mock_callback = mock.Mock()
self.assertEqual(
self.obj.basic_consume(mock_callback, 'test-queue')[:6],
expectation)
def test_basic_consume_consumer_tag_cancelled_full(self):
self.obj._set_state(self.obj.OPEN)
expectation = 'ctag1.'
mock_callback = mock.Mock()
for ctag in ['ctag1.%i' % ii for ii in range(11)]:
self.obj._cancelled.add(ctag)
self.assertEqual(
self.obj.basic_consume(mock_callback, 'test-queue')[:6],
expectation)
def test_basic_consume_consumer_tag_in_consumers(self):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag1.0'
mock_callback = mock.Mock()
self.obj.basic_consume(
mock_callback, 'test-queue', consumer_tag=consumer_tag)
self.assertIn(consumer_tag, self.obj._consumers)
def test_basic_consume_duplicate_consumer_tag_raises(self):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag1.0'
mock_callback = mock.Mock()
self.obj._consumers[consumer_tag] = logging.debug
self.assertRaises(exceptions.DuplicateConsumerTag,
self.obj.basic_consume, mock_callback, 'test-queue',
False, False, consumer_tag)
def test_basic_consume_consumers_callback_value(self):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag1.0'
mock_callback = mock.Mock()
self.obj.basic_consume(
mock_callback, 'test-queue', consumer_tag=consumer_tag)
self.assertEqual(self.obj._consumers[consumer_tag], mock_callback)
@mock.patch('pika.spec.Basic.Consume')
@mock.patch('pika.channel.Channel._rpc')
def test_basic_consume_consumers_rpc_called(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag1.0'
mock_callback = mock.Mock()
self.obj.basic_consume(
mock_callback, 'test-queue', consumer_tag=consumer_tag)
expectation = spec.Basic.Consume(
queue='test-queue',
consumer_tag=consumer_tag,
no_ack=False,
exclusive=False)
rpc.assert_called_once_with(expectation, self.obj._on_eventok,
[(spec.Basic.ConsumeOk, {
'consumer_tag': consumer_tag
})])
@mock.patch('pika.channel.Channel._validate_channel_and_callback')
def test_basic_get_calls_validate(self, validate):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.basic_get(mock_callback, 'test-queue')
validate.assert_called_once_with(mock_callback)
@mock.patch('pika.channel.Channel._send_method')
def test_basic_get_callback(self, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.basic_get(mock_callback, 'test-queue')
self.assertEqual(self.obj._on_getok_callback, mock_callback)
@mock.patch('pika.spec.Basic.Get')
@mock.patch('pika.channel.Channel._send_method')
def test_basic_get_send_method_called(self, send_method, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.basic_get(mock_callback, 'test-queue', False)
send_method.assert_called_once_with(
spec.Basic.Get(queue='test-queue', no_ack=False))
def test_basic_nack_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_nack, 0,
False, True)
@mock.patch('pika.spec.Basic.Nack')
@mock.patch('pika.channel.Channel._send_method')
def test_basic_nack_send_method_request(self, send_method, _unused):
self.obj._set_state(self.obj.OPEN)
self.obj.basic_nack(1, False, True)
send_method.assert_called_once_with(spec.Basic.Nack(1, False, True))
def test_basic_publish_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_publish,
'foo', 'bar', 'baz')
@mock.patch('pika.channel.LOGGER')
@mock.patch('pika.spec.Basic.Publish')
@mock.patch('pika.channel.Channel._send_method')
def test_immediate_called_logger_warning(self, _send_method, _unused,
logger):
self.obj._set_state(self.obj.OPEN)
exchange = 'basic_publish_test'
routing_key = 'routing-key-fun'
body = b'This is my body'
properties = spec.BasicProperties(content_type='text/plain')
mandatory = False
immediate = True
self.obj.basic_publish(exchange, routing_key, body, properties,
mandatory, immediate)
logger.warning.assert_called_once_with('The immediate flag is '
'deprecated in RabbitMQ')
@mock.patch('pika.spec.Basic.Publish')
@mock.patch('pika.channel.Channel._send_method')
def test_basic_publish_send_method_request(self, send_method, _unused):
self.obj._set_state(self.obj.OPEN)
exchange = 'basic_publish_test'
routing_key = 'routing-key-fun'
body = b'This is my body'
properties = spec.BasicProperties(content_type='text/plain')
mandatory = False
immediate = False
self.obj.basic_publish(exchange, routing_key, body, properties,
mandatory, immediate)
send_method.assert_called_once_with(
spec.Basic.Publish(
exchange=exchange,
routing_key=routing_key,
mandatory=mandatory,
immediate=immediate), (properties, body))
def test_basic_qos_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_qos, 0,
False, True)
@mock.patch('pika.spec.Basic.Qos')
@mock.patch('pika.channel.Channel._rpc')
def test_basic_qos_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.basic_qos(mock_callback, 10, 20, False)
rpc.assert_called_once_with(
spec.Basic.Qos(10, 20, False), mock_callback, [spec.Basic.QosOk])
def test_basic_reject_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_reject, 1,
False)
@mock.patch('pika.spec.Basic.Reject')
@mock.patch('pika.channel.Channel._send_method')
def test_basic_reject_send_method_request_with_int_tag(
self, send_method, _unused):
self.obj._set_state(self.obj.OPEN)
self.obj.basic_reject(1, True)
send_method.assert_called_once_with(spec.Basic.Reject(1, True))
def test_basic_reject_spec_with_int_tag(self):
decoded = spec.Basic.Reject()
decoded.decode(b''.join(spec.Basic.Reject(1, True).encode()))
self.assertEqual(decoded.delivery_tag, 1)
self.assertIs(decoded.requeue, True)
@mock.patch('pika.spec.Basic.Reject')
@mock.patch('pika.channel.Channel._send_method')
def test_basic_reject_send_method_request_with_long_tag(
self, send_method, _unused):
self.obj._set_state(self.obj.OPEN)
# NOTE: we use `sys.maxsize` for compatibility with python 3, which
# doesn't have `sys.maxint`
self.obj.basic_reject(sys.maxsize, True)
send_method.assert_called_once_with(
spec.Basic.Reject(sys.maxsize, True))
def test_basic_reject_spec_with_long_tag(self):
# NOTE: we use `sys.maxsize` for compatibility with python 3, which
# doesn't have `sys.maxint`
decoded = spec.Basic.Reject()
decoded.decode(b''.join(spec.Basic.Reject(sys.maxsize, True).encode()))
self.assertEqual(decoded.delivery_tag, sys.maxsize)
self.assertIs(decoded.requeue, True)
def test_basic_recover_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.basic_qos, 0,
False, True)
@mock.patch('pika.spec.Basic.Recover')
@mock.patch('pika.channel.Channel._rpc')
def test_basic_recover_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.basic_recover(mock_callback, True)
rpc.assert_called_once_with(
spec.Basic.Recover(True), mock_callback, [spec.Basic.RecoverOk])
def test_close_in_closing_state_raises_already_closing(self):
self.obj._set_state(self.obj.CLOSING)
self.assertRaises(exceptions.ChannelAlreadyClosing, self.obj.close)
self.assertTrue(self.obj.is_closing)
def test_close_in_closed_state_raises_channel_error_and_stays_closed(self):
self.assertTrue(self.obj.is_closed)
self.assertRaises(exceptions.ChannelClosed, self.obj.close)
self.assertTrue(self.obj.is_closed)
@mock.patch('pika.spec.Channel.Close')
def test_close_in_opening_state(self, _unused):
self.obj._set_state(self.obj.OPENING)
self.obj._rpc = mock.Mock(wraps=self.obj._rpc)
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
# close() called by user
self.obj.close(200, 'Got to go')
self.obj._rpc.assert_called_once_with(
spec.Channel.Close(200, 'Got to go', 0, 0), self.obj._on_closeok,
[spec.Channel.CloseOk])
self.assertEqual(self.obj._closing_code_and_text, (0, ''))
self.assertEqual(self.obj._state, self.obj.CLOSING)
# OpenOk method from broker
self.obj._on_openok(
frame.Method(self.obj.channel_number,
spec.Channel.OpenOk(self.obj.channel_number)))
self.assertEqual(self.obj._state, self.obj.CLOSING)
self.assertEqual(self.obj.callbacks.process.call_count, 0)
# CloseOk method from broker
self.obj._on_closeok(
frame.Method(self.obj.channel_number, spec.Channel.CloseOk()))
self.assertEqual(self.obj._state, self.obj.CLOSED)
self.obj.callbacks.process.assert_any_call(self.obj.channel_number,
'_on_channel_close',
self.obj, self.obj, 0, '')
self.assertEqual(self.obj._cleanup.call_count, 1)
def test_close_in_open_state_transitions_to_closing(self):
self.obj._set_state(self.obj.OPEN)
self.obj.close()
self.assertEqual(self.obj._state, channel.Channel.CLOSING)
def test_close_basic_cancel_called(self):
self.obj._set_state(self.obj.OPEN)
self.obj._consumers['abc'] = None
with mock.patch.object(self.obj, 'basic_cancel') as basic_cancel:
self.obj.close()
# this is actually not necessary but Pika currently cancels
# every consumer before closing the channel
basic_cancel.assert_called_once_with(
consumer_tag='abc', nowait=True)
def test_confirm_delivery_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.confirm_delivery)
def test_confirm_delivery_raises_method_not_implemented_for_confirms(self):
self.obj._set_state(self.obj.OPEN)
# Since connection is a mock.Mock, overwrite the method def with False
self.obj.connection.publisher_confirms = False
self.assertRaises(exceptions.MethodNotImplemented,
self.obj.confirm_delivery, logging.debug)
def test_confirm_delivery_raises_method_not_implemented_for_nack(self):
self.obj._set_state(self.obj.OPEN)
# Since connection is a mock.Mock, overwrite the method def with False
self.obj.connection.basic_nack = False
self.assertRaises(exceptions.MethodNotImplemented,
self.obj.confirm_delivery, logging.debug)
def test_confirm_delivery_async(self):
self.obj._set_state(self.obj.OPEN)
user_ack_nack_callback = mock.Mock()
self.obj.confirm_delivery(callback=user_ack_nack_callback, nowait=True)
self.assertEqual(self.obj.callbacks.add.call_count, 2)
self.obj.callbacks.add.assert_any_call(self.obj.channel_number,
spec.Basic.Ack,
user_ack_nack_callback, False)
self.obj.callbacks.add.assert_any_call(self.obj.channel_number,
spec.Basic.Nack,
user_ack_nack_callback, False)
def test_confirm_delivery_callback_without_nowait_selectok(self):
self.obj._set_state(self.obj.OPEN)
expectation = [
self.obj.channel_number, spec.Confirm.SelectOk,
self.obj._on_selectok
]
self.obj.confirm_delivery(logging.debug)
self.obj.callbacks.add.assert_called_with(*expectation, arguments=None)
def test_confirm_delivery_callback_basic_ack(self):
self.obj._set_state(self.obj.OPEN)
expectation = (self.obj.channel_number, spec.Basic.Ack, logging.debug,
False)
self.obj.confirm_delivery(logging.debug)
self.obj.callbacks.add.assert_any_call(*expectation)
def test_confirm_delivery_callback_basic_nack(self):
self.obj._set_state(self.obj.OPEN)
expectation = (self.obj.channel_number, spec.Basic.Nack, logging.debug,
False)
self.obj.confirm_delivery(logging.debug)
self.obj.callbacks.add.assert_any_call(*expectation)
def test_confirm_delivery_no_callback_callback_call_count(self):
self.obj._set_state(self.obj.OPEN)
self.obj.confirm_delivery()
expectation = [
mock.call(
*[
self.obj.channel_number, spec.Confirm.SelectOk,
self.obj._on_synchronous_complete
],
arguments=None),
mock.call(
*[
self.obj.channel_number,
spec.Confirm.SelectOk,
self.obj._on_selectok,
],
arguments=None)
]
self.assertEqual(self.obj.callbacks.add.call_args_list, expectation)
def test_confirm_delivery_no_callback_no_basic_ack_callback(self):
self.obj._set_state(self.obj.OPEN)
expectation = [self.obj.channel_number, spec.Basic.Ack, None, False]
self.obj.confirm_delivery()
self.assertNotIn(
mock.call(*expectation), self.obj.callbacks.add.call_args_list)
def test_confirm_delivery_no_callback_no_basic_nack_callback(self):
self.obj._set_state(self.obj.OPEN)
expectation = [self.obj.channel_number, spec.Basic.Nack, None, False]
self.obj.confirm_delivery()
self.assertNotIn(
mock.call(*expectation), self.obj.callbacks.add.call_args_list)
def test_consumer_tags(self):
self.assertListEqual(self.obj.consumer_tags,
list(self.obj._consumers.keys()))
def test_exchange_bind_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.exchange_bind,
None, 'foo', 'bar', 'baz')
def test_exchange_bind_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.exchange_bind, 'callback',
'foo', 'bar', 'baz')
@mock.patch('pika.spec.Exchange.Bind')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_bind_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_bind(mock_callback, 'foo', 'bar', 'baz')
rpc.assert_called_once_with(
spec.Exchange.Bind(0, 'foo', 'bar', 'baz'), mock_callback,
[spec.Exchange.BindOk])
@mock.patch('pika.spec.Exchange.Bind')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_bind_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_bind(mock_callback, 'foo', 'bar', 'baz', nowait=True)
rpc.assert_called_once_with(
spec.Exchange.Bind(0, 'foo', 'bar', 'baz'), mock_callback, [])
def test_exchange_declare_raises_channel_closed(self):
self.assertRaises(
exceptions.ChannelClosed,
self.obj.exchange_declare,
exchange='foo')
def test_exchange_declare_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.exchange_declare, 'callback',
'foo')
@mock.patch('pika.spec.Exchange.Declare')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_declare_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_declare(mock_callback, 'foo')
rpc.assert_called_once_with(
spec.Exchange.Declare(0, 'foo'), mock_callback,
[spec.Exchange.DeclareOk])
@mock.patch('pika.spec.Exchange.Declare')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_declare_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_declare(mock_callback, 'foo', nowait=True)
rpc.assert_called_once_with(
spec.Exchange.Declare(0, 'foo'), mock_callback, [])
def test_exchange_delete_raises_channel_closed(self):
self.assertRaises(
exceptions.ChannelClosed, self.obj.exchange_delete, exchange='foo')
def test_exchange_delete_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.exchange_delete, 'callback',
'foo')
@mock.patch('pika.spec.Exchange.Delete')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_delete_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_delete(mock_callback, 'foo')
rpc.assert_called_once_with(
spec.Exchange.Delete(0, 'foo'), mock_callback,
[spec.Exchange.DeleteOk])
@mock.patch('pika.spec.Exchange.Delete')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_delete_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_delete(mock_callback, 'foo', nowait=True)
rpc.assert_called_once_with(
spec.Exchange.Delete(0, 'foo'), mock_callback, [])
def test_exchange_unbind_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.exchange_unbind,
None, 'foo', 'bar', 'baz')
def test_exchange_unbind_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.exchange_unbind, 'callback',
'foo', 'bar', 'baz')
@mock.patch('pika.spec.Exchange.Unbind')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_unbind_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_unbind(mock_callback, 'foo', 'bar', 'baz')
rpc.assert_called_once_with(
spec.Exchange.Unbind(0, 'foo', 'bar', 'baz'), mock_callback,
[spec.Exchange.UnbindOk])
@mock.patch('pika.spec.Exchange.Unbind')
@mock.patch('pika.channel.Channel._rpc')
def test_exchange_unbind_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.exchange_unbind(
mock_callback, 'foo', 'bar', 'baz', nowait=True)
rpc.assert_called_once_with(
spec.Exchange.Unbind(0, 'foo', 'bar', 'baz'), mock_callback, [])
def test_flow_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.flow, 'foo', True)
def test_flow_raises_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.flow, 'foo', True)
@mock.patch('pika.spec.Channel.Flow')
@mock.patch('pika.channel.Channel._rpc')
def test_flow_on_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.flow(mock_callback, True)
rpc.assert_called_once_with(
spec.Channel.Flow(True), self.obj._on_flowok,
[spec.Channel.FlowOk])
@mock.patch('pika.spec.Channel.Flow')
@mock.patch('pika.channel.Channel._rpc')
def test_flow_off_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.flow(mock_callback, False)
rpc.assert_called_once_with(
spec.Channel.Flow(False), self.obj._on_flowok,
[spec.Channel.FlowOk])
@mock.patch('pika.channel.Channel._rpc')
def test_flow_on_flowok_callback(self, _rpc):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.flow(mock_callback, True)
self.assertEqual(self.obj._on_flowok_callback, mock_callback)
def test_is_closed_true(self):
self.obj._set_state(self.obj.CLOSED)
self.assertTrue(self.obj.is_closed)
def test_is_closed_false(self):
self.obj._set_state(self.obj.OPEN)
self.assertFalse(self.obj.is_closed)
def test_is_closing_true(self):
self.obj._set_state(self.obj.CLOSING)
self.assertTrue(self.obj.is_closing)
def test_is_closing_false(self):
self.obj._set_state(self.obj.OPEN)
self.assertFalse(self.obj.is_closing)
@mock.patch('pika.channel.Channel._rpc')
def test_channel_open_add_callbacks_called(self, _rpc):
with mock.patch.object(self.obj, '_add_callbacks') as _add_callbacks:
self.obj.open()
_add_callbacks.assert_called_once_with()
def test_queue_bind_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.queue_bind, None,
'foo', 'bar', 'baz')
def test_queue_bind_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.queue_bind, 'callback', 'foo',
'bar', 'baz')
@mock.patch('pika.spec.Queue.Bind')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_bind_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_bind(mock_callback, 'foo', 'bar', 'baz')
rpc.assert_called_once_with(
spec.Queue.Bind(0, 'foo', 'bar', 'baz'), mock_callback,
[spec.Queue.BindOk])
@mock.patch('pika.spec.Queue.Bind')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_bind_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_bind(mock_callback, 'foo', 'bar', 'baz', nowait=True)
rpc.assert_called_once_with(
spec.Queue.Bind(0, 'foo', 'bar', 'baz'), mock_callback, [])
def test_queue_declare_raises_channel_closed(self):
self.assertRaises(
exceptions.ChannelClosed,
self.obj.queue_declare,
None,
queue='foo')
def test_queue_declare_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.queue_declare, 'callback',
'foo')
@mock.patch('pika.spec.Queue.Declare')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_declare_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_declare(mock_callback, 'foo')
rpc.assert_called_once_with(
spec.Queue.Declare(0, 'foo'), mock_callback,
[(spec.Queue.DeclareOk, {
'queue': 'foo'
})])
@mock.patch('pika.spec.Queue.Declare')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_declare_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_declare(mock_callback, 'foo', nowait=True)
rpc.assert_called_once_with(
spec.Queue.Declare(0, 'foo'), mock_callback, [])
def test_queue_delete_raises_channel_closed(self):
self.assertRaises(
exceptions.ChannelClosed, self.obj.queue_delete, queue='foo')
def test_queue_delete_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.queue_delete, 'callback', 'foo')
@mock.patch('pika.spec.Queue.Delete')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_delete_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_delete(mock_callback, 'foo')
rpc.assert_called_once_with(
spec.Queue.Delete(0, 'foo'), mock_callback, [spec.Queue.DeleteOk])
@mock.patch('pika.spec.Queue.Delete')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_delete_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_delete(mock_callback, 'foo', nowait=True)
rpc.assert_called_once_with(
spec.Queue.Delete(0, 'foo'), mock_callback, [])
def test_queue_purge_raises_channel_closed(self):
self.assertRaises(
exceptions.ChannelClosed, self.obj.queue_purge, queue='foo')
def test_queue_purge_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.queue_purge, 'callback', 'foo')
@mock.patch('pika.spec.Queue.Purge')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_purge_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_purge(mock_callback, 'foo')
rpc.assert_called_once_with(
spec.Queue.Purge(0, 'foo'), mock_callback, [spec.Queue.PurgeOk])
@mock.patch('pika.spec.Queue.Purge')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_purge_rpc_request_nowait(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_purge(mock_callback, 'foo', nowait=True)
rpc.assert_called_once_with(
spec.Queue.Purge(0, 'foo'), mock_callback, [])
def test_queue_unbind_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.queue_unbind,
None, 'foo', 'bar', 'baz')
def test_queue_unbind_raises_value_error_on_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj.queue_unbind, 'callback', 'foo',
'bar', 'baz')
@mock.patch('pika.spec.Queue.Unbind')
@mock.patch('pika.channel.Channel._rpc')
def test_queue_unbind_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.queue_unbind(mock_callback, 'foo', 'bar', 'baz')
rpc.assert_called_once_with(
spec.Queue.Unbind(0, 'foo', 'bar', 'baz'), mock_callback,
[spec.Queue.UnbindOk])
def test_tx_commit_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj.tx_commit, None)
@mock.patch('pika.spec.Tx.Commit')
@mock.patch('pika.channel.Channel._rpc')
def test_tx_commit_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.tx_commit(mock_callback)
rpc.assert_called_once_with(spec.Tx.Commit(), mock_callback,
[spec.Tx.CommitOk])
@mock.patch('pika.spec.Tx.Rollback')
@mock.patch('pika.channel.Channel._rpc')
def test_tx_rollback_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.tx_rollback(mock_callback)
rpc.assert_called_once_with(spec.Tx.Rollback(), mock_callback,
[spec.Tx.RollbackOk])
@mock.patch('pika.spec.Tx.Select')
@mock.patch('pika.channel.Channel._rpc')
def test_tx_select_rpc_request(self, rpc, _unused):
self.obj._set_state(self.obj.OPEN)
mock_callback = mock.Mock()
self.obj.tx_select(mock_callback)
rpc.assert_called_once_with(spec.Tx.Select(), mock_callback,
[spec.Tx.SelectOk])
# Test internal methods
def test_add_callbacks_basic_cancel_empty_added(self):
self.obj._add_callbacks()
self.obj.callbacks.add.assert_any_call(self.obj.channel_number,
spec.Basic.Cancel,
self.obj._on_cancel, False)
def test_add_callbacks_basic_get_empty_added(self):
self.obj._add_callbacks()
self.obj.callbacks.add.assert_any_call(self.obj.channel_number,
spec.Basic.GetEmpty,
self.obj._on_getempty, False)
def test_add_callbacks_channel_close_added(self):
self.obj._add_callbacks()
self.obj.callbacks.add.assert_any_call(self.obj.channel_number,
spec.Channel.Close,
self.obj._on_close, True)
def test_add_callbacks_channel_flow_added(self):
self.obj._add_callbacks()
self.obj.callbacks.add.assert_any_call(self.obj.channel_number,
spec.Channel.Flow,
self.obj._on_flow, False)
def test_cleanup(self):
self.obj._cleanup()
self.obj.callbacks.cleanup.assert_called_once_with(
str(self.obj.channel_number))
def test_handle_content_frame_method_returns_none(self):
frame_value = frame.Method(1, spec.Basic.Deliver('ctag0', 1))
self.assertEqual(self.obj._handle_content_frame(frame_value), None)
def test_handle_content_frame_sets_method_frame(self):
frame_value = frame.Method(1, spec.Basic.Deliver('ctag0', 1))
self.obj._handle_content_frame(frame_value)
self.assertEqual(self.obj._content_assembler._method_frame,
frame_value)
def test_handle_content_frame_sets_header_frame(self):
frame_value = frame.Header(1, 10, spec.BasicProperties())
self.obj._handle_content_frame(frame_value)
self.assertEqual(self.obj._content_assembler._header_frame,
frame_value)
def test_handle_content_frame_basic_deliver_called(self):
method_value = frame.Method(1, spec.Basic.Deliver('ctag0', 1))
self.obj._handle_content_frame(method_value)
header_value = frame.Header(1, 10, spec.BasicProperties())
self.obj._handle_content_frame(header_value)
body_value = frame.Body(1, b'0123456789')
with mock.patch.object(self.obj, '_on_deliver') as deliver:
self.obj._handle_content_frame(body_value)
deliver.assert_called_once_with(method_value, header_value,
b'0123456789')
def test_handle_content_frame_basic_get_called(self):
method_value = frame.Method(1, spec.Basic.GetOk('ctag0', 1))
self.obj._handle_content_frame(method_value)
header_value = frame.Header(1, 10, spec.BasicProperties())
self.obj._handle_content_frame(header_value)
body_value = frame.Body(1, b'0123456789')
with mock.patch.object(self.obj, '_on_getok') as getok:
self.obj._handle_content_frame(body_value)
getok.assert_called_once_with(method_value, header_value,
b'0123456789')
def test_handle_content_frame_basic_return_called(self):
method_value = frame.Method(1,
spec.Basic.Return(999, 'Reply Text',
'exchange_value',
'routing.key'))
self.obj._handle_content_frame(method_value)
header_value = frame.Header(1, 10, spec.BasicProperties())
self.obj._handle_content_frame(header_value)
body_value = frame.Body(1, b'0123456789')
with mock.patch.object(self.obj, '_on_return') as basic_return:
self.obj._handle_content_frame(body_value)
basic_return.assert_called_once_with(method_value, header_value,
b'0123456789')
def test_has_content_true(self):
self.assertTrue(spec.has_content(spec.Basic.GetOk.INDEX))
def test_has_content_false(self):
self.assertFalse(spec.has_content(spec.Basic.Ack.INDEX))
def test_on_cancel_not_appended_cancelled(self):
consumer_tag = 'ctag0'
frame_value = frame.Method(1, spec.Basic.Cancel(consumer_tag))
self.obj._on_cancel(frame_value)
self.assertNotIn(consumer_tag, self.obj._cancelled)
def test_on_cancel_removed_consumer(self):
consumer_tag = 'ctag0'
self.obj._consumers[consumer_tag] = logging.debug
frame_value = frame.Method(1, spec.Basic.Cancel(consumer_tag))
self.obj._on_cancel(frame_value)
self.assertNotIn(consumer_tag, self.obj._consumers)
def test_on_cancelok_removed_consumer(self):
consumer_tag = 'ctag0'
self.obj._consumers[consumer_tag] = logging.debug
frame_value = frame.Method(1, spec.Basic.CancelOk(consumer_tag))
self.obj._on_cancelok(frame_value)
self.assertNotIn(consumer_tag, self.obj._consumers)
@mock.patch('pika.spec.Channel.CloseOk')
def test_on_close_in_open_state(self, _unused):
self.obj._set_state(self.obj.OPEN)
self.obj._send_method = mock.Mock(wraps=self.obj._send_method)
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.Close(400, 'error'))
self.obj._on_close(method_frame)
self.assertTrue(self.obj.is_closed,
'Channel was not closed; state=%s' %
(self.obj._state, ))
self.obj._send_method.assert_called_once_with(spec.Channel.CloseOk())
self.obj.callbacks.process.assert_any_call(
self.obj.channel_number, '_on_channel_close', self.obj, self.obj,
method_frame.method.reply_code, method_frame.method.reply_text)
self.assertEqual(self.obj._cleanup.call_count, 1)
def test_on_close_in_closing_state(self):
self.obj._set_state(self.obj.CLOSING)
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.Close(400, 'error'))
self.obj._on_close(method_frame)
# Verify didn't alter state (will wait for CloseOk)
self.assertTrue(self.obj.is_closing,
'Channel was not closed; state=%s' %
(self.obj._state, ))
self.assertEqual(self.obj._closing_code_and_text, (400, 'error'))
self.assertFalse(self.obj.callbacks.process.called,
self.obj.callbacks.process.call_args_list)
self.assertFalse(self.obj._cleanup.called)
@mock.patch('logging.Logger.warning')
def test_on_close_warning(self, warning):
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.Close(999, 'Test_Value'))
self.obj._on_close(method_frame)
warning.assert_called_once_with(
'Received remote Channel.Close (%s): %r on %s',
method_frame.method.reply_code, method_frame.method.reply_text,
self.obj)
def _verify_on_close_meta_transitions_to_closed(self, initial_state):
self.obj._set_state(initial_state)
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
self.obj._on_close_meta(-1, 'Undefined')
self.assertTrue(self.obj.is_closed)
self.assertEqual(self.obj._cleanup.call_count, 1)
self.assertEqual(self.obj.callbacks.process.call_count, 2)
self.obj.callbacks.process.assert_any_call(
self.obj.channel_number, '_on_channel_close', self.obj, self.obj,
-1, 'Undefined')
self.obj.callbacks.process.assert_any_call(
self.obj.channel_number, self.obj._ON_CHANNEL_CLEANUP_CB_KEY,
self.obj, self.obj)
def test_on_close_meta_in_opening_state_transitions_to_closed(self):
self._verify_on_close_meta_transitions_to_closed(self.obj.OPENING)
def test_on_close_meta_in_open_state_transitions_to_closed(self):
self._verify_on_close_meta_transitions_to_closed(self.obj.OPEN)
def test_on_close_meta_in_closing_state_transitions_to_closed(self):
self._verify_on_close_meta_transitions_to_closed(self.obj.CLOSING)
def test_on_close_meta_in_closed_state_is_suppressed(self):
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
self.obj._set_state(self.obj.CLOSED)
self.obj._on_close_meta(500, 'Internal error')
self.assertTrue(self.obj.is_closed)
self.assertEqual(self.obj.callbacks.process.call_count, 0)
self.assertEqual(self.obj._cleanup.call_count, 0)
def test_on_deliver_callback_called(self):
self.obj._set_state(self.obj.OPEN)
consumer_tag = 'ctag0'
mock_callback = mock.Mock()
self.obj._consumers[consumer_tag] = mock_callback
method_value = frame.Method(1, spec.Basic.Deliver(consumer_tag, 1))
header_value = frame.Header(1, 10, spec.BasicProperties())
body_value = b'0123456789'
self.obj._on_deliver(method_value, header_value, body_value)
mock_callback.assert_called_with(self.obj, method_value.method,
header_value.properties, body_value)
def test_on_closeok(self):
self.obj._set_state(self.obj.OPEN)
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
# Close from user
self.obj.close(200, 'All is well')
self.assertEqual(self.obj._closing_code_and_text, (0, ''))
self.assertEqual(self.obj._state, self.obj.CLOSING)
self.obj._on_closeok(
frame.Method(self.obj.channel_number, spec.Channel.CloseOk()))
self.assertTrue(self.obj.is_closed,
'Channel was not closed; state=%s' %
(self.obj._state, ))
self.obj.callbacks.process.assert_any_call(self.obj.channel_number,
'_on_channel_close',
self.obj, self.obj, 0, '')
self.assertEqual(self.obj._cleanup.call_count, 1)
def test_on_closeok_following_close_from_broker(self):
self.obj._set_state(self.obj.OPEN)
self.obj._cleanup = mock.Mock(wraps=self.obj._cleanup)
# Close from user
self.obj.close(0, 'All is well')
self.assertEqual(self.obj._closing_code_and_text, (0, ''))
self.assertEqual(self.obj._state, self.obj.CLOSING)
# Close from broker before Channel.CloseOk
self.obj._on_close(
frame.Method(self.obj.channel_number,
spec.Channel.Close(400,
'broker is having a bad day')))
self.assertEqual(self.obj._closing_code_and_text,
(400, 'broker is having a bad day'))
self.assertEqual(self.obj._state, self.obj.CLOSING)
self.obj._on_closeok(
frame.Method(self.obj.channel_number, spec.Channel.CloseOk()))
# Verify this completes closing of the channel
self.assertTrue(self.obj.is_closed,
'Channel was not closed; state=%s' %
(self.obj._state, ))
self.assertEqual(self.obj.callbacks.process.call_count, 2)
self.obj.callbacks.process.assert_any_call(
self.obj.channel_number, '_on_channel_close', self.obj, self.obj,
400, 'broker is having a bad day')
self.assertEqual(self.obj._cleanup.call_count, 1)
@mock.patch('logging.Logger.debug')
def test_on_getempty(self, debug):
method_frame = frame.Method(self.obj.channel_number,
spec.Basic.GetEmpty)
self.obj._on_getempty(method_frame)
debug.assert_called_with('Received Basic.GetEmpty: %r', method_frame)
@mock.patch('logging.Logger.error')
def test_on_getok_no_callback(self, error):
method_value = frame.Method(1, spec.Basic.GetOk('ctag0', 1))
header_value = frame.Header(1, 10, spec.BasicProperties())
body_value = b'0123456789'
self.obj._on_getok(method_value, header_value, body_value)
error.assert_called_with(
'Basic.GetOk received with no active callback')
def test_on_getok_callback_called(self):
mock_callback = mock.Mock()
self.obj._on_getok_callback = mock_callback
method_value = frame.Method(1, spec.Basic.GetOk('ctag0', 1))
header_value = frame.Header(1, 10, spec.BasicProperties())
body_value = b'0123456789'
self.obj._on_getok(method_value, header_value, body_value)
mock_callback.assert_called_once_with(
self.obj, method_value.method, header_value.properties, body_value)
def test_on_getok_callback_reset(self):
mock_callback = mock.Mock()
self.obj._on_getok_callback = mock_callback
method_value = frame.Method(1, spec.Basic.GetOk('ctag0', 1))
header_value = frame.Header(1, 10, spec.BasicProperties())
body_value = b'0123456789'
self.obj._on_getok(method_value, header_value, body_value)
self.assertIsNone(self.obj._on_getok_callback)
@mock.patch('logging.Logger.debug')
def test_on_confirm_selectok(self, debug):
method_frame = frame.Method(self.obj.channel_number,
spec.Confirm.SelectOk())
self.obj._on_selectok(method_frame)
debug.assert_called_with('Confirm.SelectOk Received: %r', method_frame)
@mock.patch('logging.Logger.debug')
def test_on_eventok(self, debug):
method_frame = frame.Method(self.obj.channel_number,
spec.Basic.GetEmpty())
self.obj._on_eventok(method_frame)
debug.assert_called_with('Discarding frame %r', method_frame)
@mock.patch('logging.Logger.warning')
def test_on_flow(self, warning):
self.obj._has_on_flow_callback = False
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.Flow())
self.obj._on_flow(method_frame)
warning.assert_called_with('Channel.Flow received from server')
@mock.patch('logging.Logger.warning')
def test_on_flow_with_callback(self, warning):
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.Flow())
self.obj._on_flowok_callback = logging.debug
self.obj._on_flow(method_frame)
self.assertEqual(len(warning.call_args_list), 1)
@mock.patch('logging.Logger.warning')
def test_on_flowok(self, warning):
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.FlowOk())
self.obj._on_flowok(method_frame)
warning.assert_called_with('Channel.FlowOk received with no active '
'callbacks')
def test_on_flowok_calls_callback(self):
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.FlowOk())
mock_callback = mock.Mock()
self.obj._on_flowok_callback = mock_callback
self.obj._on_flowok(method_frame)
mock_callback.assert_called_once_with(method_frame.method.active)
def test_on_flowok_callback_reset(self):
method_frame = frame.Method(self.obj.channel_number,
spec.Channel.FlowOk())
mock_callback = mock.Mock()
self.obj._on_flowok_callback = mock_callback
self.obj._on_flowok(method_frame)
self.assertIsNone(self.obj._on_flowok_callback)
def test_on_openok_no_callback(self):
self.obj._on_openok_callback = None
method_value = frame.Method(1, spec.Channel.OpenOk())
self.obj._on_openok(method_value)
self.assertEqual(self.obj._state, self.obj.OPEN)
def test_on_openok_callback_called(self):
mock_callback = mock.Mock()
self.obj._on_openok_callback = mock_callback
method_value = frame.Method(1, spec.Channel.OpenOk())
self.obj._on_openok(method_value)
mock_callback.assert_called_once_with(self.obj)
def test_onreturn(self):
method_value = frame.Method(1,
spec.Basic.Return(999, 'Reply Text',
'exchange_value',
'routing.key'))
header_value = frame.Header(1, 10, spec.BasicProperties())
body_value = frame.Body(1, b'0123456789')
self.obj._on_return(method_value, header_value, body_value)
self.obj.callbacks.process.assert_called_with(
self.obj.channel_number, '_on_return', self.obj, self.obj,
method_value.method, header_value.properties, body_value)
@mock.patch('logging.Logger.warning')
def test_onreturn_warning(self, warning):
method_value = frame.Method(1,
spec.Basic.Return(999, 'Reply Text',
'exchange_value',
'routing.key'))
header_value = frame.Header(1, 10, spec.BasicProperties())
body_value = frame.Body(1, b'0123456789')
self.obj.callbacks.process.return_value = False
self.obj._on_return(method_value, header_value, body_value)
warning.assert_called_with(
'Basic.Return received from server (%r, %r)', method_value.method,
header_value.properties)
@mock.patch('pika.channel.Channel._rpc')
def test_on_synchronous_complete(self, rpc):
mock_callback = mock.Mock()
expectation = [
spec.Queue.Unbind(0, 'foo', 'bar', 'baz'), mock_callback,
[spec.Queue.UnbindOk]
]
self.obj._blocked = collections.deque([expectation])
self.obj._on_synchronous_complete(
frame.Method(self.obj.channel_number, spec.Basic.Ack(1)))
rpc.assert_called_once_with(*expectation)
def test_repr(self):
text = repr(self.obj)
self.assertTrue(text.startswith('<Channel'), text)
def test_rpc_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed, self.obj._rpc,
spec.Basic.Cancel('tag_abc'))
def test_rpc_while_blocking_appends_blocked_collection(self):
self.obj._set_state(self.obj.OPEN)
self.obj._blocking = spec.Confirm.Select()
acceptable_replies = [(spec.Basic.CancelOk, {
'consumer_tag': 'tag_abc'
})]
expectation = [
spec.Basic.Cancel('tag_abc'), lambda *args: None,
acceptable_replies
]
self.obj._rpc(*expectation)
self.assertIn(expectation, self.obj._blocked)
def test_rpc_throws_value_error_with_unacceptable_replies(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(TypeError, self.obj._rpc,
spec.Basic.Cancel('tag_abc'), logging.debug, 'Foo')
def test_rpc_throws_type_error_with_invalid_callback(self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(TypeError, self.obj._rpc, spec.Channel.Open(1),
['foo'], [spec.Channel.OpenOk])
def test_rpc_enters_blocking_and_adds_on_synchronous_complete(self):
self.obj._set_state(self.obj.OPEN)
method_frame = spec.Channel.Open()
self.obj._rpc(method_frame, None, [spec.Channel.OpenOk])
self.assertEqual(self.obj._blocking, method_frame.NAME)
self.obj.callbacks.add.assert_called_with(
self.obj.channel_number,
spec.Channel.OpenOk,
self.obj._on_synchronous_complete,
arguments=None)
def test_rpc_not_blocking_and_no_on_synchronous_complete_when_no_replies(
self):
self.obj._set_state(self.obj.OPEN)
method_frame = spec.Channel.Open()
self.obj._rpc(method_frame, None, acceptable_replies=[])
self.assertIsNone(self.obj._blocking)
with self.assertRaises(AssertionError):
self.obj.callbacks.add.assert_called_with(
mock.ANY,
mock.ANY,
self.obj._on_synchronous_complete,
arguments=mock.ANY)
def test_rpc_adds_callback(self):
self.obj._set_state(self.obj.OPEN)
method_frame = spec.Channel.Open()
mock_callback = mock.Mock()
self.obj._rpc(method_frame, mock_callback, [spec.Channel.OpenOk])
self.obj.callbacks.add.assert_called_with(
self.obj.channel_number,
spec.Channel.OpenOk,
mock_callback,
arguments=None)
def test_send_method(self):
expectation = [2, 3]
with mock.patch.object(self.obj.connection,
'_send_method') as send_method:
self.obj._send_method(*expectation)
send_method.assert_called_once_with(
*[self.obj.channel_number] + expectation)
def test_set_state(self):
self.obj._state = channel.Channel.CLOSED
self.obj._set_state(channel.Channel.OPENING)
self.assertEqual(self.obj._state, channel.Channel.OPENING)
def test_validate_channel_and_callback_raises_channel_closed(self):
self.assertRaises(exceptions.ChannelClosed,
self.obj._validate_channel_and_callback, None)
def test_validate_channel_and_callback_raises_value_error_not_callable(
self):
self.obj._set_state(self.obj.OPEN)
self.assertRaises(ValueError, self.obj._validate_channel_and_callback,
'foo')