// 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.server;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import org.junit.Test;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.test.BrokerTestCase;
public class MemoryAlarms extends BrokerTestCase {
private static final String Q = "Restart";
private Connection connection2;
private Channel channel2;
@Override
public void setUp() throws IOException, TimeoutException {
connectionFactory.setRequestedHeartbeat(1);
super.setUp();
if (connection2 == null) {
connection2 = connectionFactory.newConnection();
}
channel2 = connection2.createChannel();
}
@Override
public void tearDown() throws IOException, TimeoutException {
if (channel2 != null) {
channel2.abort();
channel2 = null;
}
if (connection2 != null) {
connection2.abort();
connection2 = null;
}
super.tearDown();
connectionFactory.setRequestedHeartbeat(0);
}
@Override
protected void createResources() throws IOException {
channel.queueDeclare(Q, false, false, false, null);
}
@Override
protected void releaseResources() throws IOException {
try {
clearAllResourceAlarms();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
channel.queueDelete(Q);
}
}
@Test public void flowControl() throws IOException, InterruptedException {
basicPublishVolatile(Q);
setResourceAlarm("memory");
// non-publish actions only after an alarm should be fine
assertNotNull(basicGet(Q));
QueueingConsumer c = new QueueingConsumer(channel);
String consumerTag = channel.basicConsume(Q, true, c);
// publishes after an alarm should not go through
basicPublishVolatile(Q);
// the publish is async, so this is racy. This also tests we don't die
// by heartbeat (3x heartbeat interval + epsilon)
assertNull(c.nextDelivery(3100));
// once the alarm has cleared the publishes should go through
clearResourceAlarm("memory");
assertNotNull(c.nextDelivery(3100));
// everything should be back to normal
channel.basicCancel(consumerTag);
basicPublishVolatile(Q);
assertNotNull(basicGet(Q));
}
@Test public void overlappingAlarmsFlowControl() throws IOException, InterruptedException {
QueueingConsumer c = new QueueingConsumer(channel);
String consumerTag = channel.basicConsume(Q, true, c);
setResourceAlarm("memory");
basicPublishVolatile(Q);
assertNull(c.nextDelivery(100));
setResourceAlarm("disk");
assertNull(c.nextDelivery(100));
clearResourceAlarm("memory");
assertNull(c.nextDelivery(100));
clearResourceAlarm("disk");
assertNotNull(c.nextDelivery(3100));
channel.basicCancel(consumerTag);
basicPublishVolatile(Q);
assertNotNull(basicGet(Q));
}
}