// Copyright (c) 2007-Present Pivotal Software, Inc. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2 // ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see // LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL, // please see LICENSE-APACHE2. // // This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, // either express or implied. See the LICENSE file for specific language governing // rights and limitations of this software. // // If you have any questions regarding licensing, please contact us at // info@rabbitmq.com. package com.rabbitmq.client.test.functional; import static com.rabbitmq.client.test.functional.QosTests.drain; import java.io.IOException; import java.util.Arrays; import java.util.List; import org.junit.Test; import com.rabbitmq.client.GetResponse; import com.rabbitmq.client.QueueingConsumer; import com.rabbitmq.client.QueueingConsumer.Delivery; import com.rabbitmq.client.test.BrokerTestCase; public class PerConsumerPrefetch extends BrokerTestCase { private String q; @Override protected void createResources() throws IOException { q = channel.queueDeclare().getQueue(); } private interface Closure { public void makeMore(List<Delivery> deliveries) throws IOException; } @Test public void singleAck() throws IOException { testPrefetch(new Closure() { public void makeMore(List<Delivery> deliveries) throws IOException { for (Delivery del : deliveries) { ack(del, false); } } }); } @Test public void multiAck() throws IOException { testPrefetch(new Closure() { public void makeMore(List<Delivery> deliveries) throws IOException { ack(deliveries.get(deliveries.size() - 1), true); } }); } @Test public void singleNack() throws IOException { for (final boolean requeue: Arrays.asList(false, true)) { testPrefetch(new Closure() { public void makeMore(List<Delivery> deliveries) throws IOException { for (Delivery del : deliveries) { nack(del, false, requeue); } } }); } } @Test public void multiNack() throws IOException { for (final boolean requeue: Arrays.asList(false, true)) { testPrefetch(new Closure() { public void makeMore(List<Delivery> deliveries) throws IOException { nack(deliveries.get(deliveries.size() - 1), true, requeue); } }); } } @Test public void recover() throws IOException { testPrefetch(new Closure() { public void makeMore(List<Delivery> deliveries) throws IOException { channel.basicRecover(); } }); } private void testPrefetch(Closure closure) throws IOException { QueueingConsumer c = new QueueingConsumer(channel); publish(q, 15); consume(c, 5, false); List<Delivery> deliveries = drain(c, 5); ack(channel.basicGet(q, false), false); drain(c, 0); closure.makeMore(deliveries); drain(c, 5); } @Test public void prefetchOnEmpty() throws IOException { QueueingConsumer c = new QueueingConsumer(channel); publish(q, 5); consume(c, 10, false); drain(c, 5); publish(q, 10); drain(c, 5); } @Test public void autoAckIgnoresPrefetch() throws IOException { QueueingConsumer c = new QueueingConsumer(channel); publish(q, 10); consume(c, 1, true); drain(c, 10); } @Test public void prefetchZeroMeansInfinity() throws IOException { QueueingConsumer c = new QueueingConsumer(channel); publish(q, 10); consume(c, 0, false); drain(c, 10); } private void publish(String q, int n) throws IOException { for (int i = 0; i < n; i++) { channel.basicPublish("", q, null, "".getBytes()); } } private void consume(QueueingConsumer c, int prefetch, boolean autoAck) throws IOException { channel.basicQos(prefetch); channel.basicConsume(q, autoAck, c); } private void ack(Delivery del, boolean multi) throws IOException { channel.basicAck(del.getEnvelope().getDeliveryTag(), multi); } private void ack(GetResponse get, boolean multi) throws IOException { channel.basicAck(get.getEnvelope().getDeliveryTag(), multi); } private void nack(Delivery del, boolean multi, boolean requeue) throws IOException { channel.basicNack(del.getEnvelope().getDeliveryTag(), multi, requeue); } }