Fix unstable FixedThreadPoolConfigBeanTest 47/7747/2
authorTomas Olvecky <tolvecky@cisco.com>
Thu, 5 Jun 2014 16:03:17 +0000 (18:03 +0200)
committerTomas Olvecky <tolvecky@cisco.com>
Fri, 6 Jun 2014 07:06:23 +0000 (09:06 +0200)
Test was failing because threads were not cleaned
up right after the thread pool was shut down. Test now
waits up to 60 seconds before failing on threads
that should have been destroyed.

Change-Id: Ie9ac856007772f39426dbcbb2af0fb66226fc2c0
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java

index af7f01a6327529521dfd70e5230c4155605919c5..62b295be8d1c53e8b648f7c352ab9b0c5244e875 100644 (file)
@@ -7,12 +7,16 @@
  */
 package org.opendaylight.controller.config.threadpool.fixed;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.matchers.JUnitMatchers.containsString;
 
 import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.ArrayList;
+import java.util.List;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
@@ -28,8 +32,11 @@ import org.opendaylight.controller.config.yang.threadpool.impl.NamingThreadFacto
 import org.opendaylight.controller.config.yang.threadpool.impl.NamingThreadFactoryModuleMXBean;
 import org.opendaylight.controller.config.yang.threadpool.impl.fixed.FixedThreadPoolModuleFactory;
 import org.opendaylight.controller.config.yang.threadpool.impl.fixed.FixedThreadPoolModuleMXBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
+    private static final Logger logger = LoggerFactory.getLogger(FixedThreadPoolConfigBeanTest.class);
 
     private FixedThreadPoolModuleFactory factory;
     private final String nameInstance = "fixedInstance";
@@ -37,7 +44,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
     @Before
     public void setUp() {
         factory = new FixedThreadPoolModuleFactory();
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory,
                 new NamingThreadFactoryModuleFactory()));
     }
 
@@ -45,7 +52,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
     public void testCreateBean() throws InstanceAlreadyExistsException, ValidationException,
             ConflictingVersionException {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createFixed(transaction, nameInstance, 2);
+        createFixed(transaction, nameInstance, 2, nameInstance);
 
         transaction.validateConfig();
         CommitStatus status = transaction.commit();
@@ -58,7 +65,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
     public void testReusingOldInstance() throws InstanceAlreadyExistsException, ConflictingVersionException,
             ValidationException {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createFixed(transaction, nameInstance, 4);
+        createFixed(transaction, nameInstance, 4, nameInstance);
 
         transaction.validateConfig();
         transaction.commit();
@@ -76,12 +83,12 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
     public void testNegative() throws ConflictingVersionException, ValidationException, InstanceAlreadyExistsException {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
 
-        createFixed(transaction, nameInstance, 5);
+        createFixed(transaction, nameInstance, 5, nameInstance);
         transaction.commit();
 
         transaction = configRegistryClient.createTransaction();
         try {
-            createFixed(transaction, nameInstance, 0);
+            createFixed(transaction, nameInstance, 0, nameInstance);
             fail();
         } catch (InstanceAlreadyExistsException e) {
             assertThat(
@@ -90,18 +97,35 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
         }
     }
 
+    private int countThreadsByPrefix(String prefix) {
+        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+        int result = 0;
+        List<String> names = new ArrayList<>();
+        for (ThreadInfo threadInfo : threadMXBean.dumpAllThreads(false, false)) {
+            names.add(threadInfo.getThreadName());
+            if (threadInfo.getThreadName().startsWith(prefix)) {
+                result++;
+            }
+        }
+        logger.info("Current threads {}", names);
+        return result;
+    }
+
     @Test
     public void testDestroy() throws InstanceAlreadyExistsException, ValidationException, ConflictingVersionException,
-            InstanceNotFoundException {
+            InstanceNotFoundException, InterruptedException {
+
+        String prefix = org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(10);
 
         int numberOfThreads = 100;
-        int threadCount1 = ManagementFactory.getThreadMXBean().getThreadCount();
-        assertTrue("Expected less than " + numberOfThreads + " threads, got " + threadCount1, threadCount1 < numberOfThreads);
+        int threadCount1 = countThreadsByPrefix(prefix);
+        assertEquals(0, threadCount1);
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createFixed(transaction, nameInstance, numberOfThreads);
+
+        createFixed(transaction, nameInstance, numberOfThreads, prefix);
         transaction.commit();
-        int threadCount2 = ManagementFactory.getThreadMXBean().getThreadCount();
-        assertTrue("Expected more than " + numberOfThreads + " threads, got " + threadCount2, threadCount2 > numberOfThreads);
+        int threadCount2 = countThreadsByPrefix(prefix);
+        assertEquals(numberOfThreads, threadCount2);
 
         transaction = configRegistryClient.createTransaction();
         transaction.destroyModule(factory.getImplementationName(), nameInstance);
@@ -109,14 +133,20 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
 
         assertBeanCount(0, factory.getImplementationName());
         assertStatus(status, 0, 0, 1);
-        int threadCount3 = ManagementFactory.getThreadMXBean().getThreadCount();
-        assertTrue("Expected less than " + numberOfThreads + " threads, got " + threadCount3, threadCount3 < numberOfThreads);
+
+        for (int i = 0; i < 60; i++) {
+            if (countThreadsByPrefix(prefix) == 0) {
+                return;
+            }
+            Thread.sleep(1000);
+        }
+        assertEquals(0, countThreadsByPrefix(prefix));
     }
 
     @Test
     public void testValidationException() throws InstanceAlreadyExistsException {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createFixed(transaction, nameInstance, -1);
+        createFixed(transaction, nameInstance, -1, nameInstance);
         try {
             transaction.validateConfig();
             fail();
@@ -125,7 +155,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
         }
     }
 
-    private ObjectName createFixed(ConfigTransactionJMXClient transaction, String name, int numberOfThreads)
+    private ObjectName createFixed(ConfigTransactionJMXClient transaction, String name, int numberOfThreads, String prefix)
             throws InstanceAlreadyExistsException {
         ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), name);
         FixedThreadPoolModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, FixedThreadPoolModuleMXBean.class);
@@ -134,7 +164,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
         ObjectName threadFactoryON = transaction.createModule(NamingThreadFactoryModuleFactory.NAME, "naming");
         NamingThreadFactoryModuleMXBean namingThreadFactoryModuleMXBean = transaction.newMXBeanProxy(threadFactoryON,
                 NamingThreadFactoryModuleMXBean.class);
-        namingThreadFactoryModuleMXBean.setNamePrefix("prefix");
+        namingThreadFactoryModuleMXBean.setNamePrefix(prefix);
 
         mxBean.setThreadFactory(threadFactoryON);