/* * Copyright (c) 2008-2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.services.util; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class NamedThreadPoolExecutorTest { private static final Logger logger = LoggerFactory.getLogger(NamedThreadPoolExecutorTest.class); class MyCallable implements Callable<String> { /** * @return the name of the thread that executes this callable */ @Override public String call() throws Exception { return Thread.currentThread().getName(); } } class MyTask implements Runnable { private String name = ""; @Override public void run() { try { setName(Thread.currentThread().getName()); System.out.println("Name=" + name); Thread.sleep(1000L); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Test public void testNamedExecutorWithoutAppendedTask() throws Exception { String poolName = "David Webber's web"; NamedThreadPoolExecutor executor = new NamedThreadPoolExecutor(poolName, 1); Assert.assertTrue("Thread pool appendTaskName flag should have been false.", executor.isAppendTaskName() == false); Runnable worker = new MyTask(); executor.execute(worker); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); // task name should not be appended String threadName = ((MyTask) worker).getName(); Assert.assertTrue(String.format("Thread name '%s' does not contain pool name '%s'", threadName, poolName), threadName.indexOf(poolName) > -1); Assert.assertFalse(String.format("Thread name '%s' should not contain task name '%s'", threadName, poolName), threadName.indexOf(MyTask.class.getSimpleName()) > 0); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedExecutorWithAppendedTask() throws Exception { String poolName = "David Webber's web"; NamedThreadPoolExecutor executor = new NamedThreadPoolExecutor(poolName, 2); executor.setAppendTaskName(true); Assert.assertTrue("Thread pool appendTaskName flag should have been on.", executor.isAppendTaskName() == true); MyTask worker = new MyTask(); executor.execute(worker); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); // task name should be appended String threadName = ((MyTask) worker).getName(); Assert.assertTrue(String.format("Thread name '%s' does not contain pool name '%s'", threadName, poolName), threadName.indexOf(poolName) > -1); Assert.assertTrue(String.format("Thread name '%s' does not contain task name '%s'", threadName, poolName), threadName.indexOf(MyTask.class.getSimpleName()) > -1); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedExecutorWithAppendedAnonymousTask() throws Exception { String poolName = "David Webber's web"; NamedThreadPoolExecutor executor = new NamedThreadPoolExecutor(poolName, 2); executor.setAppendTaskName(true); Assert.assertTrue("Thread pool appendTaskName flag should have been on.", executor.isAppendTaskName() == true); final StringBuilder runtimeThreadName = new StringBuilder(); executor.execute(new Runnable() { @Override public void run() { runtimeThreadName.append(Thread.currentThread().getName()); } }); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); // verify the name has changed Assert.assertTrue( "Thread name does not reflect anonymous task: " + runtimeThreadName.toString(), runtimeThreadName.toString().indexOf(NamedThreadPoolHelper.ANONYMOUS_NAME) > -1); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedScheduledExecutorWithAppendedTask() throws Exception { String poolName = "David Webber's web"; ScheduledThreadPoolExecutor executor = new NamedScheduledThreadPoolExecutor(poolName, 1); ((NamedScheduledThreadPoolExecutor) executor).setAppendTaskName(true); Assert.assertTrue("Thread pool appendTaskName flag should have been on.", ((NamedScheduledThreadPoolExecutor) executor).isAppendTaskName() == true); for (int i = 0; i < 2; i++) { MyCallable worker = new MyCallable(); String threadName = executor.schedule(worker, 1L, TimeUnit.SECONDS).get(); Assert.assertTrue(String.format("Thread name '%s' does not contain pool name '%s'", threadName, poolName), threadName.indexOf(poolName) > -1); Assert.assertTrue(String.format("Thread name '%s' does not contain task name '%s'", threadName, poolName), threadName.indexOf(MyCallable.class.getSimpleName()) > -1); } executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedScheduledExecutorWithoutAppendedTask() throws Exception { String poolName = "David Webber's web"; ScheduledThreadPoolExecutor executor = new NamedScheduledThreadPoolExecutor(poolName, 1); for (int i = 0; i < 2; i++) { MyCallable worker = new MyCallable(); String threadName = executor.schedule(worker, 1L, TimeUnit.SECONDS).get(); Assert.assertTrue(String.format("Thread name '%s' does not contain pool name '%s'", threadName, poolName), threadName.indexOf(poolName) > -1); Assert.assertFalse(String.format("Thread name '%s' should not contain pool name '%s'", threadName, poolName), threadName.indexOf(MyCallable.class.getSimpleName()) > -1); } executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedExecutorThreadNameChangesDuringRun() throws Exception { String poolName = "David Webber's web"; NamedThreadPoolExecutor executor = new NamedThreadPoolExecutor(poolName, 2); executor.setAppendTaskName(true); Assert.assertTrue("Thread pool appendTaskName flag should have been on.", executor.isAppendTaskName() == true); Future<String> futureThreadName = executor.submit(new MyCallable()); String threadName = futureThreadName.get(); Assert.assertTrue( "Thread Name does not match the base + number ::task pattern during execution: " + threadName, threadName.matches(poolName + "_\\d+::" + MyCallable.class.getSimpleName())); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedScheduledExecutorThreadNameChangesDuringRun() throws Exception { String poolName = "David Webber's web"; NamedScheduledThreadPoolExecutor executor = new NamedScheduledThreadPoolExecutor(poolName, 2); executor.setAppendTaskName(true); Assert.assertTrue("Thread pool appendTaskName flag should have been on.", executor.isAppendTaskName() == true); Future<String> futureThreadName = executor.submit(new MyCallable()); String threadName = futureThreadName.get(); Assert.assertTrue( "Thread Name does not match the base + number ::task pattern during execution: " + threadName, threadName.matches(poolName + "_\\d+::" + MyCallable.class.getSimpleName())); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); if (!executor.isTerminated()) { executor.shutdownNow(); } } @Test public void testNamedExecutorThreadNameRevertsAfterRun() throws Exception { String poolName = "David Webber's web"; NamedThreadPoolExecutor executor = new NamedThreadPoolExecutor(poolName, 2); executor.setAppendTaskName(true); Assert.assertTrue("Thread pool appendTaskName flag should have been on.", executor.isAppendTaskName() == true); Future<Thread> futureThread = executor.submit(new Callable<Thread>() { @Override public Thread call() { return Thread.currentThread(); } }); Thread t = futureThread.get(); TimeUnit.SECONDS.sleep(1); String nameAfter = t.getName(); Assert.assertTrue("Thread name does not revert to base name after execution: " + nameAfter, nameAfter.matches(poolName + "_\\d+")); executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); if (!executor.isTerminated()) { executor.shutdownNow(); } } }