blob: 0f58e786e237d6637a4fe7f113e17fc0e7ec6318 [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010011import static java.util.concurrent.TimeUnit.MILLISECONDS;
12
Calin Juravle8f0d92b2013-08-01 17:26:00 +010013import java.util.concurrent.ArrayBlockingQueue;
14import java.util.concurrent.Callable;
15import java.util.concurrent.ExecutorCompletionService;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010016import java.util.concurrent.Executors;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010017import java.util.concurrent.ExecutorService;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010018import java.util.concurrent.Future;
19import java.util.concurrent.FutureTask;
20import java.util.concurrent.RunnableFuture;
21import java.util.concurrent.ThreadPoolExecutor;
22import java.util.concurrent.TimeUnit;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010023import java.util.concurrent.atomic.AtomicBoolean;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010024
25import junit.framework.Test;
26import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010027
28public class ExecutorCompletionServiceTest extends JSR166TestCase {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010029 // android-note: Removed because the CTS runner does a bad job of
30 // retrying tests that have suite() declarations.
31 //
32 // public static void main(String[] args) {
33 // main(suite(), args);
34 // }
35 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000036 // return new TestSuite(ExecutorCompletionServiceTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010037 // }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010038
39 /**
40 * Creating a new ECS with null Executor throw NPE
41 */
42 public void testConstructorNPE() {
43 try {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010044 new ExecutorCompletionService(null);
Calin Juravle8f0d92b2013-08-01 17:26:00 +010045 shouldThrow();
46 } catch (NullPointerException success) {}
47 }
48
49 /**
50 * Creating a new ECS with null queue throw NPE
51 */
52 public void testConstructorNPE2() {
53 try {
54 ExecutorService e = Executors.newCachedThreadPool();
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010055 new ExecutorCompletionService(e, null);
Calin Juravle8f0d92b2013-08-01 17:26:00 +010056 shouldThrow();
57 } catch (NullPointerException success) {}
58 }
59
60 /**
61 * Submitting a null callable throws NPE
62 */
63 public void testSubmitNPE() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000064 final ExecutorService e = Executors.newCachedThreadPool();
65 final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
66 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010067 Callable c = null;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000068 try {
69 ecs.submit(c);
70 shouldThrow();
71 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +010072 }
73 }
74
75 /**
76 * Submitting a null runnable throws NPE
77 */
78 public void testSubmitNPE2() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000079 final ExecutorService e = Executors.newCachedThreadPool();
80 final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
81 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010082 Runnable r = null;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000083 try {
84 ecs.submit(r, Boolean.TRUE);
85 shouldThrow();
86 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +010087 }
88 }
89
90 /**
91 * A taken submitted task is completed
92 */
93 public void testTake() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000094 final ExecutorService e = Executors.newCachedThreadPool();
95 final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
96 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +010097 Callable c = new StringTask();
98 ecs.submit(c);
99 Future f = ecs.take();
100 assertTrue(f.isDone());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100101 }
102 }
103
104 /**
105 * Take returns the same future object returned by submit
106 */
107 public void testTake2() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000108 final ExecutorService e = Executors.newCachedThreadPool();
109 final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
110 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100111 Callable c = new StringTask();
112 Future f1 = ecs.submit(c);
113 Future f2 = ecs.take();
114 assertSame(f1, f2);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100115 }
116 }
117
118 /**
119 * If poll returns non-null, the returned task is completed
120 */
121 public void testPoll1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000122 final ExecutorService e = Executors.newCachedThreadPool();
123 final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
124 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100125 assertNull(ecs.poll());
126 Callable c = new StringTask();
127 ecs.submit(c);
128
129 long startTime = System.nanoTime();
130 Future f;
131 while ((f = ecs.poll()) == null) {
132 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
133 fail("timed out");
134 Thread.yield();
135 }
136 assertTrue(f.isDone());
137 assertSame(TEST_STRING, f.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100138 }
139 }
140
141 /**
142 * If timed poll returns non-null, the returned task is completed
143 */
144 public void testPoll2() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000145 final ExecutorService e = Executors.newCachedThreadPool();
146 final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
147 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100148 assertNull(ecs.poll());
149 Callable c = new StringTask();
150 ecs.submit(c);
151 Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS);
152 if (f != null)
153 assertTrue(f.isDone());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100154 }
155 }
156
157 /**
158 * Submitting to underlying AES that overrides newTaskFor(Callable)
159 * returns and eventually runs Future returned by newTaskFor.
160 */
161 public void testNewTaskForCallable() throws InterruptedException {
162 final AtomicBoolean done = new AtomicBoolean(false);
163 class MyCallableFuture<V> extends FutureTask<V> {
164 MyCallableFuture(Callable<V> c) { super(c); }
165 protected void done() { done.set(true); }
166 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000167 final ExecutorService e =
168 new ThreadPoolExecutor(1, 1,
169 30L, TimeUnit.SECONDS,
170 new ArrayBlockingQueue<Runnable>(1)) {
171 protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) {
172 return new MyCallableFuture<T>(c);
173 }};
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100174 ExecutorCompletionService<String> ecs =
175 new ExecutorCompletionService<String>(e);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000176 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100177 assertNull(ecs.poll());
178 Callable<String> c = new StringTask();
179 Future f1 = ecs.submit(c);
180 assertTrue("submit must return MyCallableFuture",
181 f1 instanceof MyCallableFuture);
182 Future f2 = ecs.take();
183 assertSame("submit and take must return same objects", f1, f2);
184 assertTrue("completed task must have set done", done.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100185 }
186 }
187
188 /**
189 * Submitting to underlying AES that overrides newTaskFor(Runnable,T)
190 * returns and eventually runs Future returned by newTaskFor.
191 */
192 public void testNewTaskForRunnable() throws InterruptedException {
193 final AtomicBoolean done = new AtomicBoolean(false);
194 class MyRunnableFuture<V> extends FutureTask<V> {
195 MyRunnableFuture(Runnable t, V r) { super(t, r); }
196 protected void done() { done.set(true); }
197 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000198 final ExecutorService e =
199 new ThreadPoolExecutor(1, 1,
200 30L, TimeUnit.SECONDS,
201 new ArrayBlockingQueue<Runnable>(1)) {
202 protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) {
203 return new MyRunnableFuture<T>(t, r);
204 }};
205 final ExecutorCompletionService<String> ecs =
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100206 new ExecutorCompletionService<String>(e);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000207 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100208 assertNull(ecs.poll());
209 Runnable r = new NoOpRunnable();
210 Future f1 = ecs.submit(r, null);
211 assertTrue("submit must return MyRunnableFuture",
212 f1 instanceof MyRunnableFuture);
213 Future f2 = ecs.take();
214 assertSame("submit and take must return same objects", f1, f2);
215 assertTrue("completed task must have set done", done.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100216 }
217 }
218
219}