• 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 import static org.junit.Assert.assertThrows;
21 
22 import com.google.common.testing.NullPointerTester;
23 import java.lang.Thread.UncaughtExceptionHandler;
24 import java.util.Locale;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.ThreadFactory;
27 import junit.framework.TestCase;
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 =
37       new Runnable() {
38         @Override
39         public void run() {
40           completed = true;
41         }
42       };
43 
44   private static final UncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER =
45       new UncaughtExceptionHandler() {
46         @Override
47         public void uncaughtException(Thread t, Throwable e) {
48           // No-op
49         }
50       };
51 
52   private ThreadFactoryBuilder builder;
53   private volatile boolean completed = false;
54 
55   @Override
setUp()56   public void setUp() {
57     builder = new ThreadFactoryBuilder();
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 
testNameFormatWithPercentS_custom()96   public void testNameFormatWithPercentS_custom() {
97     String format = "super-duper-thread-%s";
98     ThreadFactory factory = builder.setNameFormat(format).build();
99     for (int i = 0; i < 11; i++) {
100       assertEquals(rootLocaleFormat(format, i), factory.newThread(monitoredRunnable).getName());
101     }
102   }
103 
testNameFormatWithPercentD_custom()104   public void testNameFormatWithPercentD_custom() {
105     String format = "super-duper-thread-%d";
106     ThreadFactory factory = builder.setNameFormat(format).build();
107     for (int i = 0; i < 11; i++) {
108       assertEquals(rootLocaleFormat(format, i), factory.newThread(monitoredRunnable).getName());
109     }
110   }
111 
testDaemon_false()112   public void testDaemon_false() {
113     ThreadFactory factory = builder.setDaemon(false).build();
114     Thread thread = factory.newThread(monitoredRunnable);
115     assertFalse(thread.isDaemon());
116   }
117 
testDaemon_true()118   public void testDaemon_true() {
119     ThreadFactory factory = builder.setDaemon(true).build();
120     Thread thread = factory.newThread(monitoredRunnable);
121     assertTrue(thread.isDaemon());
122   }
123 
testPriority_custom()124   public void testPriority_custom() {
125     for (int i = Thread.MIN_PRIORITY; i <= Thread.MAX_PRIORITY; i++) {
126       ThreadFactory factory = builder.setPriority(i).build();
127       Thread thread = factory.newThread(monitoredRunnable);
128       assertEquals(i, thread.getPriority());
129     }
130   }
131 
testPriority_tooLow()132   public void testPriority_tooLow() {
133     assertThrows(
134         IllegalArgumentException.class, () -> builder.setPriority(Thread.MIN_PRIORITY - 1));
135   }
136 
testPriority_tooHigh()137   public void testPriority_tooHigh() {
138     assertThrows(
139         IllegalArgumentException.class, () -> builder.setPriority(Thread.MAX_PRIORITY + 1));
140   }
141 
testUncaughtExceptionHandler_custom()142   public void testUncaughtExceptionHandler_custom() {
143     assertEquals(
144         UNCAUGHT_EXCEPTION_HANDLER,
145         builder
146             .setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER)
147             .build()
148             .newThread(monitoredRunnable)
149             .getUncaughtExceptionHandler());
150   }
151 
testBuildMutateBuild()152   public void testBuildMutateBuild() {
153     ThreadFactory factory1 = builder.setPriority(1).build();
154     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
155 
156     ThreadFactory factory2 = builder.setPriority(2).build();
157     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
158     assertEquals(2, factory2.newThread(monitoredRunnable).getPriority());
159   }
160 
testBuildTwice()161   public void testBuildTwice() {
162     ThreadFactory unused;
163     unused = builder.build(); // this is allowed
164     unused = builder.build(); // this is *also* allowed
165   }
166 
testBuildMutate()167   public void testBuildMutate() {
168     ThreadFactory factory1 = builder.setPriority(1).build();
169     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
170 
171     builder.setPriority(2); // change the state of the builder
172     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
173   }
174 
testThreadFactory()175   public void testThreadFactory() throws InterruptedException {
176     final String THREAD_NAME = "ludicrous speed";
177     final int THREAD_PRIORITY = 1;
178     final boolean THREAD_DAEMON = false;
179     ThreadFactory backingThreadFactory =
180         new ThreadFactory() {
181           @Override
182           public Thread newThread(Runnable r) {
183             Thread thread = new Thread(r);
184             thread.setName(THREAD_NAME);
185             thread.setPriority(THREAD_PRIORITY);
186             thread.setDaemon(THREAD_DAEMON);
187             thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER);
188             return thread;
189           }
190         };
191 
192     Thread thread =
193         builder.setThreadFactory(backingThreadFactory).build().newThread(monitoredRunnable);
194 
195     assertEquals(THREAD_NAME, thread.getName());
196     assertEquals(THREAD_PRIORITY, thread.getPriority());
197     assertEquals(THREAD_DAEMON, thread.isDaemon());
198     assertSame(UNCAUGHT_EXCEPTION_HANDLER, thread.getUncaughtExceptionHandler());
199     assertSame(Thread.State.NEW, thread.getState());
200 
201     assertFalse(completed);
202     thread.start();
203     thread.join();
204     assertTrue(completed);
205   }
206 
testNulls()207   public void testNulls() {
208     NullPointerTester npTester = new NullPointerTester();
209     npTester.testAllPublicConstructors(ThreadFactoryBuilder.class);
210     npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class);
211     npTester.testAllPublicInstanceMethods(builder);
212   }
213 
rootLocaleFormat(String format, Object... args)214   private static String rootLocaleFormat(String format, Object... args) {
215     return String.format(Locale.ROOT, format, args);
216   }
217 }
218