Refactored unit tests to avoid recurrent timeouts.

When using TestNG timeout option to control test execution, random
timeout failures appeared. The tests have been refactored to manually
control the timeout.
This commit is contained in:
Ignasi Barrera 2012-10-03 17:06:13 +02:00
parent 99d3422b4d
commit a71032df95
1 changed files with 121 additions and 41 deletions

View File

@ -22,9 +22,14 @@ package org.jclouds.abiquo.internal;
import static org.jclouds.abiquo.config.AbiquoProperties.ASYNC_TASK_MONITOR_DELAY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.abiquo.events.handlers.BlockingEventHandler;
import org.jclouds.abiquo.events.monitor.MonitorEvent;
@ -40,12 +45,18 @@ import com.google.common.base.Function;
* @author Ignasi Barrera
*/
// Since these tests block the thread, mark them as failed after the given timeout
@Test(groups = "unit", testName = "BaseMonitoringServiceTest", timeOut = 10000L)
@Test(groups = "unit", testName = "BaseMonitoringServiceTest")
public class BaseMonitoringServiceTest extends BaseInjectionTest
{
// The maximum amount of time (in ms) to wait for each test to complete
private static final long TEST_TIMEOUT = 10000L;
// The polling interval used in tests (in ms)
private static final long TEST_MONITOR_POLLING = 100L;
// An executor used to control monitor unexpected timeouts
private ExecutorService executor = Executors.newSingleThreadExecutor();
@Override
protected Properties buildProperties()
{
@ -83,14 +94,34 @@ public class BaseMonitoringServiceTest extends BaseInjectionTest
public void testAwaitCompletion()
{
BaseMonitoringService service = monitoringService();
service.awaitCompletion(new MockMonitor(), new Object());
final BaseMonitoringService service = monitoringService();
Future< ? > future = executor.submit(new Runnable()
{
@Override
public void run()
{
service.awaitCompletion(new MockMonitor(), new Object());
}
});
waitForResultOrTimeout(future);
}
public void testAwaitCompletionMultipleTasks()
{
BaseMonitoringService service = monitoringService();
service.awaitCompletion(new MockMonitor(), new Object(), new Object());
final BaseMonitoringService service = monitoringService();
Future< ? > future = executor.submit(new Runnable()
{
@Override
public void run()
{
service.awaitCompletion(new MockMonitor(), new Object(), new Object());
}
});
waitForResultOrTimeout(future);
}
@Test(expectedExceptions = NullPointerException.class)
@ -107,16 +138,23 @@ public class BaseMonitoringServiceTest extends BaseInjectionTest
public void testMonitor()
{
BaseMonitoringService service = monitoringService();
final BaseMonitoringService service = monitoringService();
final Object monitoredObject = new Object();
final CountingHandler handler = new CountingHandler(monitoredObject);
Object monitoredObject = new Object();
CountingHandler handler = new CountingHandler(monitoredObject);
service.register(handler);
Future< ? > future = executor.submit(new Runnable()
{
@Override
public void run()
{
service.register(handler);
service.monitor(new MockMonitor(), monitoredObject);
handler.lock();
service.unregister(handler);
}
});
service.monitor(new MockMonitor(), monitoredObject);
handler.lock();
service.unregister(handler);
waitForResultOrTimeout(future);
assertEquals(handler.numCompletes, 1);
assertEquals(handler.numFailures, 0);
@ -125,17 +163,24 @@ public class BaseMonitoringServiceTest extends BaseInjectionTest
public void testMonitorMultipleTasks()
{
BaseMonitoringService service = monitoringService();
final BaseMonitoringService service = monitoringService();
final Object monitoredObject1 = new Object();
final Object monitoredObject2 = new Object();
final CountingHandler handler = new CountingHandler(monitoredObject1, monitoredObject2);
Object monitoredObject1 = new Object();
Object monitoredObject2 = new Object();
CountingHandler handler = new CountingHandler(monitoredObject1, monitoredObject2);
service.register(handler);
Future< ? > future = executor.submit(new Runnable()
{
@Override
public void run()
{
service.register(handler);
service.monitor(new MockMonitor(), monitoredObject1, monitoredObject2);
handler.lock();
service.unregister(handler);
}
});
service.monitor(new MockMonitor(), monitoredObject1, monitoredObject2);
handler.lock();
service.unregister(handler);
waitForResultOrTimeout(future);
assertEquals(handler.numCompletes, 2);
assertEquals(handler.numFailures, 0);
@ -144,17 +189,24 @@ public class BaseMonitoringServiceTest extends BaseInjectionTest
public void testMonitorReachesTimeout()
{
BaseMonitoringService service = monitoringService();
final BaseMonitoringService service = monitoringService();
final Object monitoredObject = new Object();
final CountingHandler handler = new CountingHandler(monitoredObject);
Object monitoredObject = new Object();
CountingHandler handler = new CountingHandler(monitoredObject);
service.register(handler);
Future< ? > future = executor.submit(new Runnable()
{
@Override
public void run()
{
service.register(handler);
service.monitor(TEST_MONITOR_POLLING + 10L, TimeUnit.MILLISECONDS,
new MockInfiniteMonitor(), monitoredObject);
handler.lock();
service.unregister(handler);
}
});
service.monitor(TEST_MONITOR_POLLING + 10L, TimeUnit.MILLISECONDS,
new MockInfiniteMonitor(), monitoredObject);
handler.lock();
service.unregister(handler);
waitForResultOrTimeout(future);
assertEquals(handler.numCompletes, 0);
assertEquals(handler.numFailures, 0);
@ -163,18 +215,25 @@ public class BaseMonitoringServiceTest extends BaseInjectionTest
public void testMonitorMultipleTasksReachesTimeout()
{
BaseMonitoringService service = monitoringService();
final BaseMonitoringService service = monitoringService();
final Object monitoredObject1 = new Object();
final Object monitoredObject2 = new Object();
final CountingHandler handler = new CountingHandler(monitoredObject1, monitoredObject2);
Object monitoredObject1 = new Object();
Object monitoredObject2 = new Object();
CountingHandler handler = new CountingHandler(monitoredObject1, monitoredObject2);
service.register(handler);
Future< ? > future = executor.submit(new Runnable()
{
@Override
public void run()
{
service.register(handler);
service.monitor(TEST_MONITOR_POLLING + 10L, TimeUnit.MILLISECONDS,
new MockInfiniteMonitor(), monitoredObject1, monitoredObject2);
handler.lock();
service.unregister(handler);
}
});
service.monitor(TEST_MONITOR_POLLING + 10L, TimeUnit.MILLISECONDS,
new MockInfiniteMonitor(), monitoredObject1, monitoredObject2);
handler.lock();
service.unregister(handler);
waitForResultOrTimeout(future);
assertEquals(handler.numCompletes, 0);
assertEquals(handler.numFailures, 0);
@ -196,11 +255,32 @@ public class BaseMonitoringServiceTest extends BaseInjectionTest
assertNotNull(monitoringService().getAsyncTaskMonitor());
}
public void testDelegateToConversioMonitor()
{
assertNotNull(monitoringService().getConversionMonitor());
}
private BaseMonitoringService monitoringService()
{
return injector.getInstance(BaseMonitoringService.class);
}
private void waitForResultOrTimeout(final Future< ? > future)
{
try
{
future.get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
}
catch (TimeoutException ex)
{
fail("Test didn't finish within the timeout " + TEST_TIMEOUT);
}
catch (Exception ex)
{
fail("Failed to process the asynchronous task");
}
}
private static class MockMonitor implements Function<Object, MonitorStatus>
{
private int finishAfterCount;