• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.google.common.util.concurrent;
18 
19 import com.google.common.base.Predicate;
20 import com.google.common.base.Predicates;
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.collect.Iterables;
23 import com.google.common.collect.Lists;
24 
25 import junit.framework.TestCase;
26 
27 import java.util.Collection;
28 import java.util.List;
29 import java.util.concurrent.Callable;
30 import java.util.concurrent.ExecutionException;
31 import java.util.concurrent.ExecutorService;
32 import java.util.concurrent.Future;
33 import java.util.concurrent.TimeUnit;
34 import java.util.concurrent.TimeoutException;
35 
36 /**
37  * Test for {@link WrappingExecutorService}
38  *
39  * @author Chris Nokleberg
40  */
41 public class WrappingExecutorServiceTest extends TestCase {
42   private static final String RESULT_VALUE = "ran";
43   private static final Runnable DO_NOTHING = new Runnable() {
44     @Override
45     public void run() {
46     }
47   };
48 
49   // Uninteresting delegations
testDelegations()50   public void testDelegations() throws InterruptedException {
51     MockExecutor mock = new MockExecutor();
52     TestExecutor testExecutor = new TestExecutor(mock);
53     assertFalse(testExecutor.awaitTermination(10, TimeUnit.MILLISECONDS));
54     mock.assertLastMethodCalled("awaitTermination");
55     assertFalse(testExecutor.isTerminated());
56     mock.assertLastMethodCalled("isTerminated");
57     assertFalse(testExecutor.isShutdown());
58     mock.assertLastMethodCalled("isShutdown");
59     testExecutor.shutdown();
60     mock.assertLastMethodCalled("shutdown");
61     List<Runnable> list = testExecutor.shutdownNow();
62     mock.assertLastMethodCalled("shutdownNow");
63     assertEquals(ImmutableList.of(), list);
64   }
65 
testExecute()66   public void testExecute() {
67     MockExecutor mock = new MockExecutor();
68     TestExecutor testExecutor = new TestExecutor(mock);
69     testExecutor.execute(DO_NOTHING);
70     mock.assertLastMethodCalled("execute");
71   }
72 
testSubmit()73   public void testSubmit() throws InterruptedException, ExecutionException {
74     {
75       MockExecutor mock = new MockExecutor();
76       TestExecutor testExecutor = new TestExecutor(mock);
77       Future<?> f = testExecutor.submit(DO_NOTHING);
78       mock.assertLastMethodCalled("submit");
79       f.get();
80     }
81     {
82       MockExecutor mock = new MockExecutor();
83       TestExecutor testExecutor = new TestExecutor(mock);
84       Future<String> f = testExecutor.submit(DO_NOTHING, RESULT_VALUE);
85       mock.assertLastMethodCalled("submit");
86       assertEquals(RESULT_VALUE, f.get());
87     }
88     {
89       MockExecutor mock = new MockExecutor();
90       TestExecutor testExecutor = new TestExecutor(mock);
91       Callable<String> task = Callables.returning(RESULT_VALUE);
92       Future<String> f = testExecutor.submit(task);
93       mock.assertLastMethodCalled("submit");
94       assertEquals(RESULT_VALUE, f.get());
95     }
96   }
97 
testInvokeAll()98   public void testInvokeAll() throws InterruptedException, ExecutionException {
99     List<Callable<String>> tasks = createTasks(3);
100     {
101       MockExecutor mock = new MockExecutor();
102       TestExecutor testExecutor = new TestExecutor(mock);
103       List<Future<String>> futures = testExecutor.invokeAll(tasks);
104       mock.assertLastMethodCalled("invokeAll");
105       checkResults(futures);
106     }
107     {
108       MockExecutor mock = new MockExecutor();
109       TimeUnit unit = TimeUnit.SECONDS;
110       long timeout = 5;
111       TestExecutor testExecutor = new TestExecutor(mock);
112       List<Future<String>> futures = testExecutor.invokeAll(tasks, timeout, unit);
113       mock.assertMethodWithTimeout("invokeAll", timeout, unit);
114       checkResults(futures);
115     }
116   }
117 
testInvokeAny()118   public void testInvokeAny() throws InterruptedException, ExecutionException, TimeoutException {
119     List<Callable<String>> tasks = createTasks(3);
120     {
121       MockExecutor mock = new MockExecutor();
122       TestExecutor testExecutor = new TestExecutor(mock);
123       String s = testExecutor.invokeAny(tasks);
124       assertEquals("ran0", s);
125       mock.assertLastMethodCalled("invokeAny");
126     }
127     {
128       MockExecutor mock = new MockExecutor();
129       TimeUnit unit = TimeUnit.SECONDS;
130       long timeout = 5;
131       TestExecutor testExecutor = new TestExecutor(mock);
132       String s = testExecutor.invokeAny(tasks, timeout, unit);
133       assertEquals(RESULT_VALUE + "0", s);
134       mock.assertMethodWithTimeout("invokeAny", timeout, unit);
135     }
136   }
137 
checkResults(List<Future<String>> futures)138   private static void checkResults(List<Future<String>> futures)
139       throws InterruptedException, ExecutionException {
140     for (int i = 0; i < futures.size(); i++) {
141       assertEquals(RESULT_VALUE + i, futures.get(i).get());
142     }
143   }
144 
createTasks(int n)145   private static List<Callable<String>> createTasks(int n) {
146     List<Callable<String>> callables = Lists.newArrayList();
147     for (int i = 0; i < n; i++) {
148       callables.add(Callables.returning(RESULT_VALUE + i));
149     }
150     return callables;
151   }
152 
153   private static final class WrappedCallable<T> implements Callable<T> {
154     private final Callable<T> delegate;
155 
WrappedCallable(Callable<T> delegate)156     public WrappedCallable(Callable<T> delegate) {
157       this.delegate = delegate;
158     }
159 
160     @Override
call()161     public T call() throws Exception {
162       return delegate.call();
163     }
164   }
165 
166   private static final class WrappedRunnable implements Runnable {
167     private final Runnable delegate;
168 
WrappedRunnable(Runnable delegate)169     public WrappedRunnable(Runnable delegate) {
170       this.delegate = delegate;
171     }
172 
173     @Override
run()174     public void run() {
175       delegate.run();
176     }
177   }
178 
179   private static final class TestExecutor extends WrappingExecutorService {
TestExecutor(MockExecutor mock)180     public TestExecutor(MockExecutor mock) {
181       super(mock);
182     }
183 
184     @Override
wrapTask(Callable<T> callable)185     protected <T> Callable<T> wrapTask(Callable<T> callable) {
186       return new WrappedCallable<T>(callable);
187     }
188 
wrapTask(Runnable command)189     @Override protected Runnable wrapTask(Runnable command) {
190       return new WrappedRunnable(command);
191     }
192   }
193 
194   // TODO: If this test can ever depend on EasyMock or the like, use it instead.
195   private static final class MockExecutor implements ExecutorService {
196     private String lastMethodCalled = "";
197     private long lastTimeoutInMillis = -1;
198     private ExecutorService inline = MoreExecutors.sameThreadExecutor();
199 
assertLastMethodCalled(String method)200     public void assertLastMethodCalled(String method) {
201       assertEquals(method, lastMethodCalled);
202     }
203 
assertMethodWithTimeout(String method, long timeout, TimeUnit unit)204     public void assertMethodWithTimeout(String method, long timeout, TimeUnit unit) {
205       assertLastMethodCalled(method + "Timeout");
206       assertEquals(unit.toMillis(timeout), lastTimeoutInMillis);
207     }
208 
209     @Override
awaitTermination(long timeout, TimeUnit unit)210     public boolean awaitTermination(long timeout, TimeUnit unit) {
211       lastMethodCalled = "awaitTermination";
212       return false;
213     }
214 
215     @Override
invokeAll(Collection<? extends Callable<T>> tasks)216     public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
217         throws InterruptedException {
218       lastMethodCalled = "invokeAll";
219       assertTaskWrapped(tasks);
220       return inline.invokeAll(tasks);
221     }
222 
223     @Override
invokeAll( Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)224     public <T> List<Future<T>> invokeAll(
225         Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
226         throws InterruptedException {
227       assertTaskWrapped(tasks);
228       lastMethodCalled = "invokeAllTimeout";
229       lastTimeoutInMillis = unit.toMillis(timeout);
230       return inline.invokeAll(tasks, timeout, unit);
231     }
232 
233     // Define the invokeAny methods to invoke the first task
234     @Override
invokeAny(Collection<? extends Callable<T>> tasks)235     public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
236         throws ExecutionException, InterruptedException {
237       assertTaskWrapped(tasks);
238       lastMethodCalled = "invokeAny";
239       return inline.submit(Iterables.get(tasks, 0)).get();
240     }
241 
242     @Override
invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)243     public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
244         throws ExecutionException, InterruptedException, TimeoutException {
245       assertTaskWrapped(tasks);
246       lastMethodCalled = "invokeAnyTimeout";
247       lastTimeoutInMillis = unit.toMillis(timeout);
248       return inline.submit(Iterables.get(tasks, 0)).get(timeout, unit);
249     }
250 
251     @Override
isShutdown()252     public boolean isShutdown() {
253       lastMethodCalled = "isShutdown";
254       return false;
255     }
256 
257     @Override
isTerminated()258     public boolean isTerminated() {
259       lastMethodCalled = "isTerminated";
260       return false;
261     }
262 
263     @Override
shutdown()264     public void shutdown() {
265       lastMethodCalled = "shutdown";
266     }
267 
268     @Override
shutdownNow()269     public List<Runnable> shutdownNow() {
270       lastMethodCalled = "shutdownNow";
271       return ImmutableList.of();
272     }
273 
274     @Override
submit(Callable<T> task)275     public <T> Future<T> submit(Callable<T> task) {
276       lastMethodCalled = "submit";
277       assertTrue(task instanceof WrappedCallable);
278       return inline.submit(task);
279     }
280 
281     @Override
submit(Runnable task)282     public Future<?> submit(Runnable task) {
283       lastMethodCalled = "submit";
284       assertTrue(task instanceof WrappedRunnable);
285       return inline.submit(task);
286     }
287 
288     @Override
submit(Runnable task, T result)289     public <T> Future<T> submit(Runnable task, T result) {
290       lastMethodCalled = "submit";
291       assertTrue(task instanceof WrappedRunnable);
292       return inline.submit(task, result);
293     }
294 
295     @Override
execute(Runnable command)296     public void execute(Runnable command) {
297       lastMethodCalled = "execute";
298       assertTrue(command instanceof WrappedRunnable);
299       inline.execute(command);
300     }
301 
assertTaskWrapped( Collection<? extends Callable<T>> tasks)302     private static <T> void assertTaskWrapped(
303         Collection<? extends Callable<T>> tasks) {
304       Predicate<Object> p = Predicates.instanceOf(WrappedCallable.class);
305       assertTrue(Iterables.all(tasks, p));
306     }
307 
308   }
309 }
310