def test_consume_no_local(self): """ Test that the no_local flag is honoured in the consume method """ channel = self.channel #setup, declare two queues: channel.queue_declare(queue="test-queue-1a", exclusive=True) channel.queue_declare(queue="test-queue-1b", exclusive=True) #establish two consumers one of which excludes delivery of locally sent messages channel.basic_consume(consumer_tag="local_included", queue="test-queue-1a") channel.basic_consume(consumer_tag="local_excluded", queue="test-queue-1b", no_local=True) #send a message channel.basic_publish(routing_key="test-queue-1a", content=Content("consume_no_local")) channel.basic_publish(routing_key="test-queue-1b", content=Content("consume_no_local")) #check the queues of the two consumers excluded = self.client.queue("local_excluded") included = self.client.queue("local_included") msg = included.get(timeout=1) self.assertEqual("consume_no_local", msg.content.body) try: excluded.get(timeout=1) self.fail( "Received locally published message though no_local=true") except Empty: None
def test_cancel(self): """ Test compliance of the basic.cancel method """ channel = self.channel #setup, declare a queue: channel.queue_declare(queue="test-queue-4", exclusive=True) channel.basic_consume(consumer_tag="my-consumer", queue="test-queue-4") channel.basic_publish(routing_key="test-queue-4", content=Content("One")) myqueue = self.client.queue("my-consumer") msg = myqueue.get(timeout=1) self.assertEqual("One", msg.content.body) #cancel should stop messages being delivered channel.basic_cancel(consumer_tag="my-consumer") channel.basic_publish(routing_key="test-queue-4", content=Content("Two")) try: msg = myqueue.get(timeout=1) self.fail("Got message after cancellation: " + msg) except Empty: None #cancellation of non-existant consumers should be handled without error channel.basic_cancel(consumer_tag="my-consumer") channel.basic_cancel(consumer_tag="this-never-existed")
def unbind_test(self, exchange, routing_key="", args=None, headers={}): #bind two queues and consume from them channel = self.channel channel.queue_declare(queue="queue-1", exclusive="True") channel.queue_declare(queue="queue-2", exclusive="True") channel.basic_consume(queue="queue-1", consumer_tag="queue-1", no_ack=True) channel.basic_consume(queue="queue-2", consumer_tag="queue-2", no_ack=True) queue1 = self.client.queue("queue-1") queue2 = self.client.queue("queue-2") channel.queue_bind(exchange=exchange, queue="queue-1", routing_key=routing_key, arguments=args) channel.queue_bind(exchange=exchange, queue="queue-2", routing_key=routing_key, arguments=args) #send a message that will match both bindings channel.basic_publish(exchange=exchange, routing_key=routing_key, content=Content("one", properties={"headers": headers})) #unbind first queue channel.queue_unbind(exchange=exchange, queue="queue-1", routing_key=routing_key, arguments=args) #send another message channel.basic_publish(exchange=exchange, routing_key=routing_key, content=Content("two", properties={"headers": headers})) #check one queue has both messages and the other has only one self.assertEquals("one", queue1.get(timeout=1).content.body) try: msg = queue1.get(timeout=1) self.fail("Got extra message: %s" % msg.body) except Empty: pass self.assertEquals("one", queue2.get(timeout=1).content.body) self.assertEquals("two", queue2.get(timeout=1).content.body) try: msg = queue2.get(timeout=1) self.fail("Got extra message: " + msg) except Empty: pass
def test_qos_prefetch_size(self): """ Test that the prefetch size specified is honoured """ #setup: declare queue and subscribe channel = self.channel channel.queue_declare(queue="test-prefetch-size", exclusive=True) subscription = channel.basic_consume(queue="test-prefetch-size", no_ack=False) queue = self.client.queue(subscription.consumer_tag) #set prefetch to 50 bytes (each message is 9 or 10 bytes): channel.basic_qos(prefetch_size=50) #publish 10 messages: for i in range(1, 11): channel.basic_publish(routing_key="test-prefetch-size", content=Content("Message %d" % i)) #only 5 messages should have been delivered (i.e. 45 bytes worth): for i in range(1, 6): msg = queue.get(timeout=1) self.assertEqual("Message %d" % i, msg.content.body) try: extra = queue.get(timeout=1) self.fail("Got unexpected 6th message in original queue: " + extra.content.body) except Empty: None #ack messages and check that the next set arrive ok: channel.basic_ack(delivery_tag=msg.delivery_tag, multiple=True) for i in range(6, 11): msg = queue.get(timeout=1) self.assertEqual("Message %d" % i, msg.content.body) channel.basic_ack(delivery_tag=msg.delivery_tag, multiple=True) try: extra = queue.get(timeout=1) self.fail("Got unexpected 11th message in original queue: " + extra.content.body) except Empty: None #make sure that a single oversized message still gets delivered large = "abcdefghijklmnopqrstuvwxyz" large = large + "-" + large channel.basic_publish(routing_key="test-prefetch-size", content=Content(large)) msg = queue.get(timeout=1) self.assertEqual(large, msg.content.body)
def test_ack(self): """ Test basic ack/recover behaviour """ channel = self.channel channel.queue_declare(queue="test-ack-queue", exclusive=True) reply = channel.basic_consume(queue="test-ack-queue", no_ack=False) queue = self.client.queue(reply.consumer_tag) channel.basic_publish(routing_key="test-ack-queue", content=Content("One")) channel.basic_publish(routing_key="test-ack-queue", content=Content("Two")) channel.basic_publish(routing_key="test-ack-queue", content=Content("Three")) channel.basic_publish(routing_key="test-ack-queue", content=Content("Four")) channel.basic_publish(routing_key="test-ack-queue", content=Content("Five")) msg1 = queue.get(timeout=1) msg2 = queue.get(timeout=1) msg3 = queue.get(timeout=1) msg4 = queue.get(timeout=1) msg5 = queue.get(timeout=1) self.assertEqual("One", msg1.content.body) self.assertEqual("Two", msg2.content.body) self.assertEqual("Three", msg3.content.body) self.assertEqual("Four", msg4.content.body) self.assertEqual("Five", msg5.content.body) channel.basic_ack(delivery_tag=msg2.delivery_tag, multiple=True) #One & Two channel.basic_ack(delivery_tag=msg4.delivery_tag, multiple=False) #Four channel.basic_recover(requeue=False) msg3b = queue.get(timeout=1) msg5b = queue.get(timeout=1) self.assertEqual("Three", msg3b.content.body) self.assertEqual("Five", msg5b.content.body) try: extra = queue.get(timeout=1) self.fail("Got unexpected message: " + extra.content.body) except Empty: None
def test_flow_control(self): queue_name = "flow-controled-queue" connection = self.connect( channel_options={"qpid.flow_control_wait_failure": 1}) channel = connection.channel(1) channel.channel_open() channel.queue_declare(queue=queue_name, arguments={ "x-qpid-capacity": 25, "x-qpid-flow-resume-capacity": 15 }) try: for i in xrange(100): channel.basic_publish( exchange="", routing_key=queue_name, content=Content( "This is a message with more than 25 bytes. This should trigger flow control." )) time.sleep(.1) self.fail("Flow Control did not work") except Timeout: # this is expected pass consumer_reply = channel.basic_consume(queue=queue_name, consumer_tag="consumer", no_ack=True) queue = self.client.queue(consumer_reply.consumer_tag) while True: try: msg = queue.get(timeout=1) except Empty: break channel.basic_cancel(consumer_tag=consumer_reply.consumer_tag) try: channel.basic_publish( exchange="", routing_key=queue_name, content=Content( "This should not block because we have just cleared the queue." )) except Timeout: self.fail( "Unexpected Timeout. Flow Control should not be in effect.") connection.close()
def test_purge(self): """ Test that the purge method removes messages from the queue """ channel = self.channel #setup, declare a queue and add some messages to it: channel.exchange_declare(exchange="test-exchange", type="direct") channel.queue_declare(queue="test-queue", exclusive=True) channel.queue_bind(queue="test-queue", exchange="test-exchange", routing_key="key") channel.basic_publish(exchange="test-exchange", routing_key="key", content=Content("one")) channel.basic_publish(exchange="test-exchange", routing_key="key", content=Content("two")) channel.basic_publish(exchange="test-exchange", routing_key="key", content=Content("three")) #check that the queue now reports 3 messages: reply = channel.queue_declare(queue="test-queue") self.assertEqual(3, reply.message_count) #now do the purge, then test that three messages are purged and the count drops to 0 reply = channel.queue_purge(queue="test-queue") self.assertEqual(3, reply.message_count) reply = channel.queue_declare(queue="test-queue") self.assertEqual(0, reply.message_count) #send a further message and consume it, ensuring that the other messages are really gone channel.basic_publish(exchange="test-exchange", routing_key="key", content=Content("four")) reply = channel.basic_consume(queue="test-queue", no_ack=True) queue = self.client.queue(reply.consumer_tag) msg = queue.get(timeout=1) self.assertEqual("four", msg.content.body) #check error conditions (use new channels): channel = self.client.channel(2) channel.channel_open() try: #queue specified but doesn't exist: channel.queue_purge(queue="invalid-queue") self.fail("Expected failure when purging non-existent queue") except Closed, e: self.assertChannelException(404, e.args[0])
def test_commit_overlapping_acks(self): """ Test that logically 'overlapping' acks do not cause errors on commit """ channel = self.channel channel.queue_declare(queue="commit-overlapping", exclusive=True) for i in range(1, 10): channel.basic_publish(routing_key="commit-overlapping", content=Content("Message %d" % i)) channel.tx_select() sub = channel.basic_consume(queue="commit-overlapping", no_ack=False) queue = self.client.queue(sub.consumer_tag) for i in range(1, 10): msg = queue.get(timeout=1) self.assertEqual("Message %d" % i, msg.content.body) if i in [3, 6, 10]: channel.basic_ack(delivery_tag=msg.delivery_tag) channel.tx_commit() #check all have been acked: try: extra = queue.get(timeout=1) self.fail("Got unexpected message: " + extra.content.body) except Empty: None
def test_delete_simple(self): """ Test basic queue deletion """ channel = self.channel #straight-forward case: channel.queue_declare(queue="delete-me") channel.basic_publish(routing_key="delete-me", content=Content("a")) channel.basic_publish(routing_key="delete-me", content=Content("b")) channel.basic_publish(routing_key="delete-me", content=Content("c")) reply = channel.queue_delete(queue="delete-me") self.assertEqual(3, reply.message_count) #check that it has gone be declaring passively try: channel.queue_declare(queue="delete-me", passive="True") self.fail("Queue has not been deleted") except Closed, e: self.assertChannelException(404, e.args[0])
def echo_message(self, body): channel = self.channel self.queue_declare(queue="q") channel.tx_select() consumer = self.consume("q", no_ack=False) channel.basic_publish(content=Content(body), routing_key="q") channel.tx_commit() msg = consumer.get(timeout=self.recv_timeout()) channel.basic_ack(delivery_tag=msg.delivery_tag) channel.tx_commit() self.assertEqual(len(body), len(msg.content.body)) self.assertEqual(body, msg.content.body)
def assertPublishGet(self, queue, exchange="", routing_key="", properties=None): """ Publish to exchange and assert queue.get() returns the same message. """ body = self.uniqueString() self.channel.basic_publish( exchange=exchange, content=Content(body, properties=properties), routing_key=routing_key) msg = queue.get(timeout=1) self.assertEqual(body, msg.content.body) if (properties): self.assertEqual(properties, msg.content.properties)
def test_ack_and_no_ack(self): """ First, this test tries to receive a message with a no-ack consumer. Second, this test tries to explicitly receive and acknowledge a message with an acknowledging consumer. """ ch = self.channel self.queue_declare(ch, queue="myqueue") # No ack consumer ctag = ch.basic_consume(queue="myqueue", no_ack=True).consumer_tag body = "test no-ack" ch.basic_publish(routing_key="myqueue", content=Content(body)) msg = self.client.queue(ctag).get(timeout=5) self.assert_(msg.content.body == body) # Acknowledging consumer self.queue_declare(ch, queue="otherqueue") ctag = ch.basic_consume(queue="otherqueue", no_ack=False).consumer_tag body = "test ack" ch.basic_publish(routing_key="otherqueue", content=Content(body)) msg = self.client.queue(ctag).get(timeout=5) ch.basic_ack(delivery_tag=msg.delivery_tag) self.assert_(msg.content.body == body)
def test_basic_delivery_queued(self): """ Test basic message delivery where publish is issued before consume (i.e. requires queueing of the message) """ channel = self.channel self.exchange_declare(channel, exchange="test-exchange", type="direct") self.queue_declare(channel, queue="test-queue") channel.queue_bind(queue="test-queue", exchange="test-exchange", routing_key="key") body = "Queued Delivery" channel.basic_publish(exchange="test-exchange", routing_key="key", content=Content(body)) reply = channel.basic_consume(queue="test-queue", no_ack=True) queue = self.client.queue(reply.consumer_tag) msg = queue.get(timeout=self.recv_timeout()) self.assert_(msg.content.body == body)
def test_reconnect_to_durable_subscription(self): try: publisherchannel = self.channel my_id = "my_id" consumer_connection_properties_with_instance = {"instance": my_id} queue_for_subscription = "queue_for_subscription_%s" % my_id topic_name = "my_topic_name" test_message = self.uniqueString() durable_subscription_client = self.connect( client_properties=consumer_connection_properties_with_instance) consumerchannel = durable_subscription_client.channel(1) consumerchannel.channel_open() self._declare_and_bind_exclusive_queue_on_topic_exchange( consumerchannel, queue_for_subscription, topic_name) # disconnect durable_subscription_client.close() # send message to topic publisherchannel.basic_publish(routing_key=topic_name, exchange="amq.topic", content=Content(test_message)) # reconnect and consume message durable_subscription_client = self.connect( client_properties=consumer_connection_properties_with_instance) consumerchannel = durable_subscription_client.channel(1) consumerchannel.channel_open() self._declare_and_bind_exclusive_queue_on_topic_exchange( consumerchannel, queue_for_subscription, topic_name) # Create consumer and consume the message that was sent whilst subscriber was disconnected. By convention we # declare the consumer as exclusive to forbid concurrent access. subscription = consumerchannel.basic_consume( queue=queue_for_subscription, exclusive=True) queue = durable_subscription_client.queue( subscription.consumer_tag) # consume and verify message content msg = queue.get(timeout=1) self.assertEqual(test_message, msg.content.body) consumerchannel.basic_ack(delivery_tag=msg.delivery_tag) finally: consumerchannel.queue_delete(queue=queue_for_subscription) durable_subscription_client.close()
def test_channel_flow(self): channel = self.channel channel.queue_declare(queue="flow_test_queue", exclusive=True) ctag = channel.basic_consume(queue="flow_test_queue", no_ack=True).consumer_tag incoming = self.client.queue(ctag) channel.channel_flow(active=False) channel.basic_publish(routing_key="flow_test_queue", content=Content("abcdefghijklmnopqrstuvwxyz")) try: incoming.get(timeout=self.recv_timeout_negative()) self.fail("Received message when flow turned off.") except Empty: None channel.channel_flow(active=True) msg = incoming.get(timeout=self.recv_timeout()) self.assertEqual("abcdefghijklmnopqrstuvwxyz", msg.content.body)
def test_commit_ok_possibly_interleaved_with_message_delivery(self): """This test exposes an defect on the Java Broker (QPID-6094). The Java Broker (0.32 and below) can contravene the AMQP spec by sending other frames between the message header/frames. As this is a long standing defect in the Java Broker, QPID-6082 changed the Python client to allow it to tolerate such illegal interleaving. """ channel = self.channel queue_name = "q" self.queue_declare(queue=queue_name) count = 25 channel.basic_qos(prefetch_count=count) channel.tx_select() bodies = [] for i in range(count): body = self.randomLongString() bodies.append(body) channel.basic_publish(content=Content(bodies[i]), routing_key=queue_name) channel.tx_commit() # Start consuming. Prefetch will mean the Broker will start to send us # all the messages accumulating them in the client. consumer = self.consume("q", no_ack=False) # Get and ack/commit the first message msg = consumer.get(timeout=self.recv_timeout()) channel.basic_ack(delivery_tag=msg.delivery_tag) channel.tx_commit() # In the problematic case, the Broker interleaves our commit-ok response amongst the content # frames of message. QPID-6082 means the Python client now tolerates this # problem and all messages should arrive correctly. expectedBody = bodies[0] self.assertEqual(len(expectedBody), len(msg.content.body)) self.assertEqual(expectedBody, msg.content.body) for i in range(1, len(bodies)): msg = consumer.get(timeout=self.recv_timeout()) expectedBody = bodies[i] self.assertEqual(len(expectedBody), len(msg.content.body)) self.assertEqual(expectedBody, msg.content.body)
def test_delete_ifempty(self): """ Test that if_empty field of queue_delete is honoured """ channel = self.channel #create a queue and add a message to it (use default binding): channel.queue_declare(queue="delete-me-2") channel.queue_declare(queue="delete-me-2", passive="True") channel.basic_publish(routing_key="delete-me-2", content=Content("message")) #try to delete, but only if empty: try: channel.queue_delete(queue="delete-me-2", if_empty="True") self.fail("Expected delete if_empty to fail for non-empty queue") except Closed, e: self.assertChannelException(406, e.args[0])
def test_small_message(self): channel = self.channel self.queue_declare(queue="q") channel.tx_select() consumer = self.consume("q", no_ack=False) body = self.uniqueString() channel.basic_publish(content=Content(body), routing_key="q") channel.tx_commit() msg = consumer.get(timeout=1) channel.basic_ack(delivery_tag=msg.delivery_tag) channel.tx_commit() self.assertEqual(body, msg.content.body)
def test_qos_prefetch_count(self): """ Test that the prefetch count specified is honoured """ #setup: declare queue and subscribe channel = self.channel channel.queue_declare(queue="test-prefetch-count", exclusive=True) subscription = channel.basic_consume(queue="test-prefetch-count", no_ack=False) queue = self.client.queue(subscription.consumer_tag) #set prefetch to 5: channel.basic_qos(prefetch_count=5) #publish 10 messages: for i in range(1, 11): channel.basic_publish(routing_key="test-prefetch-count", content=Content("Message %d" % i)) #only 5 messages should have been delivered: for i in range(1, 6): msg = queue.get(timeout=1) self.assertEqual("Message %d" % i, msg.content.body) try: extra = queue.get(timeout=1) self.fail("Got unexpected 6th message in original queue: " + extra.content.body) except Empty: None #ack messages and check that the next set arrive ok: channel.basic_ack(delivery_tag=msg.delivery_tag, multiple=True) for i in range(6, 11): msg = queue.get(timeout=1) self.assertEqual("Message %d" % i, msg.content.body) channel.basic_ack(delivery_tag=msg.delivery_tag, multiple=True) try: extra = queue.get(timeout=1) self.fail("Got unexpected 11th message in original queue: " + extra.content.body) except Empty: None
def perform_txn_work(self, channel, name_a, name_b, name_c): """ Utility method that does some setup and some work under a transaction. Used for testing both commit and rollback """ #setup: channel.queue_declare(queue=name_a, exclusive=True) channel.queue_declare(queue=name_b, exclusive=True) channel.queue_declare(queue=name_c, exclusive=True) key = "my_key_" + name_b topic = "my_topic_" + name_c channel.queue_bind(queue=name_b, exchange="amq.direct", routing_key=key) channel.queue_bind(queue=name_c, exchange="amq.topic", routing_key=topic) for i in range(1, 5): channel.basic_publish(routing_key=name_a, content=Content("Message %d" % i)) channel.basic_publish(routing_key=key, exchange="amq.direct", content=Content("Message 6")) channel.basic_publish(routing_key=topic, exchange="amq.topic", content=Content("Message 7")) channel.tx_select() #consume and ack messages sub_a = channel.basic_consume(queue=name_a, no_ack=False) queue_a = self.client.queue(sub_a.consumer_tag) for i in range(1, 5): msg = queue_a.get(timeout=1) self.assertEqual("Message %d" % i, msg.content.body) channel.basic_ack(delivery_tag=msg.delivery_tag, multiple=True) sub_b = channel.basic_consume(queue=name_b, no_ack=False) queue_b = self.client.queue(sub_b.consumer_tag) msg = queue_b.get(timeout=1) self.assertEqual("Message 6", msg.content.body) channel.basic_ack(delivery_tag=msg.delivery_tag) sub_c = channel.basic_consume(queue=name_c, no_ack=False) queue_c = self.client.queue(sub_c.consumer_tag) msg = queue_c.get(timeout=1) self.assertEqual("Message 7", msg.content.body) channel.basic_ack(delivery_tag=msg.delivery_tag) #publish messages for i in range(1, 5): channel.basic_publish(routing_key=topic, exchange="amq.topic", content=Content("TxMessage %d" % i)) channel.basic_publish(routing_key=key, exchange="amq.direct", content=Content("TxMessage 6")) channel.basic_publish(routing_key=name_a, content=Content("TxMessage 7")) return queue_a, queue_b, queue_c
def test_basic_delivery_immediate(self): """ Test basic message delivery where consume is issued before publish """ channel = self.channel self.exchange_declare(channel, exchange="test-exchange", type="direct") self.queue_declare(channel, queue="test-queue") channel.queue_bind(queue="test-queue", exchange="test-exchange", routing_key="key") reply = channel.basic_consume(queue="test-queue", no_ack=True) queue = self.client.queue(reply.consumer_tag) body = "Immediate Delivery" channel.basic_publish(exchange="test-exchange", routing_key="key", content=Content(body), immediate=True) msg = queue.get(timeout=5) self.assert_(msg.content.body == body)
def test_large_message(self): channel = self.channel self.queue_declare(queue="q") channel.tx_select() consumer = self.consume("q", no_ack=False) # This is default maximum frame size supported by the Java Broker. Python # currently does not support framing of oversized messages in multiple frames. body = self.randomLongString() channel.basic_publish(content=Content(body), routing_key="q") channel.tx_commit() msg = consumer.get(timeout=1) channel.basic_ack(delivery_tag=msg.delivery_tag) channel.tx_commit() self.assertEqual(len(body), len(msg.content.body)) self.assertEqual(body, msg.content.body)
def test_large_message_received_in_many_content_frames(self): channel = self.channel queue_name = "q" self.queue_declare(queue=queue_name) channel.tx_select() body = self.randomLongString() channel.basic_publish(content=Content(body), routing_key=queue_name) channel.tx_commit() consuming_client = None try: # Create a second connection with minimum framesize. The Broker will then be forced to chunk # the content in order to send it to us. consuming_client = qpid.client.Client(self.config.broker.host, self.config.broker.port) tune_params = {"channel_max": 256, "frame_max": 4096} consuming_client.start(username=self.config.broker.user, password=self.config.broker.password, tune_params=tune_params) consuming_channel = consuming_client.channel(1) consuming_channel.channel_open() consuming_channel.tx_select() consumer_reply = consuming_channel.basic_consume(queue=queue_name, no_ack=False) consumer = consuming_client.queue(consumer_reply.consumer_tag) msg = consumer.get(timeout=1) consuming_channel.basic_ack(delivery_tag=msg.delivery_tag) consuming_channel.tx_commit() self.assertEqual(len(body), len(msg.content.body)) self.assertEqual(body, msg.content.body) finally: if consuming_client: consuming_client.close()
def test_get(self): """ Test basic_get method """ channel = self.channel channel.queue_declare(queue="test-get", exclusive=True) #publish some messages (no_ack=True) for i in range(1, 11): channel.basic_publish(routing_key="test-get", content=Content("Message %d" % i)) #use basic_get to read back the messages, and check that we get an empty at the end for i in range(1, 11): reply = channel.basic_get(no_ack=True) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_ok") self.assertEqual("Message %d" % i, reply.content.body) reply = channel.basic_get(no_ack=True) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_empty") #repeat for no_ack=False for i in range(11, 21): channel.basic_publish(routing_key="test-get", content=Content("Message %d" % i)) for i in range(11, 21): reply = channel.basic_get(no_ack=False) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_ok") self.assertEqual("Message %d" % i, reply.content.body) if (i == 13): channel.basic_ack(delivery_tag=reply.delivery_tag, multiple=True) if (i in [15, 17, 19]): channel.basic_ack(delivery_tag=reply.delivery_tag) reply = channel.basic_get(no_ack=True) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_empty") #recover(requeue=True) channel.basic_recover(requeue=True) #get the unacked messages again (14, 16, 18, 20) for i in [14, 16, 18, 20]: reply = channel.basic_get(no_ack=False) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_ok") self.assertEqual("Message %d" % i, reply.content.body) channel.basic_ack(delivery_tag=reply.delivery_tag) reply = channel.basic_get(no_ack=True) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_empty") channel.basic_recover(requeue=True) reply = channel.basic_get(no_ack=True) self.assertEqual(reply.method.klass.name, "basic") self.assertEqual(reply.method.name, "get_empty")
def test_recover_requeue(self): """ Test requeing on recovery """ channel = self.channel channel.queue_declare(queue="test-requeue", exclusive=True) subscription = channel.basic_consume(queue="test-requeue", no_ack=False) queue = self.client.queue(subscription.consumer_tag) channel.basic_publish(routing_key="test-requeue", content=Content("One")) channel.basic_publish(routing_key="test-requeue", content=Content("Two")) channel.basic_publish(routing_key="test-requeue", content=Content("Three")) channel.basic_publish(routing_key="test-requeue", content=Content("Four")) channel.basic_publish(routing_key="test-requeue", content=Content("Five")) msg1 = queue.get(timeout=1) msg2 = queue.get(timeout=1) msg3 = queue.get(timeout=1) msg4 = queue.get(timeout=1) msg5 = queue.get(timeout=1) self.assertEqual("One", msg1.content.body) self.assertEqual("Two", msg2.content.body) self.assertEqual("Three", msg3.content.body) self.assertEqual("Four", msg4.content.body) self.assertEqual("Five", msg5.content.body) channel.basic_ack(delivery_tag=msg2.delivery_tag, multiple=True) #One & Two channel.basic_ack(delivery_tag=msg4.delivery_tag, multiple=False) #Four channel.basic_cancel(consumer_tag=subscription.consumer_tag) channel.basic_recover(requeue=True) subscription2 = channel.basic_consume(queue="test-requeue") queue2 = self.client.queue(subscription2.consumer_tag) msg3b = queue2.get(timeout=1) msg5b = queue2.get(timeout=1) self.assertEqual("Three", msg3b.content.body) self.assertEqual("Five", msg5b.content.body) self.assertEqual(True, msg3b.redelivered) self.assertEqual(True, msg5b.redelivered) try: extra = queue2.get(timeout=1) self.fail("Got unexpected message in second queue: " + extra.content.body) except Empty: None try: extra = queue.get(timeout=1) self.fail("Got unexpected message in original queue: " + extra.content.body) except Empty: None
def test_large_message_received_in_many_content_frames(self): if self.client.conn.FRAME_MIN_SIZE == self.frame_max_size: raise Skipped( "Test requires that frame_max_size (%d) exceeds frame_min_size (%d)" % (self.frame_max_size, self.frame_max_size)) channel = self.channel queue_name = "q" self.queue_declare(queue=queue_name) channel.tx_select() body = self.randomLongString() channel.basic_publish(content=Content(body), routing_key=queue_name) channel.tx_commit() consuming_client = None try: # Create a second connection with minimum framesize. The Broker will then be forced to chunk # the content in order to send it to us. consuming_client = qpid.client.Client( self.config.broker.host, self.config.broker.port or self.DEFAULT_PORT) tune_params = {"frame_max": self.client.conn.FRAME_MIN_SIZE} consuming_client.start(username=self.config.broker.user or self.DEFAULT_USERNAME, password=self.config.broker.password or self.DEFAULT_PASSWORD, tune_params=tune_params) consuming_channel = consuming_client.channel(1) consuming_channel.channel_open() consuming_channel.tx_select() consumer_reply = consuming_channel.basic_consume(queue=queue_name, no_ack=False) consumer = consuming_client.queue(consumer_reply.consumer_tag) msg = consumer.get(timeout=self.recv_timeout()) consuming_channel.basic_ack(delivery_tag=msg.delivery_tag) consuming_channel.tx_commit() self.assertEqual(len(body), len(msg.content.body)) self.assertEqual(body, msg.content.body) finally: if consuming_client: consuming_client.close() def test_commit_ok_possibly_interleaved_with_message_delivery(self): """This test exposes an defect on the Java Broker (QPID-6094). The Java Broker (0.32 and below) can contravene the AMQP spec by sending other frames between the message header/frames. As this is a long standing defect in the Java Broker, QPID-6082 changed the Python client to allow it to tolerate such illegal interleaving. """ channel = self.channel queue_name = "q" self.queue_declare(queue=queue_name) count = 25 channel.basic_qos(prefetch_count=count) channel.tx_select() bodies = [] for i in range(count): body = self.randomLongString() bodies.append(body) channel.basic_publish(content=Content(bodies[i]), routing_key=queue_name) channel.tx_commit() # Start consuming. Prefetch will mean the Broker will start to send us # all the messages accumulating them in the client. consumer = self.consume("q", no_ack=False) # Get and ack/commit the first message msg = consumer.get(timeout=self.recv_timeout()) channel.basic_ack(delivery_tag=msg.delivery_tag) channel.tx_commit() # In the problematic case, the Broker interleaves our commit-ok response amongst the content # frames of message. QPID-6082 means the Python client now tolerates this # problem and all messages should arrive correctly. expectedBody = bodies[0] self.assertEqual(len(expectedBody), len(msg.content.body)) self.assertEqual(expectedBody, msg.content.body) for i in range(1, len(bodies)): msg = consumer.get(timeout=self.recv_timeout()) expectedBody = bodies[i] self.assertEqual(len(expectedBody), len(msg.content.body)) self.assertEqual(expectedBody, msg.content.body)
def test_example(self): """ An example test. Note that test functions must start with 'test_' to be recognized by the test framework. """ # By inheriting TestBase, self.client is automatically connected # and self.channel is automatically opened as channel(1) # Other channel methods mimic the protocol. channel = self.channel # Now we can send regular commands. If you want to see what the method # arguments mean or what other commands are available, you can use the # python builtin help() method. For example: #help(chan) #help(chan.exchange_declare) # If you want browse the available protocol methods without being # connected to a live server you can use the amqp-doc utility: # # Usage amqp-doc [<options>] <spec> [<pattern_1> ... <pattern_n>] # # Options: # -e, --regexp use regex instead of glob when matching # Now that we know what commands are available we can use them to # interact with the server. # Here we use ordinal arguments. self.exchange_declare(channel, 0, "test", "direct") # Here we use keyword arguments. self.queue_declare(channel, queue="test-queue") channel.queue_bind(queue="test-queue", exchange="test", routing_key="key") # Call Channel.basic_consume to register as a consumer. # All the protocol methods return a message object. The message object # has fields corresponding to the reply method fields, plus a content # field that is filled if the reply includes content. In this case the # interesting field is the consumer_tag. reply = channel.basic_consume(queue="test-queue") # We can use the Client.queue(...) method to access the queue # corresponding to our consumer_tag. queue = self.client.queue(reply.consumer_tag) # Now lets publish a message and see if our consumer gets it. To do # this we need to import the Content class. body = "Hello World!" channel.basic_publish(exchange="test", routing_key="key", content=Content(body)) # Now we'll wait for the message to arrive. We can use the timeout # argument in case the server hangs. By default queue.get() will wait # until a message arrives or the connection to the server dies. msg = queue.get(timeout=self.recv_timeout()) # And check that we got the right response with assertEqual self.assertEqual(body, msg.content.body) # Now acknowledge the message. channel.basic_ack(msg.delivery_tag, True)
def send_message(self, message, exchange='amq.topic', routing_key=''): self.conn.basic_publish(routing_key=routing_key, content=Content(message), exchange=exchange)
def myBasicPublish(self, headers): self.channel.basic_publish(exchange="amq.match", content=Content( "foobar", properties={'headers': headers}))