Example #1
0
 def test_on_clean(self):
     q = {'failed': False}
     c = Cluster([NODE], on_fail=lambda: q.update(failed=True))
     c.start(wait=True)
     c.shutdown()
     time.sleep(5)
     self.assertFalse(q['failed'])
Example #2
0
 def test_on_fail(self):
     q = {'failed': False}
     c = Cluster(
         NodeDefinition('127.0.0.1', 'xguest', 'xguest', heartbeat=20),
         on_fail=lambda: q.update(failed=True))
     c.start()
     time.sleep(5)
     c.shutdown()
     self.assertTrue(q['failed'])
Example #3
0
class TestLogFrames(unittest.TestCase):
    def test_log_frames_works(self):
        frame_logger = HoldingFrameTracer()
        self.c = Cluster([NODE], log_frames=frame_logger)
        self.c.start()
        self.assertGreaterEqual(len(frame_logger.frames), 3)

    def tearDown(self):
        self.c.shutdown()
Example #4
0
 def test_on_fail(self):
     """Assert that on_fail doesn't fire if the cluster fails to connect"""
     q = {'failed': False}
     c = Cluster(NodeDefinition(os.environ.get('AMQP_HOST', '127.0.0.1'),
                                'xguest',
                                'xguest',
                                heartbeat=20),
                 on_fail=lambda: q.update(failed=True))
     self.assertRaises(ConnectionDead, c.start)
     c.shutdown()
     self.assertFalse(q['failed'])
Example #5
0
 def test_on_clean(self):
     q = {'failed': False}
     c = Cluster([NODE], on_fail=lambda: q.update(failed=True))
     c.start(wait=True)
     c.shutdown()
     time.sleep(5)
     self.assertFalse(q['failed'])
Example #6
0
def wait_for_amqp(host_name, wait_timeout, login, password, virtual_host):
    start_at = time.time()
    wait_println_counter = 0
    node_def = NodeDefinition(host=host_name, user=login, password=password, virtual_host=virtual_host)
    while time.time() - start_at < wait_timeout:
        time_remaining = wait_timeout - (time.time() - start_at)
        try:
            Cluster([node_def]).start(wait=True, timeout=time_remaining)
        except ConnectionDead:
            wait_println_counter += 3
            if wait_println_counter == 3:
                print("Waiting 30 more seconds...")
                wait_println_counter = 0
            time.sleep(10)
        else:
            sys.exit(0)
    else:
        print("Waiting time exceeded, aborting...")
        sys.exit(1)
Example #7
0
 def setUp(self):
     self.c = Cluster([NODE])
     self.c.start()
Example #8
0
class TestDouble(unittest.TestCase):
    def setUp(self):
        self.c1 = Cluster([NODE])
        self.c1.start()

        self.c2 = Cluster([NODE])
        self.c2.start()

    def tearDown(self):
        self.c1.shutdown()
        self.c2.shutdown()

    @unittest.skip(
        "Since RabbitMQ does not support queue deletion, you need to do this manually"
    )
    def test_ccn(self):
        """
        Will consumer cancel itself after Consumer Cancel Notification?

        Manual procedure:
            - start the test
            - delete the queue using RabbitMQ Management web panel
              you got 30 seconds to do this
              see if it fails or not
        """
        q1 = Queue(b'yo', auto_delete=True)

        con1, fut1 = self.c1.consume(q1)
        fut1.result()

        #        self.c2.delete_queue(q1) #.result()

        time.sleep(30)
        self.assertTrue(con1.cancelled)

    def test_resource_locked(self):

        q = Queue(u'yo', exclusive=True, auto_delete=True)

        con, fut = self.c1.consume(q, qos=(None, 20))
        fut.result()

        try:
            con2, fut2 = self.c2.consume(
                q, fail_on_first_time_resource_locked=True)
            fut2.result(timeout=20)
        except AMQPError as e:
            self.assertEquals(e.reply_code, RESOURCE_LOCKED)
            self.assertFalse(e.is_hard_error())
        else:
            self.fail('Expected exception')
Example #9
0
 def test_log_frames_works(self):
     frame_logger = HoldingFrameTracer()
     self.c = Cluster([NODE], log_frames=frame_logger)
     self.c.start()
     self.assertGreaterEqual(len(frame_logger.frames), 3)
