View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
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 net.sf.ehcache.constructs.nonstop;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.concurrent.Callable;
22  import java.util.concurrent.ThreadFactory;
23  import java.util.concurrent.atomic.AtomicInteger;
24  
25  import junit.framework.Assert;
26  import junit.framework.TestCase;
27  import net.sf.ehcache.constructs.nonstop.ThreadDump.ThreadInformation;
28  
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  public class ExecutorServiceTest extends TestCase {
33  
34      private static final String TEST_EXECUTOR_THREAD_NAME_PREFIX = "Test Executor thread";
35      private NonstopExecutorServiceImpl service;
36      private static final Logger LOG = LoggerFactory.getLogger(ExecutorServiceTest.class);
37  
38      @Override
39      protected void setUp() throws Exception {
40          int initialThreadsCount = countExecutorThreads();
41          LOG.info("Initial thread count: " + initialThreadsCount);
42          Assert.assertEquals(0, initialThreadsCount);
43          service = new NonstopExecutorServiceImpl(new ThreadFactory() {
44              private final AtomicInteger count = new AtomicInteger();
45  
46              public Thread newThread(Runnable r) {
47                  Thread thread = new Thread(r, TEST_EXECUTOR_THREAD_NAME_PREFIX + "-" + count.incrementAndGet() + " [for '"
48                          + Thread.currentThread().getName() + "']");
49                  thread.setDaemon(true);
50                  return thread;
51              }
52          });
53      }
54  
55      @Override
56      protected void tearDown() throws Exception {
57          service.shutdown();
58          Thread.sleep(2000);
59          int threads = countExecutorThreads();
60          LOG.info("After shutting down service, thread count: " + threads);
61          Assert.assertEquals(0, threads);
62          LOG.info("Test complete successfully");
63      }
64  
65      public void testOnlyOneExecutorThreadCreated() throws Exception {
66          int initialThreadsCount = countExecutorThreads();
67          int numOps = 100;
68          for (int i = 0; i < numOps; i++) {
69              service.execute(new NoopCallable(), 5000);
70          }
71          // assert almost 1 pool thread is created
72          int actualThreadCount = countExecutorThreads() - initialThreadsCount;
73          assertEquals("ActualThreadCount: " + actualThreadCount + " Expected to be 1", 1, actualThreadCount);
74      }
75  
76      public void testOneExecutorThreadCreatedPerAppThread() throws Exception {
77          int initialThreadsCount = countExecutorThreads();
78          // each request thread should create one executor thread
79          List<Thread> requestThreads = new ArrayList<Thread>();
80          int extraRequests = 20;
81          for (int i = 0; i < extraRequests; i++) {
82              Thread thread = new Thread(new Runnable() {
83                  public void run() {
84                      try {
85                          service.execute(new NoopCallable(), 5000);
86                      } catch (Exception e) {
87                          fail("Executing noopCallable should not fail");
88                      }
89                  }
90              }, "RequestThread-" + i);
91              requestThreads.add(thread);
92              thread.start();
93          }
94          for (Thread t : requestThreads) {
95              t.join();
96          }
97          Assert.assertEquals(extraRequests, countExecutorThreads() - initialThreadsCount);
98      }
99  
100     // public void testMultipleExecutorThreadsCreatedPerAppThread() throws Exception {
101     // int initialThreadsCount = countExecutorThreads();
102     // int numRequests = 20;
103     // // submitting multiple blocking jobs should create multiple threads
104     // for (int i = 0; i < numRequests; i++) {
105     // try {
106     // service.execute(new BlockingCallable(), 10);
107     // fail("Executing blockingCallable should timeout");
108     // } catch (TimeoutException e) {
109     // // ignore
110     // }
111     // }
112     // Thread.sleep(1000);
113     // assertEquals("", numRequests, countExecutorThreads() - initialThreadsCount);
114     //
115     // }
116 
117     private int countExecutorThreads() {
118         List<ThreadInformation> threadDump = ThreadDump.getThreadDump();
119         int rv = 0;
120         List<ThreadInformation> threads = new ArrayList();
121         for (ThreadInformation info : threadDump) {
122             if (info.getThreadName().contains(TEST_EXECUTOR_THREAD_NAME_PREFIX)) {
123                 // LOG.info("Thread: id=" + info.getThreadId() + ", name=\"" + info.getThreadName() +
124                 // "\": is an executor thread");
125                 threads.add(info);
126                 rv++;
127             }
128         }
129         LOG.info("Counting number of executor threads created till now: " + rv);
130         String string = "{";
131         for (ThreadInformation info : threads) {
132             string += info.getThreadName() + " [id=" + info.getThreadId() + "], ";
133         }
134         string += "}";
135         LOG.info("Thread name/ids: " + string);
136         return rv;
137     }
138 
139     private static class NoopCallable implements Callable<Void> {
140 
141         public Void call() throws Exception {
142             // do nothing
143             return null;
144         }
145 
146     }
147 
148 }