Home | History | Annotate | Download | only in concurrent
      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 
     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 
     52   @Override public void setUp() {
     53     builder = new ThreadFactoryBuilder();
     54   }
     55 
     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     assertThat(
     87         thread2.getName().substring(0, thread.getName().lastIndexOf('-')))
     88         .isNotEqualTo(
     89             thread3.getName().substring(0, thread.getName().lastIndexOf('-')));
     90   }
     91 
     92   private static void checkThreadPoolName(Thread thread, int threadId) {
     93     assertTrue(thread.getName().matches("^pool-\\d+-thread-" + threadId + "$"));
     94   }
     95 
     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(String.format(format, i),
    101           factory.newThread(monitoredRunnable).getName());
    102     }
    103   }
    104 
    105   public void testNameFormatWithPercentD_custom() {
    106     String format = "super-duper-thread-%d";
    107     ThreadFactory factory = builder.setNameFormat(format).build();
    108     for (int i = 0; i < 11; i++) {
    109       assertEquals(String.format(format, i),
    110           factory.newThread(monitoredRunnable).getName());
    111     }
    112   }
    113 
    114   public void testDaemon_false() {
    115     ThreadFactory factory = builder.setDaemon(false).build();
    116     Thread thread = factory.newThread(monitoredRunnable);
    117     assertFalse(thread.isDaemon());
    118   }
    119 
    120   public void testDaemon_true() {
    121     ThreadFactory factory = builder.setDaemon(true).build();
    122     Thread thread = factory.newThread(monitoredRunnable);
    123     assertTrue(thread.isDaemon());
    124   }
    125 
    126   public void testPriority_custom() {
    127     for (int i = Thread.MIN_PRIORITY; i <= Thread.MAX_PRIORITY; i++) {
    128       ThreadFactory factory = builder.setPriority(i).build();
    129       Thread thread = factory.newThread(monitoredRunnable);
    130       assertEquals(i, thread.getPriority());
    131     }
    132   }
    133 
    134   public void testPriority_tooLow() {
    135     try {
    136       builder.setPriority(Thread.MIN_PRIORITY - 1);
    137       fail();
    138     } catch (IllegalArgumentException expected) {
    139     }
    140   }
    141 
    142   public void testPriority_tooHigh() {
    143     try {
    144       builder.setPriority(Thread.MAX_PRIORITY + 1);
    145       fail();
    146     } catch (IllegalArgumentException expected) {
    147     }
    148   }
    149 
    150   public void testUncaughtExceptionHandler_custom() {
    151     assertEquals(UNCAUGHT_EXCEPTION_HANDLER,
    152         builder.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER).build()
    153         .newThread(monitoredRunnable).getUncaughtExceptionHandler());
    154   }
    155 
    156   public void testBuildMutateBuild() {
    157     ThreadFactory factory1 = builder.setPriority(1).build();
    158     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
    159 
    160     ThreadFactory factory2 = builder.setPriority(2).build();
    161     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
    162     assertEquals(2, factory2.newThread(monitoredRunnable).getPriority());
    163   }
    164 
    165   public void testBuildTwice() {
    166     builder.build();  // this is allowed
    167     builder.build();  // this is *also* allowed
    168   }
    169 
    170   public void testBuildMutate() {
    171     ThreadFactory factory1 = builder.setPriority(1).build();
    172     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
    173 
    174     builder.setPriority(2);  // change the state of the builder
    175     assertEquals(1, factory1.newThread(monitoredRunnable).getPriority());
    176   }
    177 
    178   public void testThreadFactory() throws InterruptedException {
    179     final String THREAD_NAME = "ludicrous speed";
    180     final int THREAD_PRIORITY = 1;
    181     final boolean THREAD_DAEMON = false;
    182     ThreadFactory backingThreadFactory = new ThreadFactory() {
    183       @Override public Thread newThread(Runnable r) {
    184         Thread thread = new Thread(r);
    185         thread.setName(THREAD_NAME);
    186         thread.setPriority(THREAD_PRIORITY);
    187         thread.setDaemon(THREAD_DAEMON);
    188         thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER);
    189         return thread;
    190       }
    191     };
    192 
    193     Thread thread = builder.setThreadFactory(backingThreadFactory).build()
    194         .newThread(monitoredRunnable);
    195 
    196     assertEquals(THREAD_NAME, thread.getName());
    197     assertEquals(THREAD_PRIORITY, thread.getPriority());
    198     assertEquals(THREAD_DAEMON, thread.isDaemon());
    199     assertSame(UNCAUGHT_EXCEPTION_HANDLER,
    200         thread.getUncaughtExceptionHandler());
    201     assertSame(Thread.State.NEW, thread.getState());
    202 
    203     assertFalse(completed);
    204     thread.start();
    205     thread.join();
    206     assertTrue(completed);
    207   }
    208 
    209   public void testNulls() {
    210     NullPointerTester npTester = new NullPointerTester();
    211     npTester.testAllPublicConstructors(ThreadFactoryBuilder.class);
    212     npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class);
    213     npTester.testAllPublicInstanceMethods(builder);
    214   }
    215 }
    216