Example #10
0
class TestA(unittest.TestCase):
    def setUp(self):
        self.c = Cluster([NODE])
        self.c.start()

    def tearDown(self):
        self.c.shutdown()

    def test_delete_queue(self):
        # that's how it's written, due to http://www.rabbitmq.com/specification.html#method-status-queue.delete
        self.c.delete_queue(Queue(u'i-do-not-exist')).result()

    def test_consume(self):
        con, fut = self.c.consume(Queue(u'hello', exclusive=True))
        fut.result()
        con.cancel()

    def test_very_long_messages(self):
        con, fut = self.c.consume(Queue(u'hello', exclusive=True))
        fut.result()

        data = six.binary_type(os.urandom(20 * 1024 * 1024 + 1423))

        self.c.publish(Message(data), routing_key=b'hello',
                       confirm=True).result()

    #        rmsg = self.c.drain(3)
    #        rmsg.ack()

    #        self.assertEquals(rmsg.body, data)

    def test_actually_waits(self):
        a = monotonic.monotonic()

        self.c.drain(5)

        self.assertTrue(monotonic.monotonic() - a >= 4)

    def test_set_qos_but_later(self):
        con, fut = self.c.consume(Queue(u'hello', exclusive=True))

        fut.result()

        con.set_qos(100, 100)
        time.sleep(1)
        self.assertEquals(con.qos, (100, 100))

        con.set_qos(None, 110)
        time.sleep(1)
        self.assertEquals(con.qos, (0, 110))

    def test_anonymq(self):
        q = Queue(exchange=Exchange(u'ooo', type=b'fanout', auto_delete=True),
                  auto_delete=True)

        c, f = self.c.consume(q)

        f.result()

    def test_send_recv_zerolen(self):
        P = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            P['q'] = True

        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
                                  on_message=ok, no_ack=True)
        fut.result()
        self.c.publish(Message(b''), routing_key=u'hello', tx=True).result()

        time.sleep(1)

        self.assertTrue(P['q'])

    def test_message_with_propos_confirm(self):
        P = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            self.assertEquals(e.body, b'hello')
            # bcoz u can compare memoryviews to their providers :D
            self.assertEquals(e.properties.content_type, b'text/plain')
            self.assertEquals(e.properties.content_encoding, b'utf8')
            P['q'] = True

        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
                                  on_message=ok, no_ack=True)
        fut.result()
        self.c.publish(Message(b'hello', properties={
            'content_type': b'text/plain',
            'content_encoding': b'utf8'
        }), routing_key=u'hello', confirm=True).result()

        self.assertRaises(RuntimeError,
                          lambda: self.c.publish(Message(b'hello', properties={
                              'content_type': b'text/plain',
                              'content_encoding': b'utf8'
                          }), routing_key=u'hello', confirm=True,
                                                 tx=True).result())

        time.sleep(1)

        self.assertTrue(P['q'])

    def test_message_with_propos(self):
        P = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            self.assertEquals(e.body, b'hello')
            # bcoz u can compare memoryviews to their providers :D
            self.assertEquals(e.properties.content_type, b'text/plain')
            self.assertEquals(e.properties.content_encoding, b'utf8')
            P['q'] = True

        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
                                  on_message=ok, no_ack=True)
        fut.result()
        self.c.publish(Message(b'hello', properties={
            'content_type': b'text/plain',
            'content_encoding': b'utf8'
        }), routing_key=u'hello', tx=True).result()

        time.sleep(1)

        self.assertTrue(P['q'])

    def test_send_recv_nonzerolen(self):
        """with callback function"""

        P = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            self.assertEquals(e.body, b'hello')
            P['q'] = True

        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
                                  on_message=ok, no_ack=True)
        fut.result()
        self.c.publish(Message(b'hello'), routing_key=u'hello',
                       tx=True).result()

        time.sleep(1)

        self.assertTrue(P['q'])

    def test_send_recv_nonzerolen_memoryview(self):
        """single and multi frame"""
        from coolamqp.attaches import BodyReceiveMode

        con, fut = self.c.consume(Queue(u'hello', exclusive=True), no_ack=True,
                                  body_receive_mode=BodyReceiveMode.MEMORYVIEW)
        fut.result()

        data = b'hello'
        self.c.publish(Message(data), routing_key=u'hello', confirm=True)
        m = self.c.drain(2)
        self.assertIsInstance(m, MessageReceived)
        self.assertIsInstance(m.body, memoryview)
        self.assertEquals(m.body, data)

        data = six.binary_type(os.urandom(512 * 1024))
        self.c.publish(Message(data), routing_key=u'hello', confirm=True)
        m = self.c.drain(9)
        self.assertIsInstance(m, MessageReceived)
        self.assertIsInstance(m.body, memoryview)
        print(len(m.body))
        self.assertEquals(m.body.tobytes(), data)

    def test_send_recv_nonzerolen_listofmemoryview(self):
        """single and multi frame"""
        from coolamqp.attaches import BodyReceiveMode

        con, fut = self.c.consume(Queue(u'hello', exclusive=True), no_ack=True,
                                  body_receive_mode=BodyReceiveMode.LIST_OF_MEMORYVIEW)
        fut.result()

        data = b'hello'
        self.c.publish(Message(data), routing_key=u'hello', confirm=True)
        m = self.c.drain(1)
        self.assertIsInstance(m, MessageReceived)
        self.assertIsInstance(m.body[0], memoryview)
        self.assertEquals(m.body[0], data)

        data = six.binary_type(os.urandom(512 * 1024))
        self.c.publish(Message(data), routing_key=u'hello', confirm=True)
        m = self.c.drain(5)
        self.assertIsInstance(m, MessageReceived)
        self.assertTrue(all([isinstance(x, memoryview) for x in m.body]))
        self.assertEquals(b''.join(x.tobytes() for x in m.body), data)

    def test_consumer_cancel(self):
        con, fut = self.c.consume(
            Queue(u'hello', exclusive=True, auto_delete=True))
        fut.result()
        con.cancel().result()

    def test_drain_1(self):
        con, fut = self.c.consume(
            Queue(u'hello', exclusive=True, auto_delete=True))
        fut.result()

        self.c.publish(Message(b'ioi'), routing_key=u'hello')

        self.assertIsInstance(self.c.drain(2), MessageReceived)
        self.assertIsInstance(self.c.drain(1), NothingMuch)
