View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3.concurrent;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertNotSame;
23  import static org.junit.jupiter.api.Assertions.assertNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.util.concurrent.ThreadFactory;
29  
30  import org.apache.commons.lang3.AbstractLangTest;
31  import org.easymock.EasyMock;
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * Test class for {@code BasicThreadFactory}.
37   */
38  public class BasicThreadFactoryTest extends AbstractLangTest {
39      /** Constant for the test naming pattern. */
40      private static final String PATTERN = "testThread-%d";
41  
42      /** The builder for creating a thread factory. */
43      private BasicThreadFactory.Builder builder;
44  
45      /**
46       * Helper method for testing whether the daemon flag is taken into account.
47       *
48       * @param flag the value of the flag
49       */
50      private void checkDaemonFlag(final boolean flag) {
51          final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
52          final Runnable r = EasyMock.createMock(Runnable.class);
53          final Thread t = new Thread();
54          EasyMock.expect(wrapped.newThread(r)).andReturn(t);
55          EasyMock.replay(wrapped, r);
56          final BasicThreadFactory factory = builder.wrappedFactory(wrapped).daemon(
57                  flag).build();
58          assertSame(t, factory.newThread(r), "Wrong thread");
59          assertEquals(flag, t.isDaemon(), "Wrong daemon flag");
60          EasyMock.verify(wrapped, r);
61      }
62  
63      /**
64       * Tests the default options of a thread factory.
65       *
66       * @param factory the factory to be checked
67       */
68      private void checkFactoryDefaults(final BasicThreadFactory factory) {
69          assertNull(factory.getNamingPattern(), "Got a naming pattern");
70          assertNull(factory.getUncaughtExceptionHandler(), "Got an exception handler");
71          assertNull(factory.getPriority(), "Got a priority");
72          assertNull(factory.getDaemonFlag(), "Got a daemon flag");
73          assertNotNull(factory.getWrappedFactory(), "No wrapped factory");
74      }
75  
76      @BeforeEach
77      public void setUp() {
78          builder = new BasicThreadFactory.Builder();
79      }
80  
81      /**
82       * Tests the default values used by the builder.
83       */
84      @Test
85      public void testBuildDefaults() {
86          final BasicThreadFactory factory = builder.build();
87          checkFactoryDefaults(factory);
88      }
89  
90      /**
91       * Tests the reset() method of the builder.
92       */
93      @Test
94      public void testBuilderReset() {
95          final ThreadFactory wrappedFactory = EasyMock.createMock(ThreadFactory.class);
96          final Thread.UncaughtExceptionHandler exHandler = EasyMock
97                  .createMock(Thread.UncaughtExceptionHandler.class);
98          EasyMock.replay(wrappedFactory, exHandler);
99          builder.namingPattern(PATTERN).daemon(true).priority(
100                 Thread.MAX_PRIORITY).uncaughtExceptionHandler(exHandler)
101                 .wrappedFactory(wrappedFactory);
102         builder.reset();
103         final BasicThreadFactory factory = builder.build();
104         checkFactoryDefaults(factory);
105         assertNotSame(wrappedFactory, factory.getWrappedFactory(), "Wrapped factory not reset");
106         EasyMock.verify(wrappedFactory, exHandler);
107     }
108 
109     /**
110      * Tests whether reset() is automatically called after build().
111      */
112     @Test
113     public void testBuilderResetAfterBuild() {
114         builder.wrappedFactory(EasyMock.createNiceMock(ThreadFactory.class))
115                 .namingPattern(PATTERN).daemon(true).build();
116         checkFactoryDefaults(builder.build());
117     }
118 
119     /**
120      * Tries to set a null naming pattern.
121      */
122     @Test
123     public void testBuildNamingPatternNull() {
124         assertThrows(NullPointerException.class, () -> builder.namingPattern(null));
125     }
126 
127     /**
128      * Tries to set a null exception handler.
129      */
130     @Test
131     public void testBuildUncaughtExceptionHandlerNull() {
132         assertThrows(NullPointerException.class, () -> builder.uncaughtExceptionHandler(null));
133     }
134 
135     /**
136      * Tries to set a null wrapped factory.
137      */
138     @Test
139     public void testBuildWrappedFactoryNull() {
140         assertThrows(NullPointerException.class, () -> builder.wrappedFactory(null));
141     }
142 
143     /**
144      * Tests whether the daemon status of new threads can be turned off.
145      */
146     @Test
147     public void testNewThreadDaemonFalse() {
148         checkDaemonFlag(false);
149     }
150 
151     /**
152      * Tests whether daemon threads can be created.
153      */
154     @Test
155     public void testNewThreadDaemonTrue() {
156         checkDaemonFlag(true);
157     }
158 
159     /**
160      * Tests whether the exception handler is set if one is provided.
161      */
162     @Test
163     public void testNewThreadExHandler() {
164         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
165         final Runnable r = EasyMock.createMock(Runnable.class);
166         final Thread.UncaughtExceptionHandler handler = EasyMock
167                 .createMock(Thread.UncaughtExceptionHandler.class);
168         final Thread t = new Thread();
169         EasyMock.expect(wrapped.newThread(r)).andReturn(t);
170         EasyMock.replay(wrapped, r, handler);
171         final BasicThreadFactory factory = builder.wrappedFactory(wrapped)
172                 .uncaughtExceptionHandler(handler).build();
173         assertSame(t, factory.newThread(r), "Wrong thread");
174         assertEquals(handler, t.getUncaughtExceptionHandler(), "Wrong exception handler");
175         EasyMock.verify(wrapped, r, handler);
176     }
177 
178     /**
179      * Tests whether the naming pattern is applied to new threads.
180      */
181     @Test
182     public void testNewThreadNamingPattern() {
183         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
184         final Runnable r = EasyMock.createMock(Runnable.class);
185         final int count = 12;
186         for (int i = 0; i < count; i++) {
187             EasyMock.expect(wrapped.newThread(r)).andReturn(new Thread());
188         }
189         EasyMock.replay(wrapped, r);
190         final BasicThreadFactory factory = builder.wrappedFactory(wrapped)
191                 .namingPattern(PATTERN).build();
192         for (int i = 0; i < count; i++) {
193             final Thread t = factory.newThread(r);
194             assertEquals(String.format(PATTERN, Long.valueOf(i + 1)), t.getName(), "Wrong thread name");
195             assertEquals(i + 1, factory.getThreadCount(), "Wrong thread count");
196         }
197         EasyMock.verify(wrapped, r);
198     }
199 
200     /**
201      * Tests whether the daemon flag is not touched on newly created threads if
202      * it is not specified.
203      */
204     @Test
205     public void testNewThreadNoDaemonFlag() {
206         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
207         final Runnable r1 = EasyMock.createMock(Runnable.class);
208         final Runnable r2 = EasyMock.createMock(Runnable.class);
209         final Thread t1 = new Thread();
210         final Thread t2 = new Thread();
211         t1.setDaemon(true);
212         EasyMock.expect(wrapped.newThread(r1)).andReturn(t1);
213         EasyMock.expect(wrapped.newThread(r2)).andReturn(t2);
214         EasyMock.replay(wrapped, r1, r2);
215         final BasicThreadFactory factory = builder.wrappedFactory(wrapped).build();
216         assertSame(t1, factory.newThread(r1), "Wrong thread 1");
217         assertTrue(t1.isDaemon(), "No daemon thread");
218         assertSame(t2, factory.newThread(r2), "Wrong thread 2");
219         assertFalse(t2.isDaemon(), "A daemon thread");
220         EasyMock.verify(wrapped, r1, r2);
221     }
222 
223     /**
224      * Tests whether the original exception handler is not touched if none is
225      * specified.
226      */
227     @Test
228     public void testNewThreadNoExHandler() {
229         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
230         final Runnable r = EasyMock.createMock(Runnable.class);
231         final Thread.UncaughtExceptionHandler handler = EasyMock
232                 .createMock(Thread.UncaughtExceptionHandler.class);
233         final Thread t = new Thread();
234         t.setUncaughtExceptionHandler(handler);
235         EasyMock.expect(wrapped.newThread(r)).andReturn(t);
236         EasyMock.replay(wrapped, r, handler);
237         final BasicThreadFactory factory = builder.wrappedFactory(wrapped).build();
238         assertSame(t, factory.newThread(r), "Wrong thread");
239         assertEquals(handler, t.getUncaughtExceptionHandler(), "Wrong exception handler");
240         EasyMock.verify(wrapped, r, handler);
241     }
242 
243     /**
244      * Tests whether the thread name is not modified if no naming pattern is
245      * set.
246      */
247     @Test
248     public void testNewThreadNoNamingPattern() {
249         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
250         final Runnable r = EasyMock.createMock(Runnable.class);
251         final String name = "unchangedThreadName";
252         final Thread t = new Thread(name);
253         EasyMock.expect(wrapped.newThread(r)).andReturn(t);
254         EasyMock.replay(wrapped, r);
255         final BasicThreadFactory factory = builder.wrappedFactory(wrapped).build();
256         assertSame(t, factory.newThread(r), "Wrong thread");
257         assertEquals(name, t.getName(), "Name was changed");
258         EasyMock.verify(wrapped, r);
259     }
260 
261     /**
262      * Tests whether the original priority is not changed if no priority is
263      * specified.
264      */
265     @Test
266     public void testNewThreadNoPriority() {
267         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
268         final Runnable r = EasyMock.createMock(Runnable.class);
269         final int orgPriority = Thread.NORM_PRIORITY + 1;
270         final Thread t = new Thread();
271         t.setPriority(orgPriority);
272         EasyMock.expect(wrapped.newThread(r)).andReturn(t);
273         EasyMock.replay(wrapped, r);
274         final BasicThreadFactory factory = builder.wrappedFactory(wrapped).build();
275         assertSame(t, factory.newThread(r), "Wrong thread");
276         assertEquals(orgPriority, t.getPriority(), "Wrong priority");
277         EasyMock.verify(wrapped, r);
278     }
279 
280     /**
281      * Tests whether the priority is set on newly created threads.
282      */
283     @Test
284     public void testNewThreadPriority() {
285         final ThreadFactory wrapped = EasyMock.createMock(ThreadFactory.class);
286         final Runnable r = EasyMock.createMock(Runnable.class);
287         final Thread t = new Thread();
288         EasyMock.expect(wrapped.newThread(r)).andReturn(t);
289         EasyMock.replay(wrapped, r);
290         final int priority = Thread.NORM_PRIORITY + 1;
291         final BasicThreadFactory factory = builder.wrappedFactory(wrapped).priority(
292                 priority).build();
293         assertSame(t, factory.newThread(r), "Wrong thread");
294         assertEquals(priority, t.getPriority(), "Wrong priority");
295         EasyMock.verify(wrapped, r);
296     }
297 }