• 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 com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.testing.NullPointerTester;
22 import java.lang.Thread.UncaughtExceptionHandler;
23 import java.util.Locale;
24 import java.util.concurrent.Executors;
25 import java.util.concurrent.ThreadFactory;
26 import junit.framework.TestCase;
27 
28 /**
29  * Tests for ThreadFactoryBuilder.
30  *
31  * @author Kurt Alfred Kluever
32  * @author Martin Buchholz
33  */
34 public class ThreadFactoryBuilderTest extends TestCase {
35   private final Runnable monitoredRunnable =
36       new Runnable() {
37         @Override
38         public void run() {
39           completed = true;
40         }
41       };
42 
43   private static final UncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER =
44       new UncaughtExceptionHandler() {
45         @Override
46         public void uncaughtException(Thread t, Throwable e) {
47           // No-op
48         }
49       };
50 
51   private ThreadFactoryBuilder builder;
52   private volatile boolean completed = false;
53 
54   @Override
setUp()55   public void setUp() {
56     builder = new ThreadFactoryBuilder();
57   }
58 
59 
testThreadFactoryBuilder_defaults()60   public void testThreadFactoryBuilder_defaults() throws InterruptedException {
61     ThreadFactory threadFactory = builder.build();
62     Thread thread = threadFactory.newThread(monitoredRunnable);
63     checkThreadPoolName(thread, 1);
64 
65     Thread defaultThread = Executors.defaultThreadFactory().newThread(monitoredRunnable);
66     assertEquals(defaultThread.isDaemon(), thread.isDaemon());
67     assertEquals(defaultThread.getPriority(), thread.getPriority());
68     assertSame(defaultThread.getThreadGroup(), thread.getThreadGroup());
69     assertSame(defaultThread.getUncaughtExceptionHandler(), thread.getUncaughtExceptionHandler());
70 
71     assertFalse(completed);
72     thread.start();
73     thread.join();
74     assertTrue(completed);
75 
76     // Creating a new thread from the same ThreadFactory will have the same
77     // pool ID but a thread ID of 2.
78     Thread thread2 = threadFactory.newThread(monitoredRunnable);
79     checkThreadPoolName(thread2, 2);
80     assertEquals(
81         thread.getName().substring(0, thread.getName().lastIndexOf('-')),
82         thread2.getName().substring(0, thread.getName().lastIndexOf('-')));
83 
84     // Building again should give us a different pool ID.
85     ThreadFactory threadFactory2 = builder.build();
86     Thread thread3 = threadFactory2.newThread(monitoredRunnable);
87     checkThreadPoolName(thread3, 1);
88     assertThat(thread2.getName().substring(0, thread.getName().lastIndexOf('-')))
89         .isNotEqualTo(thread3.getName().substring(0, thread.getName().lastIndexOf('-')));
90   }
91 
checkThreadPoolName(Thread thread, int threadId)92   private static void checkThreadPoolName(Thread thread, int threadId) {
93     assertThat(thread.getName()).matches("^pool-\\d+-thread-" + threadId + "$");
94   }
95 
96 
testNameFormatWithPercentS_custom()97   public void testNameFormatWithPercentS_custom() {
98     String format = "super-duper-thread-%s";
99     ThreadFactory factory = builder.setNameFormat(format).build();
100     for (int i = 0; i < 11; i++) {
101       assertEquals(rootLocaleFormat(format, i), factory.newThread(monitoredRunnable).getName());
102     }
103   }
104 
105 
testNameFormatWithPercentD_custom()106   public void testNameFormatWithPercentD_custom() {
107     String format = "super-duper-thread-%d";
108     ThreadFactory factory = builder.setNameFormat(format).build();
109     for (int i = 0; i < 11; i++) {
110       assertEquals(rootLocaleFormat(format, i), factory.newThread(monitoredRunnable).getName());
111     }
112   }
113 
114 
testDaemon_false()115   public void testDaemon_false() {
116     ThreadFactory factory = builder.setDaemon(false).build();
117     Thread thread = factory.newThread(monitoredRunnable);
118     assertFalse(thread.isDaemon());
119   }
120 
121 
testDaemon_true()122   public void testDaemon_true() {
123     ThreadFactory factory = builder.setDaemon(true).build();
124     Thread thread = factory.newThread(monitoredRunnable);
125     assertTrue(thread.isDaemon());
126   }
127 
128 
testPriority_custom()129   public void testPriority_custom() {
130     for (int i = Thread.MIN_PRIORITY; i <= Thread.MAX_PRIORITY; i++) {
131       ThreadFactory factory = builder.setPriority(i).build();
132       Thread thread = factory.newThread(monitoredRunnable);
133       assertEquals(i, thread.getPriority());
134     }
135   }
136 
testPriority_tooLow()137   public void testPriority_tooLow() {
138     try {
139       builder.setPriority(Thread.MIN_PRIORITY - 1);
140       fail();
141     } catch (IllegalArgumentException expected) {
142     }
143   }
144 
testPriority_tooHigh()145   public void testPriority_tooHigh() {
146     try {
147       builder.setPriority(Thread.MAX_PRIORITY + 1);
148       fail();
149     } catch (IllegalArgumentException expected) {
150     }
151   }
152 
153 
testUncaughtExceptionHandler_custom()154   public void testUncaughtExceptionHandler_custom() {
155     assertEquals(
156         UNCAUGHT_EXCEPTION_HANDLER,
157         builder
158             .setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER)
159             .build()
160             .newThread(monitoredRunnable)
161             .getUncaughtExceptionHandler());
162   }
163 
164 
testBuildMutateBuild()165   public void testBuildMutateBuild() {
166     ThreadFactory factory1 = builder.setPriority(1).build();
167     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
168 
169     ThreadFactory factory2 = builder.setPriority(2).build();
170     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
171     assertEquals(2, factory2.newThread(monitoredRunnable).getPriority());
172   }
173 
testBuildTwice()174   public void testBuildTwice() {
175     ThreadFactory unused;
176     unused = builder.build(); // this is allowed
177     unused = builder.build(); // this is *also* allowed
178   }
179 
180 
testBuildMutate()181   public void testBuildMutate() {
182     ThreadFactory factory1 = builder.setPriority(1).build();
183     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
184 
185     builder.setPriority(2); // change the state of the builder
186     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
187   }
188 
189 
testThreadFactory()190   public void testThreadFactory() throws InterruptedException {
191     final String THREAD_NAME = "ludicrous speed";
192     final int THREAD_PRIORITY = 1;
193     final boolean THREAD_DAEMON = false;
194     ThreadFactory backingThreadFactory =
195         new ThreadFactory() {
196           @Override
197           public Thread newThread(Runnable r) {
198             Thread thread = new Thread(r);
199             thread.setName(THREAD_NAME);
200             thread.setPriority(THREAD_PRIORITY);
201             thread.setDaemon(THREAD_DAEMON);
202             thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER);
203             return thread;
204           }
205         };
206 
207     Thread thread =
208         builder.setThreadFactory(backingThreadFactory).build().newThread(monitoredRunnable);
209 
210     assertEquals(THREAD_NAME, thread.getName());
211     assertEquals(THREAD_PRIORITY, thread.getPriority());
212     assertEquals(THREAD_DAEMON, thread.isDaemon());
213     assertSame(UNCAUGHT_EXCEPTION_HANDLER, thread.getUncaughtExceptionHandler());
214     assertSame(Thread.State.NEW, thread.getState());
215 
216     assertFalse(completed);
217     thread.start();
218     thread.join();
219     assertTrue(completed);
220   }
221 
testNulls()222   public void testNulls() {
223     NullPointerTester npTester = new NullPointerTester();
224     npTester.testAllPublicConstructors(ThreadFactoryBuilder.class);
225     npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class);
226     npTester.testAllPublicInstanceMethods(builder);
227   }
228 
rootLocaleFormat(String format, Object... args)229   private static String rootLocaleFormat(String format, Object... args) {
230     return String.format(Locale.ROOT, format, args);
231   }
232 }
233