Example #11
0
 def test_shutdown_without_start(self):
     c = Cluster([NODE])
     self.assertRaises(RuntimeError, lambda: c.shutdown())
Example #12
0
 def test_start_called_multiple_times(self):
     c = Cluster([NODE])
     c.start(wait=True)
     self.assertRaises(RuntimeError, lambda: c.start())
     c.shutdown(wait=True)
Example #13
0
class TestA(unittest.TestCase):
    def setUp(self):
        self.c = Cluster([NODE])
        self.c.start()

    def tearDown(self):
        self.c.shutdown()

    def test_queue_bind(self):
        queue = Queue('my-queue')
        exchange = Exchange('my-exchange', type='topic')
        self.c.declare(queue).result()
        self.c.declare(exchange).result()
        self.c.bind(queue, exchange, 'test').result()
        q = six.moves.queue.Queue()
        cons, fut = self.c.consume(queue,
                                   on_message=lambda msg: q.put(msg),
                                   no_ack=True)
        fut.result()
        self.c.publish(Message(b'test'),
                       exchange=exchange,
                       routing_key='test',
                       confirm=True).result()
        msg_v = q.get(block=True, timeout=5)
        self.assertEqual(msg_v.body, b'test')
        cons.cancel()

    def test_delete_queue(self):
        # that's how it's written, due to http://www.rabbitmq.com/specification.html#method-status-queue.delete
        self.c.delete_queue(Queue(u'i-do-not-exist')).result()

    def test_consume(self):
        con, fut = self.c.consume(Queue(u'hello', exclusive=True))
        fut.result()
        con.cancel()

    def test_very_long_messages(self):
        con, fut = self.c.consume(Queue(u'hello', exclusive=True))
        fut.result()

        data = six.binary_type(os.urandom(20 * 1024 * 1024 + 1423))

        self.c.publish(Message(data), routing_key=b'hello',
                       confirm=True).result()

    def test_actually_waits(self):
        a = monotonic()

        self.c.drain(5)

        self.assertGreaterEqual(monotonic() - a, 4)

    def test_set_qos_but_later(self):
        con, fut = self.c.consume(Queue(u'hello2', exclusive=True))

        fut.result()

        con.set_qos(100, 100)
        time.sleep(1)
        self.assertEquals(con.qos, (100, 100))

        con.set_qos(None, 110)
        time.sleep(1)
        self.assertEquals(con.qos, (0, 110))

    def test_declare_anonymous(self):
        xchg = Exchange('wtfzomg', type='fanout')
        q = Queue(exchange=xchg)
        self.c.declare(xchg).result()
        self.c.declare(q).result()
        self.assertTrue(q.name)

    def test_anonymq(self):
        q = Queue(exchange=Exchange(u'ooo', type=b'fanout', auto_delete=True),
                  auto_delete=True)

        c, f = self.c.consume(q)

        f.result()

        self.assertTrue(q.name)

    def test_send_recv_zerolen(self):
        p = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            p['q'] = True

        con, fut = self.c.consume(Queue(u'hello3', exclusive=True),
                                  on_message=ok,
                                  no_ack=True)
        fut.result()
        self.c.publish(Message(b''), routing_key=u'hello3', tx=True).result()

        time.sleep(1)

        self.assertTrue(p['q'])

    def test_nacking_and_acking(self):
        p = {'q': False, 'count': 0}

        def ok(msg):
            if not p['count']:
                msg.nack()
                msg.nack()
            else:
                msg.ack()
                msg.ack()
            self.assertIsInstance(msg, ReceivedMessage)
            p['q'] = True
            p['count'] += 1

        con, fut = self.c.consume(Queue(u'hello3', exclusive=True),
                                  on_message=ok,
                                  no_ack=False)
        fut.result()
        self.c.publish(Message(b''), routing_key=u'hello3', tx=True).result()

        time.sleep(1)

        self.assertTrue(p['q'])
        self.assertEquals(p['count'], 2)

    def test_message_with_propos_confirm(self):
        p = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            self.assertEquals(e.body, b'hello4')
            # bcoz u can compare memoryviews to their providers :D
            self.assertEquals(e.properties.content_type, b'text/plain')
            self.assertEquals(e.properties.content_encoding, b'utf8')
            p['q'] = True

        con, fut = self.c.consume(Queue(u'hello4', exclusive=True),
                                  on_message=ok,
                                  no_ack=True)
        fut.result()
        self.c.publish(Message(b'hello4',
                               properties={
                                   'content_type': b'text/plain',
                                   'content_encoding': b'utf8'
                               }),
                       routing_key=u'hello4',
                       confirm=True).result()

        self.assertRaises(
            RuntimeError,
            lambda: self.c.publish(Message(b'hello4',
                                           properties={
                                               'content_type': b'text/plain',
                                               'content_encoding': b'utf8'
                                           }),
                                   routing_key=u'hello4',
                                   confirm=True,
                                   tx=True).result())

        time.sleep(1)

        self.assertTrue(p['q'])

    def test_message_with_propos(self):
        p = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            self.assertEquals(e.body, b'hello5')
            # bcoz u can compare memoryviews to their providers :D
            self.assertEquals(e.properties.content_type, b'text/plain')
            self.assertEquals(e.properties.content_encoding, b'utf8')
            p['q'] = True

        con, fut = self.c.consume(Queue(u'hello5', exclusive=True),
                                  on_message=ok,
                                  no_ack=True)
        fut.result()
        self.c.publish(Message(b'hello5',
                               properties={
                                   'content_type': b'text/plain',
                                   'content_encoding': b'utf8'
                               }),
                       routing_key=u'hello5',
                       tx=True).result()

        time.sleep(2)

        self.assertTrue(p['q'])

    def test_send_recv_nonzerolen(self):
        """with callback function"""

        p = {'q': False}

        def ok(e):
            self.assertIsInstance(e, ReceivedMessage)
            self.assertEquals(e.body, b'hello6')
            p['q'] = True

        con, fut = self.c.consume(Queue(u'hello6', exclusive=True),
                                  on_message=ok,
                                  no_ack=True)
        fut.result()
        self.c.publish(Message(b'hello6'), routing_key=u'hello6',
                       tx=True).result()

        time.sleep(1)

        self.assertTrue(p['q'])

    def test_send_recv_nonzerolen_memoryview(self):
        """single and multi frame in MEMORYVIEW mode"""
        from coolamqp.attaches import BodyReceiveMode

        con, fut = self.c.consume(Queue(u'hello7', exclusive=True),
                                  no_ack=True,
                                  body_receive_mode=BodyReceiveMode.MEMORYVIEW)
        fut.result()

        data = b'hello7'
        self.c.publish(Message(data), routing_key=u'hello7', confirm=True)
        m = self.c.drain(2)
        self.assertIsInstance(m, MessageReceived)
        self.assertIsInstance(m.body, memoryview)
        self.assertEquals(m.body, data)

        data = six.binary_type(os.urandom(512 * 1024))
        self.c.publish(Message(data), routing_key=u'hello7', confirm=True)
        m = self.c.drain(9)
        self.assertIsInstance(m, MessageReceived)
        self.assertIsInstance(m.body, memoryview)
        print(len(m.body))
        self.assertEquals(m.body.tobytes(), data)

    def test_send_recv_nonzerolen_listofmemoryview(self):
        """single and multi frame in LIST_OF_MEMORYVIEW mode"""
        from coolamqp.attaches import BodyReceiveMode

        con, fut = self.c.consume(
            Queue(u'hello8', exclusive=True),
            no_ack=True,
            body_receive_mode=BodyReceiveMode.LIST_OF_MEMORYVIEW)
        fut.result()

        data = b'hello8'
        self.c.publish(Message(data), routing_key=u'hello8', confirm=True)
        m = self.c.drain(1)
        self.assertIsInstance(m, MessageReceived)
        self.assertIsInstance(m.body[0], memoryview)
        self.assertEquals(m.body[0], data)

        data = six.binary_type(os.urandom(512 * 1024))
        self.c.publish(Message(data), routing_key=u'hello8', confirm=True)
        m = self.c.drain(5)
        self.assertIsInstance(m, MessageReceived)
        self.assertTrue(all([isinstance(x, memoryview) for x in m.body]))
        self.assertEquals(b''.join(x.tobytes() for x in m.body), data)

    def test_consumer_cancel(self):
        con, fut = self.c.consume(
            Queue(u'hello9', exclusive=True, auto_delete=True))
        fut.result()
        con.cancel().result()

    def test_drain_1(self):
        con, fut = self.c.consume(
            Queue(u'helloA', exclusive=True, auto_delete=True))
        fut.result()

        self.c.publish(Message(b'ioi'), routing_key=u'helloA')

        self.assertIsInstance(self.c.drain(2), MessageReceived)
        self.assertIsInstance(self.c.drain(1), NothingMuch)
