From a71032df95ea6fbac7c9edccc30c7a23d47697b9 Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Wed, 3 Oct 2012 17:06:13 +0200 Subject: [PATCH] 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. --- .../internal/BaseMonitoringServiceTest.java | 162 +++++++++++++----- 1 file changed, 121 insertions(+), 41 deletions(-) diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseMonitoringServiceTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseMonitoringServiceTest.java index 6d58677094..50264fe1f2 100644 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseMonitoringServiceTest.java +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseMonitoringServiceTest.java @@ -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 { private int finishAfterCount;