package org.yajul.util;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.yajul.concurrent.HeartbeatMonitor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.yajul.concurrent.HeartbeatMonitor.Status.*;
/**
* Hearbeat monitor unit test
* <br>User: Josh
* Date: Mar 5, 2009
* Time: 7:50:36 AM
*/
public class HeartbeatMonitorTest extends TestCase
{
private final static Logger log = Logger.getLogger(HeartbeatMonitorTest.class.getName());
public HeartbeatMonitorTest(String n)
{
super(n);
}
public void testMonitor() throws InterruptedException
{
ExecutorService exec = Executors.newCachedThreadPool();
int scanInterval = 100;
MockObserver observer = new MockObserver();
HeartbeatMonitor monitor = new HeartbeatMonitor(scanInterval, exec, observer);
int suspectTimeout = 20 * scanInterval;
int failureTimeout = 30 * scanInterval;
int fudgeFactor = 10; // Slight delay to ensure a complete scan.
monitor.createMonitor("one", suspectTimeout, failureTimeout);
assertEquals(CREATED, observer.getStatus("one"));
Thread.sleep(suspectTimeout + scanInterval + fudgeFactor);
assertEquals(SUSPECTED, observer.getStatus("one"));
Thread.sleep((failureTimeout - suspectTimeout) + 2 * scanInterval + fudgeFactor);
assertEquals(FAILED, observer.getStatus("one"));
monitor.heartbeat("one");
assertEquals(RESTORED, observer.getStatus("one"));
monitor.removeMonitor("one");
monitor.createMonitor("two", 0, 10 * scanInterval);
assertEquals(CREATED, observer.getStatus("two"));
for (int i = 0; i < 20; i++)
{
Thread.sleep(scanInterval);
monitor.heartbeat("two");
assertEquals(CREATED, observer.getStatus("two"));
}
monitor.clear();
assertEquals(CANCELED, observer.getStatus("two"));
}
public void testMonitorRemove()
{
// Make sure we don't NPE when removing the last monitor.
ExecutorService exec = Executors.newCachedThreadPool();
int scanInterval = 100;
MockObserver observer = new MockObserver();
HeartbeatMonitor monitor = new HeartbeatMonitor(scanInterval, exec, observer);
int suspectTimeout = 20 * scanInterval;
int failureTimeout = 30 * scanInterval;
monitor.removeMonitor("one");
monitor.heartbeat("one");
monitor.createMonitor("one", suspectTimeout, failureTimeout);
monitor.removeMonitor("one");
}
public static Test suite()
{
return new TestSuite(HeartbeatMonitorTest.class);
}
private static class MockObserver implements HeartbeatMonitor.HeartbeatObserver
{
private Map<String, HeartbeatMonitor.Status> statusById = new HashMap<String, HeartbeatMonitor.Status>();
public HeartbeatMonitor.Timeouts getDefaultTimeouts(String id)
{
return new HeartbeatMonitor.Timeouts(1000, 3000);
}
public void onEvent(String id, HeartbeatMonitor.Status status, long lastHeartbeat)
{
Date last = new Date(lastHeartbeat);
DateFormat df = new SimpleDateFormat(DateFormatConstants.ISO8601_DATETIME_FORMAT);
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, "onEvent() : id=" + id + " status=" + status + " last=" + df.format(last));
synchronized (this)
{
statusById.put(id, status);
}
}
public HeartbeatMonitor.Status getStatus(String id)
{
synchronized (this)
{
return statusById.get(id);
}
}
}
}