Example #14
0
class TestDouble(unittest.TestCase):
    def setUp(self):
        self.c1 = Cluster([NODE])
        self.c1.start()

        self.c2 = Cluster([NODE])
        self.c2.start()

    def tearDown(self):
        self.c1.shutdown()
        self.c2.shutdown()

    @unittest.skip(
        "Since RabbitMQ does not support queue deletion, you need to do this manually")
    def test_ccn(self):
        """
        Will consumer cancel itself after Consumer Cancel Notification?

        Manual procedure:
            - start the test
            - delete the queue using RabbitMQ Management web panel
              you got 30 seconds to do this
              see if it fails or not
        """
        q1 = Queue(b'yo', auto_delete=True)

        con1, fut1 = self.c1.consume(q1)
        fut1.result()

        #        self.c2.delete_queue(q1) #.result()

        time.sleep(30)
        self.assertTrue(con1.cancelled)

    def test_resource_locked(self):

        q = Queue(u'yo', exclusive=True, auto_delete=True)

        con, fut = self.c1.consume(q, qos=(None, 20))
        fut.result()

        try:
            con2, fut2 = self.c2.consume(q,
                                         fail_on_first_time_resource_locked=True)
            fut2.result()
        except AMQPError as e:
            self.assertEquals(e.reply_code, RESOURCE_LOCKED)
            self.assertFalse(e.is_hard_error())
        else:
            self.fail('Expected exception')
