class RabbitMQCnxFixture(AbstractTestFixture): """ Mock a message over RabbitMQ """ def _get_producer(self): producer = producers[self._mock_rabbit_connection].acquire(block=True, timeout=2) self._connections.add(producer.connection) return producer def setup(self): #Note: not a setup_class method, not to conflict with AbstractTestFixture's setup self._mock_rabbit_connection = BrokerConnection("pyamqp://*****:*****@localhost:5672") self._connections = {self._mock_rabbit_connection} self._exchange = Exchange('navitia', durable=True, delivry_mode=2, type='topic') self._mock_rabbit_connection.connect() #wait for the cnx to run the test self._wait_for_rabbitmq_cnx() def teardown(self): #we need to release the amqp connection self._mock_rabbit_connection.release() def _publish(self, item): with self._get_producer() as producer: producer.publish(item, exchange=self._exchange, routing_key=rt_topic, declare=[self._exchange]) def _make_mock_item(self, *args, **kwargs): """ method to overload to create a mock object to send over rabbitmq """ raise NotImplementedError() def send_mock(self, *args, **kwargs): status = self.query_region('status') last_loaded_data = get_not_null(status['status'], 'last_rt_data_loaded') item = self._make_mock_item(*args, **kwargs) self._publish(item) #we sleep a bit to let kraken reload the data self._poll_until_reload(last_loaded_data) def _poll_until_reload(self, previous_val): """ poll until the kraken have reloaded its data check that the last_rt_data_loaded field is different from the first call """ Retrying(stop_max_delay=10 * 1000, wait_fixed=100, retry_on_result=lambda status: get_not_null(status['status'], 'last_rt_data_loaded') == previous_val) \ .call(lambda: self.query_region('status')) def _wait_for_rabbitmq_cnx(self): """ poll until the kraken is connected to rabbitmq small timeout because it must not be long (otherwise it way be a server configuration problem) """ Retrying(stop_max_delay=1 * 1000, wait_fixed=50, retry_on_result=lambda status: get_not_null(status['status'], 'is_connected_to_rabbitmq') is False) \ .call(lambda: self.query_region('status'))
def get_connection(self, vhost): if vhost in self.connections: connection = self.connections[vhost] else: connection = BrokerConnection(settings.AMQP_URL + vhost) if not connection.connected: connection.connect() return connection
def test__enter____exit__(self): conn = BrokerConnection(backend_cls=Backend) context = conn.__enter__() self.assertIs(context, conn) conn.connect() self.assertTrue(conn.connection.connected) conn.__exit__() self.assertIsNone(conn.connection) conn.close() # again
def test__enter____exit__(self): conn = BrokerConnection(transport=Transport) context = conn.__enter__() self.assertIs(context, conn) conn.connect() self.assertTrue(conn.connection.connected) conn.__exit__() self.assertIsNone(conn.connection) conn.close() # again
def test_establish_connection(self): conn = BrokerConnection(port=5672, backend_cls=Backend) conn.connect() self.assertTrue(conn.connection.connected) self.assertEqual(conn.host, "localhost:5672") channel = conn.channel() self.assertTrue(channel.open) self.assertEqual(conn.drain_events(), "event") _connection = conn.connection conn.close() self.assertFalse(_connection.connected) self.assertIsInstance(conn.backend, Backend)
def test_close_survives_connerror(self): class _CustomError(Exception): pass class MyTransport(Transport): connection_errors = (_CustomError, ) def close_connection(self, connection): raise _CustomError("foo") conn = BrokerConnection(transport=MyTransport) conn.connect() conn.close() self.assertTrue(conn._closed)
class Sender(): """ Simple class to wrap the operations needed for an AMQP listener """ def __init__(self, hostname="127.0.0.1", userid="guest", password="******", virtual_host="/", port=5672, name="", routing_key=""): """ Setup a connection to the AMQP server, get a channel and create an exchange. A specific service listener implementation overrides the name and routing_key """ if name == "": raise Exception("Name must be non-empty string") self.name = name self.routing_key = routing_key if routing_key == "": exchange_type = "fanout" elif "*" in routing_key or "#" in routing_key: exchange_type = "topic" else : exchange_type = "direct" self.connection = BrokerConnection(hostname=hostname, userid=userid, password=password, virtual_host=virtual_host, port=443, insist=False, ssl=False) self.channel = self.connection.channel() self.exchange = Exchange(name=self.name, type=exchange_type, durable=False, channel=self.channel) self.connection.connect() return def send(self, msg): """ Publishes a message to the AMQP server on the initialized exchange msg is a string, usually a JSON dump """ self.exchange.publish(self.exchange.Message(msg), routing_key=self.routing_key) return
class Listener(): """ Simple class to wrap the operations needed for an AMQP listener """ def __init__(self, hostname="127.0.0.1", userid="guest", password="******", virtual_host="/", port=5672): """ Setup a connection to the AMQP server, get a channel Create a topic exchange, attach a bonded queue to it and register a consumer callback. A specific service listener implementation overrides the name and routing_key """ self.connection = BrokerConnection(hostname=hostname, userid=userid, password=password, virtual_host=virtual_host, port=port, insist=False, ssl=False) self.channel = self.connection.channel() self.exchange = Exchange(name=self.name, type="topic", durable=True, channel=self.channel) self.queue = Queue(self.name, exchange=self.exchange, routing_key=self.routing_key) self.queue = self.queue(self.channel) self.queue.declare() self.queue.consume(consumer_tag="", callback=self.callback, no_ack=True) self.connection.connect() return def callback(self, msg): """ This callback is run when a message is recieved """ return def consume(self): """ Event loop """ while True: self.connection.drain_events() return
class ChaosDisruptionsFixture(AbstractTestFixture): """ Mock a chaos disruption message, in order to check the api """ def _get_producer(self): producer = producers[self.mock_chaos_connection].acquire(block=True, timeout=2) self._connections.add(producer.connection) return producer def setup(self): self.mock_chaos_connection = BrokerConnection( "pyamqp://*****:*****@localhost:5672") self._connections = {self.mock_chaos_connection} self._exchange = Exchange('navitia', durable=True, delivry_mode=2, type='topic') self.mock_chaos_connection.connect() def teardown(self): #we need to release the amqp connection self.mock_chaos_connection.release() def send_chaos_disruption(self, disruption_name, impacted_obj, impacted_obj_type, start=None, end=None, message='default_message', is_deleted=False, blocking=False, start_period="20100412T165200", end_period="20200412T165200"): item = make_mock_chaos_item(disruption_name, impacted_obj, impacted_obj_type, start, end, message, is_deleted, blocking, start_period, end_period) with self._get_producer() as producer: producer.publish(item, exchange=self._exchange, routing_key=chaos_rt_topic, declare=[self._exchange]) def send_chaos_disruption_and_sleep(self, disruption_name, impacted_obj, impacted_obj_type, start=None, end=None, message='default_message', is_deleted=False, blocking=False, start_period="20100412T165200", end_period="20200412T165200"): status = self.query_region('status') last_loaded_data = get_not_null(status['status'], 'last_rt_data_loaded') self.send_chaos_disruption(disruption_name, impacted_obj, impacted_obj_type, start, end, message, is_deleted, blocking, start_period, end_period) #we sleep a bit to let kraken reload the data self.poll_until_reload(last_loaded_data) def poll_until_reload(self, previous_val): """ poll until the kraken have reloaded its data check that the last_rt_data_loaded field is different from the first call """ Retrying(stop_max_delay=10 * 1000, wait_fixed=100, retry_on_result=lambda status: get_not_null(status['status'], 'last_rt_data_loaded') == previous_val) \ .call(lambda: self.query_region('status')) def wait_for_rabbitmq_cnx(self): """ poll until the kraken is connected to rabbitmq small timeout because it must not be long (otherwise it way be a server configuration problem) """ Retrying(stop_max_delay=1 * 1000, wait_fixed=50, retry_on_result=lambda status: get_not_null(status['status'], 'is_connected_to_rabbitmq') is False) \ .call(lambda: self.query_region('status'))
def test_can_connect(): b = BrokerConnection('localhost', 'guest', 'guest', '/') b.connect() assert True
class test_Consumer(TestCase): def setUp(self): self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.exchange = Exchange("foo", "direct") def test_set_no_ack(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True, no_ack=True) self.assertTrue(consumer.no_ack) def test_add_queue_when_auto_declare(self): consumer = self.connection.Consumer(auto_declare=True) q = Mock() q.return_value = q consumer.add_queue(q) self.assertIn(q, consumer.queues) q.declare.assert_called_with() def test_add_queue_when_not_auto_declare(self): consumer = self.connection.Consumer(auto_declare=False) q = Mock() q.return_value = q consumer.add_queue(q) self.assertIn(q, consumer.queues) self.assertFalse(q.declare.call_count) def test_consume_without_queues_returns(self): consumer = self.connection.Consumer() consumer.queues[:] = [] self.assertIsNone(consumer.consume()) def test_consuming_from(self): consumer = self.connection.Consumer() consumer.queues[:] = [Queue("a"), Queue("b")] self.assertFalse(consumer.consuming_from(Queue("c"))) self.assertFalse(consumer.consuming_from("c")) self.assertTrue(consumer.consuming_from(Queue("a"))) self.assertTrue(consumer.consuming_from(Queue("b"))) self.assertTrue(consumer.consuming_from("b")) def test_receive_callback_without_m2p(self): channel = self.connection.channel() c = channel.Consumer() m2p = getattr(channel, "message_to_python") channel.message_to_python = None try: message = Mock() message.decode.return_value = "Hello" recv = c.receive = Mock() c._receive_callback(message) recv.assert_called_with("Hello", message) finally: channel.message_to_python = m2p def test_set_callbacks(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") callbacks = [lambda x, y: x, lambda x, y: x] consumer = Consumer(channel, queue, auto_declare=True, callbacks=callbacks) self.assertEqual(consumer.callbacks, callbacks) def test_auto_declare(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.consume() consumer.consume() # twice is a noop self.assertIsNot(consumer.queues[0], queue) self.assertTrue(consumer.queues[0].is_bound) self.assertTrue(consumer.queues[0].exchange.is_bound) self.assertIsNot(consumer.queues[0].exchange, self.exchange) for meth in ("exchange_declare", "queue_declare", "queue_bind", "basic_consume"): self.assertIn(meth, channel) self.assertEqual(channel.called.count("basic_consume"), 1) self.assertTrue(consumer._active_tags) consumer.cancel_by_queue(queue.name) consumer.cancel_by_queue(queue.name) self.assertFalse(consumer._active_tags) def test_manual_declare(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=False) self.assertIsNot(consumer.queues[0], queue) self.assertTrue(consumer.queues[0].is_bound) self.assertTrue(consumer.queues[0].exchange.is_bound) self.assertIsNot(consumer.queues[0].exchange, self.exchange) for meth in ("exchange_declare", "queue_declare", "basic_consume"): self.assertNotIn(meth, channel) consumer.declare() for meth in ("exchange_declare", "queue_declare", "queue_bind"): self.assertIn(meth, channel) self.assertNotIn("basic_consume", channel) consumer.consume() self.assertIn("basic_consume", channel) def test_consume__cancel(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.consume() consumer.cancel() self.assertIn("basic_cancel", channel) self.assertFalse(consumer._active_tags) def test___enter____exit__(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) context = consumer.__enter__() self.assertIs(context, consumer) self.assertTrue(consumer._active_tags) res = consumer.__exit__(None, None, None) self.assertFalse(res) self.assertIn("basic_cancel", channel) self.assertFalse(consumer._active_tags) def test_flow(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.flow(False) self.assertIn("flow", channel) def test_qos(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.qos(30, 10, False) self.assertIn("basic_qos", channel) def test_purge(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") b2 = Queue("qname2", self.exchange, "rkey") b3 = Queue("qname3", self.exchange, "rkey") b4 = Queue("qname4", self.exchange, "rkey") consumer = Consumer(channel, [b1, b2, b3, b4], auto_declare=True) consumer.purge() self.assertEqual(channel.called.count("queue_purge"), 4) def test_multiple_queues(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") b2 = Queue("qname2", self.exchange, "rkey") b3 = Queue("qname3", self.exchange, "rkey") b4 = Queue("qname4", self.exchange, "rkey") consumer = Consumer(channel, [b1, b2, b3, b4]) consumer.consume() self.assertEqual(channel.called.count("exchange_declare"), 4) self.assertEqual(channel.called.count("queue_declare"), 4) self.assertEqual(channel.called.count("queue_bind"), 4) self.assertEqual(channel.called.count("basic_consume"), 4) self.assertEqual(len(consumer._active_tags), 4) consumer.cancel() self.assertEqual(channel.called.count("basic_cancel"), 4) self.assertFalse(len(consumer._active_tags)) def test_receive_callback(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) received = [] def callback(message_data, message): received.append(message_data) message.ack() message.payload # trigger cache consumer.register_callback(callback) consumer._receive_callback({u"foo": u"bar"}) self.assertIn("basic_ack", channel) self.assertIn("message_to_python", channel) self.assertEqual(received[0], {u"foo": u"bar"}) def test_basic_ack_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.ack() message.ack() consumer.register_callback(callback) with self.assertRaises(MessageStateError): consumer._receive_callback({"foo": "bar"}) def test_basic_reject(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.reject() consumer.register_callback(callback) consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject", channel) def test_basic_reject_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.reject() message.reject() consumer.register_callback(callback) with self.assertRaises(MessageStateError): consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject", channel) def test_basic_reject__requeue(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.requeue() consumer.register_callback(callback) consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject:requeue", channel) def test_basic_reject__requeue_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.requeue() message.requeue() consumer.register_callback(callback) with self.assertRaises(MessageStateError): consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject:requeue", channel) def test_receive_without_callbacks_raises(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) with self.assertRaises(NotImplementedError): consumer.receive(1, 2) def test_decode_error(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) consumer.channel.throw_decode_error = True with self.assertRaises(ValueError): consumer._receive_callback({"foo": "bar"}) def test_on_decode_error_callback(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") thrown = [] def on_decode_error(msg, exc): thrown.append((msg.body, exc)) consumer = Consumer(channel, [b1], on_decode_error=on_decode_error) consumer.channel.throw_decode_error = True consumer._receive_callback({"foo": "bar"}) self.assertTrue(thrown) m, exc = thrown[0] self.assertEqual(anyjson.loads(m), {"foo": "bar"}) self.assertIsInstance(exc, ValueError) def test_recover(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) consumer.recover() self.assertIn("basic_recover", channel) def test_revive(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) channel2 = self.connection.channel() consumer.revive(channel2) self.assertIs(consumer.channel, channel2) self.assertIs(consumer.queues[0].channel, channel2) self.assertIs(consumer.queues[0].exchange.channel, channel2) def test__repr__(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") self.assertTrue(repr(Consumer(channel, [b1]))) def test_connection_property_handles_AttributeError(self): p = self.connection.Consumer() p.channel = object() self.assertIsNone(p.connection)
class test_Producer(TestCase): def setUp(self): self.exchange = Exchange("foo", "direct") self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.assertFalse(self.exchange.is_bound) @patch("kombu.common.maybe_declare") def test_maybe_declare(self, maybe_declare): p = self.connection.Producer() q = Queue("foo") p.maybe_declare(q) maybe_declare.assert_called_with(q, p.channel, False) @patch("kombu.common.maybe_declare") def test_maybe_declare_when_entity_false(self, maybe_declare): p = self.connection.Producer() p.maybe_declare(None) self.assertFalse(maybe_declare.called) def test_auto_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=True) self.assertIsNot(p.exchange, self.exchange, "creates Exchange clone at bind") self.assertTrue(p.exchange.is_bound) self.assertIn("exchange_declare", channel, "auto_declare declares exchange") def test_manual_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=False) self.assertTrue(p.exchange.is_bound) self.assertNotIn("exchange_declare", channel, "auto_declare=False does not declare exchange") p.declare() self.assertIn("exchange_declare", channel, "p.declare() declares exchange") def test_prepare(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, headers={}) self.assertDictEqual(message, anyjson.loads(m)) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") def test_prepare_compression(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") headers = {} m, ctype, cencoding = p._prepare(message, compression="zlib", headers=headers) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") self.assertEqual(headers["compression"], "application/x-gzip") import zlib self.assertEqual(anyjson.loads(zlib.decompress(m).decode("utf-8")), message) def test_prepare_custom_content_type(self): message = "the quick brown fox".encode("utf-8") channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="custom") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "binary") m, ctype, cencoding = p._prepare(message, content_type="custom", content_encoding="alien") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "alien") def test_prepare_is_already_unicode(self): message = u"the quick brown fox" channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="text/plain") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") m, ctype, cencoding = p._prepare(message, content_type="text/plain", content_encoding="utf-8") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") def test_publish_with_Exchange_instance(self): p = self.connection.Producer() p.exchange.publish = Mock() p.publish("hello", exchange=Exchange("foo")) self.assertEqual(p.exchange.publish.call_args[0][4], "foo") def test_publish_retry_with_declare(self): p = self.connection.Producer() p.maybe_declare = Mock() ensure = p.connection.ensure = Mock() ex = Exchange("foo") p.publish("hello", exchange=ex, declare=[ex], retry=True, retry_policy={"step": 4}) p.maybe_declare.assert_called_with(ex, True, step=4) ensure.assert_called_with(p, p.exchange.publish, step=4) def test_revive_when_channel_is_connection(self): p = self.connection.Producer() p.exchange = Mock() new_conn = BrokerConnection("memory://") defchan = new_conn.default_channel p.revive(new_conn) self.assertIs(p.channel, defchan) p.exchange.revive.assert_called_with(defchan) def test_enter_exit(self): p = self.connection.Producer() p.release = Mock() self.assertIs(p.__enter__(), p) p.__exit__() p.release.assert_called_with() def test_connection_property_handles_AttributeError(self): p = self.connection.Producer() p.channel = object() self.assertIsNone(p.connection) def test_publish(self): channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") message = {u"the quick brown fox": u"jumps over the lazy dog"} ret = p.publish(message, routing_key="process") self.assertIn("prepare_message", channel) self.assertIn("basic_publish", channel) m, exc, rkey = ret self.assertDictEqual(message, anyjson.loads(m["body"])) self.assertDictContainsSubset( { "content_type": "application/json", "content_encoding": "utf-8", "priority": 0 }, m) self.assertDictContainsSubset({"delivery_mode": 2}, m["properties"]) self.assertEqual(exc, p.exchange.name) self.assertEqual(rkey, "process") def test_no_exchange(self): chan = self.connection.channel() p = Producer(chan) self.assertFalse(p.exchange.name) def test_revive(self): chan = self.connection.channel() p = Producer(chan) chan2 = self.connection.channel() p.revive(chan2) self.assertIs(p.channel, chan2) self.assertIs(p.exchange.channel, chan2) def test_on_return(self): chan = self.connection.channel() def on_return(exception, exchange, routing_key, message): pass p = Producer(chan, on_return=on_return) self.assertTrue(on_return in chan.events["basic_return"]) self.assertTrue(p.on_return)
class test_Producer(TestCase): def setUp(self): self.exchange = Exchange("foo", "direct") self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.assertFalse(self.exchange.is_bound) @patch("kombu.common.maybe_declare") def test_maybe_declare(self, maybe_declare): p = self.connection.Producer() q = Queue("foo") p.maybe_declare(q) maybe_declare.assert_called_with(q, p.channel, False) @patch("kombu.common.maybe_declare") def test_maybe_declare_when_entity_false(self, maybe_declare): p = self.connection.Producer() p.maybe_declare(None) self.assertFalse(maybe_declare.called) def test_auto_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=True) self.assertIsNot(p.exchange, self.exchange, "creates Exchange clone at bind") self.assertTrue(p.exchange.is_bound) self.assertIn("exchange_declare", channel, "auto_declare declares exchange") def test_manual_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=False) self.assertTrue(p.exchange.is_bound) self.assertNotIn("exchange_declare", channel, "auto_declare=False does not declare exchange") p.declare() self.assertIn("exchange_declare", channel, "p.declare() declares exchange") def test_prepare(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, headers={}) self.assertDictEqual(message, anyjson.loads(m)) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") def test_prepare_compression(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") headers = {} m, ctype, cencoding = p._prepare(message, compression="zlib", headers=headers) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") self.assertEqual(headers["compression"], "application/x-gzip") import zlib self.assertEqual(anyjson.loads( zlib.decompress(m).decode("utf-8")), message) def test_prepare_custom_content_type(self): message = "the quick brown fox".encode("utf-8") channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="custom") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "binary") m, ctype, cencoding = p._prepare(message, content_type="custom", content_encoding="alien") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "alien") def test_prepare_is_already_unicode(self): message = u"the quick brown fox" channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="text/plain") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") m, ctype, cencoding = p._prepare(message, content_type="text/plain", content_encoding="utf-8") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") def test_publish_with_Exchange_instance(self): p = self.connection.Producer() p.exchange.publish = Mock() p.publish("hello", exchange=Exchange("foo")) self.assertEqual(p.exchange.publish.call_args[0][4], "foo") def test_publish_retry_with_declare(self): p = self.connection.Producer() p.maybe_declare = Mock() ensure = p.connection.ensure = Mock() ex = Exchange("foo") p.publish("hello", exchange=ex, declare=[ex], retry=True, retry_policy={"step": 4}) p.maybe_declare.assert_called_with(ex, True, step=4) ensure.assert_called_with(p, p.exchange.publish, step=4) def test_revive_when_channel_is_connection(self): p = self.connection.Producer() p.exchange = Mock() new_conn = BrokerConnection("memory://") defchan = new_conn.default_channel p.revive(new_conn) self.assertIs(p.channel, defchan) p.exchange.revive.assert_called_with(defchan) def test_enter_exit(self): p = self.connection.Producer() p.release = Mock() self.assertIs(p.__enter__(), p) p.__exit__() p.release.assert_called_with() def test_connection_property_handles_AttributeError(self): p = self.connection.Producer() p.channel = object() self.assertIsNone(p.connection) def test_publish(self): channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") message = {u"the quick brown fox": u"jumps over the lazy dog"} ret = p.publish(message, routing_key="process") self.assertIn("prepare_message", channel) self.assertIn("basic_publish", channel) m, exc, rkey = ret self.assertDictEqual(message, anyjson.loads(m["body"])) self.assertDictContainsSubset({"content_type": "application/json", "content_encoding": "utf-8", "priority": 0}, m) self.assertDictContainsSubset({"delivery_mode": 2}, m["properties"]) self.assertEqual(exc, p.exchange.name) self.assertEqual(rkey, "process") def test_no_exchange(self): chan = self.connection.channel() p = Producer(chan) self.assertFalse(p.exchange.name) def test_revive(self): chan = self.connection.channel() p = Producer(chan) chan2 = self.connection.channel() p.revive(chan2) self.assertIs(p.channel, chan2) self.assertIs(p.exchange.channel, chan2) def test_on_return(self): chan = self.connection.channel() def on_return(exception, exchange, routing_key, message): pass p = Producer(chan, on_return=on_return) self.assertTrue(on_return in chan.events["basic_return"]) self.assertTrue(p.on_return)
class test_Producer(unittest.TestCase): def setUp(self): self.exchange = Exchange("foo", "direct") self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.assertFalse(self.exchange.is_bound) def test_auto_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=True) self.assertIsNot(p.exchange, self.exchange, "creates Exchange clone at bind") self.assertTrue(p.exchange.is_bound) self.assertIn("exchange_declare", channel, "auto_declare declares exchange") def test_manual_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=False) self.assertTrue(p.exchange.is_bound) self.assertNotIn("exchange_declare", channel, "auto_declare=False does not declare exchange") p.declare() self.assertIn("exchange_declare", channel, "p.declare() declares exchange") def test_prepare(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, headers={}) self.assertDictEqual(message, anyjson.deserialize(m)) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") def test_prepare_compression(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") headers = {} m, ctype, cencoding = p._prepare(message, compression="zlib", headers=headers) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") self.assertEqual(headers["compression"], "application/x-gzip") import zlib self.assertEqual( anyjson.deserialize(zlib.decompress(m).decode("utf-8")), message) def test_prepare_custom_content_type(self): message = "the quick brown fox".encode("utf-8") channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="custom") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "binary") m, ctype, cencoding = p._prepare(message, content_type="custom", content_encoding="alien") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "alien") def test_prepare_is_already_unicode(self): message = u"the quick brown fox" channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="text/plain") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") m, ctype, cencoding = p._prepare(message, content_type="text/plain", content_encoding="utf-8") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") def test_publish(self): channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") message = {u"the quick brown fox": u"jumps over the lazy dog"} ret = p.publish(message, routing_key="process") self.assertIn("prepare_message", channel) self.assertIn("basic_publish", channel) m, exc, rkey = ret self.assertDictEqual(message, anyjson.deserialize(m["body"])) self.assertDictContainsSubset( { "content_type": "application/json", "content_encoding": "utf-8", "priority": 0 }, m) self.assertDictContainsSubset({"delivery_mode": 2}, m["properties"]) self.assertEqual(exc, p.exchange.name) self.assertEqual(rkey, "process") def test_no_exchange(self): chan = self.connection.channel() p = Producer(chan) self.assertFalse(p.exchange.name) def test_revive(self): chan = self.connection.channel() p = Producer(chan) chan2 = self.connection.channel() p.revive(chan2) self.assertIs(p.channel, chan2) self.assertIs(p.exchange.channel, chan2) def test_on_return(self): chan = self.connection.channel() def on_return(exception, exchange, routing_key, message): pass p = Producer(chan, on_return=on_return) self.assertTrue(on_return in chan.events["basic_return"]) self.assertTrue(p.on_return)
class test_Consumer(unittest.TestCase): def setUp(self): self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.exchange = Exchange("foo", "direct") def test_set_no_ack(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True, no_ack=True) self.assertTrue(consumer.no_ack) def test_set_callbacks(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") callbacks = [lambda x, y: x, lambda x, y: x] consumer = Consumer(channel, queue, auto_declare=True, callbacks=callbacks) self.assertEqual(consumer.callbacks, callbacks) def test_auto_declare(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.consume() consumer.consume() # twice is a noop self.assertIsNot(consumer.queues[0], queue) self.assertTrue(consumer.queues[0].is_bound) self.assertTrue(consumer.queues[0].exchange.is_bound) self.assertIsNot(consumer.queues[0].exchange, self.exchange) for meth in ("exchange_declare", "queue_declare", "queue_bind", "basic_consume"): self.assertIn(meth, channel) self.assertEqual(channel.called.count("basic_consume"), 1) self.assertTrue(consumer._active_tags) consumer.cancel_by_queue(queue.name) consumer.cancel_by_queue(queue.name) self.assertFalse(consumer._active_tags) def test_manual_declare(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=False) self.assertIsNot(consumer.queues[0], queue) self.assertTrue(consumer.queues[0].is_bound) self.assertTrue(consumer.queues[0].exchange.is_bound) self.assertIsNot(consumer.queues[0].exchange, self.exchange) for meth in ("exchange_declare", "queue_declare", "basic_consume"): self.assertNotIn(meth, channel) consumer.declare() for meth in ("exchange_declare", "queue_declare", "queue_bind"): self.assertIn(meth, channel) self.assertNotIn("basic_consume", channel) consumer.consume() self.assertIn("basic_consume", channel) def test_consume__cancel(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.consume() consumer.cancel() self.assertIn("basic_cancel", channel) self.assertFalse(consumer._active_tags) def test___enter____exit__(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) context = consumer.__enter__() self.assertIs(context, consumer) self.assertTrue(consumer._active_tags) res = consumer.__exit__(None, None, None) self.assertFalse(res) self.assertIn("basic_cancel", channel) self.assertFalse(consumer._active_tags) def test_flow(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.flow(False) self.assertIn("flow", channel) def test_qos(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.qos(30, 10, False) self.assertIn("basic_qos", channel) def test_purge(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") b2 = Queue("qname2", self.exchange, "rkey") b3 = Queue("qname3", self.exchange, "rkey") b4 = Queue("qname4", self.exchange, "rkey") consumer = Consumer(channel, [b1, b2, b3, b4], auto_declare=True) consumer.purge() self.assertEqual(channel.called.count("queue_purge"), 4) def test_multiple_queues(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") b2 = Queue("qname2", self.exchange, "rkey") b3 = Queue("qname3", self.exchange, "rkey") b4 = Queue("qname4", self.exchange, "rkey") consumer = Consumer(channel, [b1, b2, b3, b4]) consumer.consume() self.assertEqual(channel.called.count("exchange_declare"), 4) self.assertEqual(channel.called.count("queue_declare"), 4) self.assertEqual(channel.called.count("queue_bind"), 4) self.assertEqual(channel.called.count("basic_consume"), 4) self.assertEqual(len(consumer._active_tags), 4) consumer.cancel() self.assertEqual(channel.called.count("basic_cancel"), 4) self.assertFalse(len(consumer._active_tags)) def test_receive_callback(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) received = [] def callback(message_data, message): received.append(message_data) message.ack() message.payload # trigger cache consumer.register_callback(callback) consumer._receive_callback({u"foo": u"bar"}) self.assertIn("basic_ack", channel) self.assertIn("message_to_python", channel) self.assertEqual(received[0], {u"foo": u"bar"}) def test_basic_ack_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.ack() message.ack() consumer.register_callback(callback) self.assertRaises(MessageStateError, consumer._receive_callback, {"foo": "bar"}) def test_basic_reject(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.reject() consumer.register_callback(callback) consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject", channel) def test_basic_reject_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.reject() message.reject() consumer.register_callback(callback) self.assertRaises(MessageStateError, consumer._receive_callback, {"foo": "bar"}) self.assertIn("basic_reject", channel) def test_basic_reject__requeue(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.requeue() consumer.register_callback(callback) consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject:requeue", channel) def test_basic_reject__requeue_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.requeue() message.requeue() consumer.register_callback(callback) self.assertRaises(MessageStateError, consumer._receive_callback, {"foo": "bar"}) self.assertIn("basic_reject:requeue", channel) def test_receive_without_callbacks_raises(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) self.assertRaises(NotImplementedError, consumer.receive, 1, 2) def test_decode_error(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) consumer.channel.throw_decode_error = True self.assertRaises(ValueError, consumer._receive_callback, {"foo": "bar"}) def test_on_decode_error_callback(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") thrown = [] def on_decode_error(msg, exc): thrown.append((msg.body, exc)) consumer = Consumer(channel, [b1], on_decode_error=on_decode_error) consumer.channel.throw_decode_error = True consumer._receive_callback({"foo": "bar"}) self.assertTrue(thrown) m, exc = thrown[0] self.assertEqual(anyjson.deserialize(m), {"foo": "bar"}) self.assertIsInstance(exc, ValueError) def test_recover(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) consumer.recover() self.assertIn("basic_recover", channel) def test_revive(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) channel2 = self.connection.channel() consumer.revive(channel2) self.assertIs(consumer.channel, channel2) self.assertIs(consumer.queues[0].channel, channel2) self.assertIs(consumer.queues[0].exchange.channel, channel2) def test__repr__(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") self.assertTrue(repr(Consumer(channel, [b1])))
class test_Producer(unittest.TestCase): def setUp(self): self.exchange = Exchange("foo", "direct") self.connection = BrokerConnection(backend_cls=Backend) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.assertFalse(self.exchange.is_bound) def test_auto_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=True) self.assertIsNot(p.exchange, self.exchange, "creates Exchange clone at bind") self.assertTrue(p.exchange.is_bound) self.assertIn("exchange_declare", channel, "auto_declare declares exchange") def test_manual_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=False) self.assertTrue(p.exchange.is_bound) self.assertNotIn("exchange_declare", channel, "auto_declare=False does not declare exchange") p.declare() self.assertIn("exchange_declare", channel, "p.declare() declares exchange") def test_prepare(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p.prepare(message) self.assertDictEqual(message, simplejson.loads(m)) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") def test_prepare_custom_content_type(self): message = "the quick brown fox" channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p.prepare(message, content_type="custom") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "binary") m, ctype, cencoding = p.prepare(message, content_type="custom", content_encoding="alien") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "alien") def test_prepare_is_already_unicode(self): message = u"the quick brown fox" channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p.prepare(message, content_type="text/plain") self.assertEqual(m, message) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") m, ctype, cencoding = p.prepare(message, content_type="text/plain", content_encoding="utf-8") self.assertEqual(m, message) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") def test_publish(self): channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") message = {u"the quick brown fox": u"jumps over the lazy dog"} ret = p.publish(message, routing_key="process") self.assertIn("prepare_message", channel) self.assertIn("basic_publish", channel) m, exc, rkey = ret self.assertDictEqual(message, simplejson.loads(m["body"])) self.assertDictContainsSubset({"content_type": "application/json", "content_encoding": "utf-8", "priority": 0}, m) self.assertDictContainsSubset({"delivery_mode": 2}, m["properties"]) self.assertEqual(exc, p.exchange.name) self.assertEqual(rkey, "process") def test_no_exchange(self): chan = self.connection.channel() p = Producer(chan) self.assertIsNone(p.exchange)
class test_Producer(unittest.TestCase): def setUp(self): self.exchange = Exchange("foo", "direct") self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.assertFalse(self.exchange.is_bound) def test_auto_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=True) self.assertIsNot(p.exchange, self.exchange, "creates Exchange clone at bind") self.assertTrue(p.exchange.is_bound) self.assertIn("exchange_declare", channel, "auto_declare declares exchange") def test_manual_declare(self): channel = self.connection.channel() p = Producer(channel, self.exchange, auto_declare=False) self.assertTrue(p.exchange.is_bound) self.assertNotIn("exchange_declare", channel, "auto_declare=False does not declare exchange") p.declare() self.assertIn("exchange_declare", channel, "p.declare() declares exchange") def test_prepare(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, headers={}) self.assertDictEqual(message, anyjson.deserialize(m)) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") def test_prepare_compression(self): message = {u"the quick brown fox": u"jumps over the lazy dog"} channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") headers = {} m, ctype, cencoding = p._prepare(message, compression="zlib", headers=headers) self.assertEqual(ctype, "application/json") self.assertEqual(cencoding, "utf-8") self.assertEqual(headers["compression"], "application/x-gzip") import zlib self.assertEqual(anyjson.deserialize( zlib.decompress(m).decode("utf-8")), message) def test_prepare_custom_content_type(self): message = "the quick brown fox".encode("utf-8") channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="custom") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "binary") m, ctype, cencoding = p._prepare(message, content_type="custom", content_encoding="alien") self.assertEqual(m, message) self.assertEqual(ctype, "custom") self.assertEqual(cencoding, "alien") def test_prepare_is_already_unicode(self): message = u"the quick brown fox" channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") m, ctype, cencoding = p._prepare(message, content_type="text/plain") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") m, ctype, cencoding = p._prepare(message, content_type="text/plain", content_encoding="utf-8") self.assertEqual(m, message.encode("utf-8")) self.assertEqual(ctype, "text/plain") self.assertEqual(cencoding, "utf-8") def test_publish(self): channel = self.connection.channel() p = Producer(channel, self.exchange, serializer="json") message = {u"the quick brown fox": u"jumps over the lazy dog"} ret = p.publish(message, routing_key="process") self.assertIn("prepare_message", channel) self.assertIn("basic_publish", channel) m, exc, rkey = ret self.assertDictEqual(message, anyjson.deserialize(m["body"])) self.assertDictContainsSubset({"content_type": "application/json", "content_encoding": "utf-8", "priority": 0}, m) self.assertDictContainsSubset({"delivery_mode": 2}, m["properties"]) self.assertEqual(exc, p.exchange.name) self.assertEqual(rkey, "process") def test_no_exchange(self): chan = self.connection.channel() p = Producer(chan) self.assertFalse(p.exchange.name) def test_revive(self): chan = self.connection.channel() p = Producer(chan) chan2 = self.connection.channel() p.revive(chan2) self.assertIs(p.channel, chan2) self.assertIs(p.exchange.channel, chan2) def test_on_return(self): chan = self.connection.channel() def on_return(exception, exchange, routing_key, message): pass p = Producer(chan, on_return=on_return) self.assertTrue(on_return in chan.events["basic_return"]) self.assertTrue(p.on_return)
class test_Consumer(unittest.TestCase): def setUp(self): self.connection = BrokerConnection(transport=Transport) self.connection.connect() self.assertTrue(self.connection.connection.connected) self.exchange = Exchange("foo", "direct") def test_set_no_ack(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True, no_ack=True) self.assertTrue(consumer.no_ack) def test_set_callbacks(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") callbacks = [lambda x, y: x, lambda x, y: x] consumer = Consumer(channel, queue, auto_declare=True, callbacks=callbacks) self.assertEqual(consumer.callbacks, callbacks) def test_auto_declare(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.consume() consumer.consume() # twice is a noop self.assertIsNot(consumer.queues[0], queue) self.assertTrue(consumer.queues[0].is_bound) self.assertTrue(consumer.queues[0].exchange.is_bound) self.assertIsNot(consumer.queues[0].exchange, self.exchange) for meth in ("exchange_declare", "queue_declare", "queue_bind", "basic_consume"): self.assertIn(meth, channel) self.assertEqual(channel.called.count("basic_consume"), 1) self.assertTrue(consumer._active_tags) consumer.cancel_by_queue(queue.name) consumer.cancel_by_queue(queue.name) self.assertFalse(consumer._active_tags) def test_manual_declare(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=False) self.assertIsNot(consumer.queues[0], queue) self.assertTrue(consumer.queues[0].is_bound) self.assertTrue(consumer.queues[0].exchange.is_bound) self.assertIsNot(consumer.queues[0].exchange, self.exchange) for meth in ("exchange_declare", "queue_declare", "basic_consume"): self.assertNotIn(meth, channel) consumer.declare() for meth in ("exchange_declare", "queue_declare", "queue_bind"): self.assertIn(meth, channel) self.assertNotIn("basic_consume", channel) consumer.consume() self.assertIn("basic_consume", channel) def test_consume__cancel(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.consume() consumer.cancel() self.assertIn("basic_cancel", channel) self.assertFalse(consumer._active_tags) def test___enter____exit__(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) context = consumer.__enter__() self.assertIs(context, consumer) self.assertTrue(consumer._active_tags) consumer.__exit__() self.assertIn("basic_cancel", channel) self.assertFalse(consumer._active_tags) def test_flow(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.flow(False) self.assertIn("flow", channel) def test_qos(self): channel = self.connection.channel() queue = Queue("qname", self.exchange, "rkey") consumer = Consumer(channel, queue, auto_declare=True) consumer.qos(30, 10, False) self.assertIn("basic_qos", channel) def test_purge(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") b2 = Queue("qname2", self.exchange, "rkey") b3 = Queue("qname3", self.exchange, "rkey") b4 = Queue("qname4", self.exchange, "rkey") consumer = Consumer(channel, [b1, b2, b3, b4], auto_declare=True) consumer.purge() self.assertEqual(channel.called.count("queue_purge"), 4) def test_multiple_queues(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") b2 = Queue("qname2", self.exchange, "rkey") b3 = Queue("qname3", self.exchange, "rkey") b4 = Queue("qname4", self.exchange, "rkey") consumer = Consumer(channel, [b1, b2, b3, b4]) consumer.consume() self.assertEqual(channel.called.count("exchange_declare"), 4) self.assertEqual(channel.called.count("queue_declare"), 4) self.assertEqual(channel.called.count("queue_bind"), 4) self.assertEqual(channel.called.count("basic_consume"), 4) self.assertEqual(len(consumer._active_tags), 4) consumer.cancel() self.assertEqual(channel.called.count("basic_cancel"), 4) self.assertFalse(len(consumer._active_tags)) def test_receive_callback(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) received = [] def callback(message_data, message): received.append(message_data) message.ack() message.payload # trigger cache consumer.register_callback(callback) consumer._receive_callback({u"foo": u"bar"}) self.assertIn("basic_ack", channel) self.assertIn("message_to_python", channel) self.assertEqual(received[0], {u"foo": u"bar"}) def test_basic_ack_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.ack() message.ack() consumer.register_callback(callback) self.assertRaises(MessageStateError, consumer._receive_callback, {"foo": "bar"}) def test_basic_reject(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.reject() consumer.register_callback(callback) consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject", channel) def test_basic_reject_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.reject() message.reject() consumer.register_callback(callback) self.assertRaises(MessageStateError, consumer._receive_callback, {"foo": "bar"}) self.assertIn("basic_reject", channel) def test_basic_reject__requeue(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.requeue() consumer.register_callback(callback) consumer._receive_callback({"foo": "bar"}) self.assertIn("basic_reject:requeue", channel) def test_basic_reject__requeue_twice(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) def callback(message_data, message): message.requeue() message.requeue() consumer.register_callback(callback) self.assertRaises(MessageStateError, consumer._receive_callback, {"foo": "bar"}) self.assertIn("basic_reject:requeue", channel) def test_receive_without_callbacks_raises(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) self.assertRaises(NotImplementedError, consumer.receive, 1, 2) def test_decode_error(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) consumer.channel.throw_decode_error = True self.assertRaises(ValueError, consumer._receive_callback, {"foo": "bar"}) def test_on_decode_error_callback(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") thrown = [] def on_decode_error(msg, exc): thrown.append((msg.body, exc)) consumer = Consumer(channel, [b1], on_decode_error=on_decode_error) consumer.channel.throw_decode_error = True consumer._receive_callback({"foo": "bar"}) self.assertTrue(thrown) m, exc = thrown[0] self.assertEqual(anyjson.deserialize(m), {"foo": "bar"}) self.assertIsInstance(exc, ValueError) def test_recover(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) consumer.recover() self.assertIn("basic_recover", channel) def test_revive(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") consumer = Consumer(channel, [b1]) channel2 = self.connection.channel() consumer.revive(channel2) self.assertIs(consumer.channel, channel2) self.assertIs(consumer.queues[0].channel, channel2) self.assertIs(consumer.queues[0].exchange.channel, channel2) def test__repr__(self): channel = self.connection.channel() b1 = Queue("qname1", self.exchange, "rkey") self.assertTrue(repr(Consumer(channel, [b1])))