• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.util.concurrent;
18 
19 import static org.junit.contrib.truth.Truth.ASSERT;
20 
21 import com.google.common.testing.NullPointerTester;
22 
23 import junit.framework.TestCase;
24 
25 import java.lang.Thread.UncaughtExceptionHandler;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ThreadFactory;
28 
29 /**
30  * Tests for ThreadFactoryBuilder.
31  *
32  * @author Kurt Alfred Kluever
33  * @author Martin Buchholz
34  */
35 public class ThreadFactoryBuilderTest extends TestCase {
36   private final Runnable monitoredRunnable = new Runnable() {
37     @Override public void run() {
38       completed = true;
39     }
40   };
41 
42   private static final UncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER =
43       new UncaughtExceptionHandler() {
44         @Override public void uncaughtException(Thread t, Throwable e) {
45           // No-op
46         }
47       };
48 
49   private ThreadFactoryBuilder builder;
50   private volatile boolean completed = false;
51 
setUp()52   @Override public void setUp() {
53     builder = new ThreadFactoryBuilder();
54   }
55 
testThreadFactoryBuilder_defaults()56   public void testThreadFactoryBuilder_defaults() throws InterruptedException {
57     ThreadFactory threadFactory = builder.build();
58     Thread thread = threadFactory.newThread(monitoredRunnable);
59     checkThreadPoolName(thread, 1);
60 
61     Thread defaultThread =
62         Executors.defaultThreadFactory().newThread(monitoredRunnable);
63     assertEquals(defaultThread.isDaemon(), thread.isDaemon());
64     assertEquals(defaultThread.getPriority(), thread.getPriority());
65     assertSame(defaultThread.getThreadGroup(), thread.getThreadGroup());
66     assertSame(defaultThread.getUncaughtExceptionHandler(),
67         thread.getUncaughtExceptionHandler());
68 
69     assertFalse(completed);
70     thread.start();
71     thread.join();
72     assertTrue(completed);
73 
74     // Creating a new thread from the same ThreadFactory will have the same
75     // pool ID but a thread ID of 2.
76     Thread thread2 = threadFactory.newThread(monitoredRunnable);
77     checkThreadPoolName(thread2, 2);
78     assertEquals(
79         thread.getName().substring(0, thread.getName().lastIndexOf('-')),
80         thread2.getName().substring(0, thread.getName().lastIndexOf('-')));
81 
82     // Building again should give us a different pool ID.
83     ThreadFactory threadFactory2 = builder.build();
84     Thread thread3 = threadFactory2.newThread(monitoredRunnable);
85     checkThreadPoolName(thread3, 1);
86     ASSERT.that(
87         thread2.getName().substring(0, thread.getName().lastIndexOf('-')))
88         .isNotEqualTo(
89             thread3.getName().substring(0, thread.getName().lastIndexOf('-')));
90   }
91 
checkThreadPoolName(Thread thread, int threadId)92   private static void checkThreadPoolName(Thread thread, int threadId) {
93     assertTrue(thread.getName().matches("^pool-\\d+-thread-" + threadId + "$"));
94   }
95 
testNameFormat_custom()96   public void testNameFormat_custom() {
97     final String NAME_FORMAT = "super duper thread #%s";
98     ThreadFactory factory = builder.setNameFormat(NAME_FORMAT).build();
99     for (int i = 0; i < 10; i++) {
100       assertEquals(String.format(NAME_FORMAT, i),
101           factory.newThread(monitoredRunnable).getName());
102     }
103   }
104 
testDaemon_false()105   public void testDaemon_false() {
106     ThreadFactory factory = builder.setDaemon(false).build();
107     Thread thread = factory.newThread(monitoredRunnable);
108     assertFalse(thread.isDaemon());
109   }
110 
testDaemon_true()111   public void testDaemon_true() {
112     ThreadFactory factory = builder.setDaemon(true).build();
113     Thread thread = factory.newThread(monitoredRunnable);
114     assertTrue(thread.isDaemon());
115   }
116 
testPriority_custom()117   public void testPriority_custom() {
118     for (int i = Thread.MIN_PRIORITY; i <= Thread.MAX_PRIORITY; i++) {
119       ThreadFactory factory = builder.setPriority(i).build();
120       Thread thread = factory.newThread(monitoredRunnable);
121       assertEquals(i, thread.getPriority());
122     }
123   }
124 
testPriority_tooLow()125   public void testPriority_tooLow() {
126     try {
127       builder.setPriority(Thread.MIN_PRIORITY - 1);
128       fail();
129     } catch (IllegalArgumentException expected) {
130     }
131   }
132 
testPriority_tooHigh()133   public void testPriority_tooHigh() {
134     try {
135       builder.setPriority(Thread.MAX_PRIORITY + 1);
136       fail();
137     } catch (IllegalArgumentException expected) {
138     }
139   }
140 
testUncaughtExceptionHandler_custom()141   public void testUncaughtExceptionHandler_custom() {
142     assertEquals(UNCAUGHT_EXCEPTION_HANDLER,
143         builder.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER).build()
144         .newThread(monitoredRunnable).getUncaughtExceptionHandler());
145   }
146 
testBuildMutateBuild()147   public void testBuildMutateBuild() {
148     ThreadFactory factory1 = builder.setPriority(1).build();
149     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
150 
151     ThreadFactory factory2 = builder.setPriority(2).build();
152     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
153     assertEquals(2, factory2.newThread(monitoredRunnable).getPriority());
154   }
155 
testBuildTwice()156   public void testBuildTwice() {
157     builder.build();  // this is allowed
158     builder.build();  // this is *also* allowed
159   }
160 
testBuildMutate()161   public void testBuildMutate() {
162     ThreadFactory factory1 = builder.setPriority(1).build();
163     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
164 
165     builder.setPriority(2);  // change the state of the builder
166     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
167   }
168 
testThreadFactory()169   public void testThreadFactory() throws InterruptedException {
170     final String THREAD_NAME = "ludicrous speed";
171     final int THREAD_PRIORITY = 1;
172     final boolean THREAD_DAEMON = false;
173     ThreadFactory backingThreadFactory = new ThreadFactory() {
174       @Override public Thread newThread(Runnable r) {
175         Thread thread = new Thread(r);
176         thread.setName(THREAD_NAME);
177         thread.setPriority(THREAD_PRIORITY);
178         thread.setDaemon(THREAD_DAEMON);
179         thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER);
180         return thread;
181       }
182     };
183 
184     Thread thread = builder.setThreadFactory(backingThreadFactory).build()
185         .newThread(monitoredRunnable);
186 
187     assertEquals(THREAD_NAME, thread.getName());
188     assertEquals(THREAD_PRIORITY, thread.getPriority());
189     assertEquals(THREAD_DAEMON, thread.isDaemon());
190     assertSame(UNCAUGHT_EXCEPTION_HANDLER,
191         thread.getUncaughtExceptionHandler());
192     assertSame(Thread.State.NEW, thread.getState());
193 
194     assertFalse(completed);
195     thread.start();
196     thread.join();
197     assertTrue(completed);
198   }
199 
testNulls()200   public void testNulls() throws Exception {
201     NullPointerTester npTester = new NullPointerTester();
202     npTester.testAllPublicConstructors(ThreadFactoryBuilder.class);
203     npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class);
204     npTester.testAllPublicInstanceMethods(builder);
205   }
206 }
207