Example #15
0
# coding=UTF-8
from __future__ import absolute_import, division, print_function
import time, logging, threading
from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, \
    Exchange
from coolamqp.exceptions import AMQPError
from coolamqp.clustering import Cluster

import time

NODE = NodeDefinition('127.0.0.1', 'guest', 'guest', heartbeat=20)
logging.basicConfig(level=logging.DEBUG)

amqp = Cluster([NODE])
amqp.start(wait=True)

q = Queue(u'lolwut', auto_delete=True, exclusive=True)
c, f = amqp.consume(q, no_ack=True, body_receive_mode=1)

# time.sleep(30)

# amqp.shutdown(True)
Example #16
0
 def test_shutdown_without_start(self):
     c = Cluster([NODE])
     self.assertRaises(RuntimeError, lambda: c.shutdown())
Example #17
0
 def test_start_called_multiple_times(self):
     c = Cluster([NODE])
     c.start(wait=True)
     self.assertRaises(RuntimeError, lambda: c.start())
     c.shutdown(wait=True)
Example #18
0
# coding=UTF-8
from __future__ import absolute_import, division, print_function

import logging
import os

from coolamqp.clustering import Cluster
from coolamqp.objects import NodeDefinition, Queue

NODE = NodeDefinition(os.environ.get('AMQP_HOST', '127.0.0.1'), 'guest', 'guest', heartbeat=20)
logging.basicConfig(level=logging.DEBUG)

