// 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 org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Test; import com.rabbitmq.client.GetResponse; import com.rabbitmq.client.test.BrokerTestCase; /** * Test queue max length limit. */ public class QueueSizeLimit extends BrokerTestCase { private final int MAXMAXLENGTH = 3; private final String q = "queue-maxlength"; @Test public void queueSize() throws IOException, InterruptedException { for (int maxLen = 0; maxLen <= MAXMAXLENGTH; maxLen ++){ setupNonDlxTest(maxLen, false); assertHead(maxLen, "msg2", q); deleteQueue(q); } } @Test public void queueSizeUnacked() throws IOException, InterruptedException { for (int maxLen = 0; maxLen <= MAXMAXLENGTH; maxLen ++){ setupNonDlxTest(maxLen, true); assertHead(maxLen > 0 ? 1 : 0, "msg" + (maxLen + 1), q); deleteQueue(q); } } @Test public void queueSizeDlx() throws IOException, InterruptedException { for (int maxLen = 0; maxLen <= MAXMAXLENGTH; maxLen ++){ setupDlxTest(maxLen, false); assertHead(1, "msg1", "DLQ"); deleteQueue(q); deleteQueue("DLQ"); } } @Test public void queueSizeUnackedDlx() throws IOException, InterruptedException { for (int maxLen = 0; maxLen <= MAXMAXLENGTH; maxLen ++){ setupDlxTest(maxLen, true); assertHead(maxLen > 0 ? 0 : 1, "msg1", "DLQ"); deleteQueue(q); deleteQueue("DLQ"); } } @Test public void requeue() throws IOException, InterruptedException { for (int maxLen = 1; maxLen <= MAXMAXLENGTH; maxLen ++) { declareQueue(maxLen, false); setupRequeueTest(maxLen); assertHead(maxLen, "msg1", q); deleteQueue(q); } } @Test public void requeueWithDlx() throws IOException, InterruptedException { for (int maxLen = 1; maxLen <= MAXMAXLENGTH; maxLen ++) { declareQueue(maxLen, true); setupRequeueTest(maxLen); assertHead(maxLen, "msg1", q); assertHead(maxLen, "msg1", "DLQ"); deleteQueue(q); deleteQueue("DLQ"); } } private void setupNonDlxTest(int maxLen, boolean unAcked) throws IOException, InterruptedException { declareQueue(maxLen, false); fill(maxLen); if (unAcked) getUnacked(maxLen); publish("msg" + (maxLen + 1)); } private void setupDlxTest(int maxLen, boolean unAcked) throws IOException, InterruptedException { declareQueue(maxLen, true); fill(maxLen); if (unAcked) getUnacked(maxLen); publish("msg" + (maxLen + 1)); try { Thread.sleep(100); } catch (InterruptedException _e) { } } private void setupRequeueTest(int maxLen) throws IOException, InterruptedException { fill(maxLen); List<Long> tags = getUnacked(maxLen); fill(maxLen); channel.basicNack(tags.get(0), false, true); if (maxLen > 1) channel.basicNack(tags.get(maxLen - 1), true, true); } private void declareQueue(int maxLen, boolean dlx) throws IOException { Map<String, Object> args = new HashMap<String, Object>(); args.put("x-max-length", maxLen); if (dlx) { args.put("x-dead-letter-exchange", "amq.fanout"); channel.queueDeclare("DLQ", false, true, false, null); channel.queueBind("DLQ", "amq.fanout", ""); } channel.queueDeclare(q, false, true, true, args); } private void fill(int count) throws IOException, InterruptedException { for (int i=1; i <= count; i++){ publish("msg" + i); } } private void publish(String payload) throws IOException, InterruptedException { basicPublishVolatile(payload.getBytes(), q); } private void assertHead(int expectedLength, String expectedHeadPayload, String queueName) throws IOException { GetResponse head = channel.basicGet(queueName, true); if (expectedLength > 0) { assertNotNull(head); assertEquals(expectedHeadPayload, new String(head.getBody())); assertEquals(expectedLength, head.getMessageCount() + 1); } else { assertNull(head); } } private List<Long> getUnacked(int howMany) throws IOException { List<Long> tags = new ArrayList<Long>(howMany); for (;howMany > 0; howMany --) { GetResponse response = channel.basicGet(q, false); tags.add(response.getEnvelope().getDeliveryTag()); } return tags; } }