Exemple #1
0
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'))
Exemple #2
0
 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
Exemple #3
0
 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
Exemple #4
0
 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
Exemple #5
0
 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)
Exemple #7
0
    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)
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
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'))
Exemple #11
0
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_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)
Exemple #16
0
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)
Exemple #17
0
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])))
Exemple #18
0
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)
Exemple #19
0
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)
Exemple #20
0
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])))