amqp = Cluster([NODE])
amqp.start(wait=True)

q = Queue(u'lolwut', auto_delete=True, exclusive=True)
c, f = amqp.consume(q, no_ack=True, body_receive_mode=1)

# time.sleep(30)

# amqp.shutdown(True)
Example #19
0
    def setUp(self):
        self.c1 = Cluster([NODE])
        self.c1.start()

        self.c2 = Cluster([NODE])
        self.c2.start()
Example #20
0
    def setUp(self):
        self.c1 = Cluster([NODE])
        self.c1.start()

        self.c2 = Cluster([NODE])
        self.c2.start()
Example #21
0
class TestExchanges(unittest.TestCase):
    def setUp(self):
        self.c = Cluster([NODE])
        self.c.start()

    def tearDown(self):
        self.c.shutdown()

    def test_declare_exchange(self):
        a = Exchange(u'jolax', type=b'fanout', auto_delete=True)
        self.c.declare(a).result()

    def test_fanout(self):
        x = Exchange(u'jola', type='direct', auto_delete=True)

        c1, f1 = self.c.consume(Queue('one', exchange=x, exclusive=True),
                                no_ack=True)
        c2, f2 = self.c.consume(Queue('two', exchange=x, exclusive=True),
                                no_ack=True)

        f1.result()
        f2.result()

        self.c.publish(Message(b'hello'), exchange=x, tx=True).result()

        self.assertIsInstance(self.c.drain(2), MessageReceived)
        self.assertIsInstance(self.c.drain(2), MessageReceived)
        self.assertIsInstance(self.c.drain(2), NothingMuch)
Example #22
0
 def setUp(self):
     self.c = Cluster([NODE])
     self.c.start()
Example #23
0
class TestExchanges(unittest.TestCase):
    def setUp(self):
        self.c = Cluster([NODE])
        self.c.start()

    def tearDown(self):
        self.c.shutdown()

    def test_declare_exchange(self):
        a = Exchange(u'jolax', type=b'fanout', auto_delete=True)
        self.c.declare(a).result()

    def test_fanout(self):
        x = Exchange(u'jola', type='direct', auto_delete=True)

        c1, f1 = self.c.consume(Queue('one', exchange=x, exclusive=True),
                                no_ack=True)
        c2, f2 = self.c.consume(Queue('two', exchange=x, exclusive=True),
                                no_ack=True)

        f1.result()
        f2.result()

        self.c.publish(Message(b'hello'), exchange=x, tx=True).result()

        self.assertIsInstance(self.c.drain(2), MessageReceived)
        self.assertIsInstance(self.c.drain(2), MessageReceived)
        self.assertIsInstance(self.c.drain(2), NothingMuch)