/*
* KeepAliveDaemonTest.java
*/
package org.activemq.transport.reliable;
import java.net.URI;
import javax.jms.JMSException;
import junit.framework.TestCase;
import org.activemq.io.impl.DefaultWireFormat;
import org.activemq.message.Packet;
import org.activemq.message.ReceiptHolder;
/**
* KeepAliveDaemonTest.java
*
*/
public class KeepAliveDaemonTest extends TestCase {
private boolean forced = false;
private boolean sent = false;
final long keepAliveTimeout = 1000L;
final long checkInterval = 500L;
protected class ReliableTransportChannelMock extends ReliableTransportChannel {
private boolean stopped = false;
protected long lastReceiptTime = 0;
protected ReliableTransportChannelMock() {
super(new DefaultWireFormat());
}
public ReceiptHolder asyncSendWithReceipt(Packet packet) throws JMSException {
sent = true;
return null;
}
public void forceDisconnect() {
forced = true;
}
public void start() throws JMSException {
}
public void stop() {
stopped = true;
}
public long getLastReceiptTimestamp() {
return lastReceiptTime;
}
public boolean isTransportConnected() {
return !stopped;
}
};
private void reset() {
sent = false;
forced = false;
}
public void testKeepAliveProperty() throws Exception {
long keepAliveTimeout = 373727;
ReliableTransportChannel ch = (ReliableTransportChannel) new ReliableTransportChannelFactory().create(new DefaultWireFormat(), new URI("vm://localhost:6144?keepAliveTimeout=" + keepAliveTimeout));
assertEquals(ch.getKeepAliveTimeout(), keepAliveTimeout);
}
public void testNoDisconnectOnChannelWithNoTimeout() throws Exception {
// Test on a connection that does not respond in time
ReliableTransportChannelMock channel = new ReliableTransportChannelMock() {
public long getLastReceiptTimestamp() {
return 0;
}
};
channel.setKeepAliveTimeout(0);
// Make sure it's timed out
channel.lastReceiptTime = System.currentTimeMillis();
KeepAliveDaemon d = new KeepAliveDaemon();
d.setCheckInterval(checkInterval);
d.addMonitoredChannel(channel);
d.start();
// Sleep so the daemon might disconnect the channel (it shouldn't)
reset();
Thread.sleep(checkInterval * 4);
assertFalse("No keep-alive should have been sent since the channel has a zero timeout.", sent);
assertFalse("Should not have been disconnected since channel has a zero timeout.", forced);
}
public void testNoDisconnectOnFreshChannel() throws Exception {
// Test on a connection that has a fresh timestamp
ReliableTransportChannelMock channel = new ReliableTransportChannelMock() {
public long getLastReceiptTimestamp() {
return System.currentTimeMillis();
}
};
channel.setKeepAliveTimeout(keepAliveTimeout);
KeepAliveDaemon d = new KeepAliveDaemon();
d.setCheckInterval(checkInterval);
d.addMonitoredChannel(channel);
d.start();
// Sleep so the daemon might disconnect the channel (it shouldn't)
reset();
Thread.sleep(checkInterval * 2);
assertFalse("No keep-alive should have been sent since this channel has a fresh timestamp.", sent);
assertFalse("Should NOT have been forced to disconnect.", forced);
}
public void testForcedDisconnect() throws Exception {
// Test on a connection that does not respond in time
final KeepAliveDaemon d = new KeepAliveDaemon();
ReliableTransportChannelMock channel = new ReliableTransportChannelMock() {
// Make sure it's timed out
public long getLastReceiptTimestamp() {
return d.getLastCheckTime() - keepAliveTimeout * 2 - 1;
}
};
channel.setKeepAliveTimeout(keepAliveTimeout);
// Make sure it's timed out
d.setCheckInterval(checkInterval);
d.addMonitoredChannel(channel);
d.start();
// Sleep so the daemon can flag the channel as a possible zombie suspect
// since it's
// timeout interval has expired
//Thread.sleep(checkInterval + (checkInterval / 2));
Thread.sleep(checkInterval);
assertTrue("KeepAlive packet should have been sent", sent);
assertFalse("Should NOT have been forced to disconnect yet.", forced);
// Now sleep another period to check that the channel is
// disconnected
reset();
Thread.sleep(checkInterval);
assertTrue("Should have been forced to disconnect.", forced);
}
public void testIdleChannelThatRespondsInTime() throws Exception {
// Test on a connection that initially is a zombie suspect but responds
// in time
ReliableTransportChannelMock channel = new ReliableTransportChannelMock();
channel.setKeepAliveTimeout(keepAliveTimeout);
// Make sure it's timed out
channel.lastReceiptTime = System.currentTimeMillis() - keepAliveTimeout;
KeepAliveDaemon d = new KeepAliveDaemon();
d.setCheckInterval(checkInterval);
d.addMonitoredChannel(channel);
d.start();
// Sleep so the daemon can flag the channel as a possible zombie suspect
// since it's
// timeout interval has expired
Thread.sleep(checkInterval + (checkInterval / 2));
assertTrue("KeepAlive packet should have been sent", sent);
assertFalse("Should NOT have been forced to disconnect yet.", forced);
// Now pretend that the channel has received a receipt for the
// keep-alive packet or something else
reset();
channel.lastReceiptTime = System.currentTimeMillis() + checkInterval;
Thread.sleep(checkInterval);
assertFalse("Should NOT have been forced to disconnect since the new timestamp is fresh enough.", forced);
}
public void testStoppedChannelsAreStoppedBeingMonitored() throws Exception {
// Test on a connection that does not respond in time
ReliableTransportChannelMock channel = new ReliableTransportChannelMock() {
public long getLastReceiptTimestamp() {
return 0;
}
};
channel.setKeepAliveTimeout(keepAliveTimeout);
// Make sure it's timed out
channel.lastReceiptTime = System.currentTimeMillis();
KeepAliveDaemon d = new KeepAliveDaemon();
d.setCheckInterval(checkInterval);
d.addMonitoredChannel(channel);
d.start();
channel.stop();
// Sleep so the daemon might disconnect the channel (it shouldn't)
Thread.sleep(checkInterval + (checkInterval / 2));
assertFalse("No keep-alive should have been sent since the channel is stopped.", sent);
assertFalse("Should NOT have been forced to disconnect.", forced);
}
}