/* * Copyright (C) 2010 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.util.concurrent; import static org.junit.contrib.truth.Truth.ASSERT; import com.google.common.testing.NullPointerTester; import junit.framework.TestCase; import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; /** * Tests for ThreadFactoryBuilder. * * @author Kurt Alfred Kluever * @author Martin Buchholz */ public class ThreadFactoryBuilderTest extends TestCase { private final Runnable monitoredRunnable = new Runnable() { @Override public void run() { completed = true; } }; private static final UncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER = new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { // No-op } }; private ThreadFactoryBuilder builder; private volatile boolean completed = false; @Override public void setUp() { builder = new ThreadFactoryBuilder(); } public void testThreadFactoryBuilder_defaults() throws InterruptedException { ThreadFactory threadFactory = builder.build(); Thread thread = threadFactory.newThread(monitoredRunnable); checkThreadPoolName(thread, 1); Thread defaultThread = Executors.defaultThreadFactory().newThread(monitoredRunnable); assertEquals(defaultThread.isDaemon(), thread.isDaemon()); assertEquals(defaultThread.getPriority(), thread.getPriority()); assertSame(defaultThread.getThreadGroup(), thread.getThreadGroup()); assertSame(defaultThread.getUncaughtExceptionHandler(), thread.getUncaughtExceptionHandler()); assertFalse(completed); thread.start(); thread.join(); assertTrue(completed); // Creating a new thread from the same ThreadFactory will have the same // pool ID but a thread ID of 2. Thread thread2 = threadFactory.newThread(monitoredRunnable); checkThreadPoolName(thread2, 2); assertEquals( thread.getName().substring(0, thread.getName().lastIndexOf('-')), thread2.getName().substring(0, thread.getName().lastIndexOf('-'))); // Building again should give us a different pool ID. ThreadFactory threadFactory2 = builder.build(); Thread thread3 = threadFactory2.newThread(monitoredRunnable); checkThreadPoolName(thread3, 1); ASSERT.that( thread2.getName().substring(0, thread.getName().lastIndexOf('-'))) .isNotEqualTo( thread3.getName().substring(0, thread.getName().lastIndexOf('-'))); } private static void checkThreadPoolName(Thread thread, int threadId) { assertTrue(thread.getName().matches("^pool-\\d+-thread-" + threadId + "$")); } public void testNameFormat_custom() { final String NAME_FORMAT = "super duper thread #%s"; ThreadFactory factory = builder.setNameFormat(NAME_FORMAT).build(); for (int i = 0; i < 10; i++) { assertEquals(String.format(NAME_FORMAT, i), factory.newThread(monitoredRunnable).getName()); } } public void testDaemon_false() { ThreadFactory factory = builder.setDaemon(false).build(); Thread thread = factory.newThread(monitoredRunnable); assertFalse(thread.isDaemon()); } public void testDaemon_true() { ThreadFactory factory = builder.setDaemon(true).build(); Thread thread = factory.newThread(monitoredRunnable); assertTrue(thread.isDaemon()); } public void testPriority_custom() { for (int i = Thread.MIN_PRIORITY; i <= Thread.MAX_PRIORITY; i++) { ThreadFactory factory = builder.setPriority(i).build(); Thread thread = factory.newThread(monitoredRunnable); assertEquals(i, thread.getPriority()); } } public void testPriority_tooLow() { try { builder.setPriority(Thread.MIN_PRIORITY - 1); fail(); } catch (IllegalArgumentException expected) { } } public void testPriority_tooHigh() { try { builder.setPriority(Thread.MAX_PRIORITY + 1); fail(); } catch (IllegalArgumentException expected) { } } public void testUncaughtExceptionHandler_custom() { assertEquals(UNCAUGHT_EXCEPTION_HANDLER, builder.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER).build() .newThread(monitoredRunnable).getUncaughtExceptionHandler()); } public void testBuildMutateBuild() { ThreadFactory factory1 = builder.setPriority(1).build(); assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); ThreadFactory factory2 = builder.setPriority(2).build(); assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); assertEquals(2, factory2.newThread(monitoredRunnable).getPriority()); } public void testBuildTwice() { builder.build(); // this is allowed builder.build(); // this is *also* allowed } public void testBuildMutate() { ThreadFactory factory1 = builder.setPriority(1).build(); assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); builder.setPriority(2); // change the state of the builder assertEquals(1, factory1.newThread(monitoredRunnable).getPriority()); } public void testThreadFactory() throws InterruptedException { final String THREAD_NAME = "ludicrous speed"; final int THREAD_PRIORITY = 1; final boolean THREAD_DAEMON = false; ThreadFactory backingThreadFactory = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName(THREAD_NAME); thread.setPriority(THREAD_PRIORITY); thread.setDaemon(THREAD_DAEMON); thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER); return thread; } }; Thread thread = builder.setThreadFactory(backingThreadFactory).build() .newThread(monitoredRunnable); assertEquals(THREAD_NAME, thread.getName()); assertEquals(THREAD_PRIORITY, thread.getPriority()); assertEquals(THREAD_DAEMON, thread.isDaemon()); assertSame(UNCAUGHT_EXCEPTION_HANDLER, thread.getUncaughtExceptionHandler()); assertSame(Thread.State.NEW, thread.getState()); assertFalse(completed); thread.start(); thread.join(); assertTrue(completed); } public void testNulls() throws Exception { NullPointerTester npTester = new NullPointerTester(); npTester.testAllPublicConstructors(ThreadFactoryBuilder.class); npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class); npTester.testAllPublicInstanceMethods(builder); } }