ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ScheduledExecutorSubclassTest.java (file contents):
Revision 1.54 by jsr166, Tue Oct 6 05:30:44 2015 UTC vs.
Revision 1.63 by jsr166, Wed Dec 21 02:14:06 2016 UTC

# Line 5 | Line 5
5   */
6  
7   import static java.util.concurrent.TimeUnit.MILLISECONDS;
8 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
9   import static java.util.concurrent.TimeUnit.SECONDS;
10  
11   import java.util.ArrayList;
# Line 16 | Line 17 | import java.util.concurrent.Cancellation
17   import java.util.concurrent.CountDownLatch;
18   import java.util.concurrent.Delayed;
19   import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Executors;
20   import java.util.concurrent.ExecutorService;
21   import java.util.concurrent.Future;
22   import java.util.concurrent.RejectedExecutionException;
# Line 28 | Line 28 | import java.util.concurrent.ThreadFactor
28   import java.util.concurrent.ThreadPoolExecutor;
29   import java.util.concurrent.TimeoutException;
30   import java.util.concurrent.TimeUnit;
31 + import java.util.concurrent.atomic.AtomicBoolean;
32   import java.util.concurrent.atomic.AtomicInteger;
33 + import java.util.concurrent.atomic.AtomicLong;
34  
35   import junit.framework.Test;
36   import junit.framework.TestSuite;
# Line 42 | Line 44 | public class ScheduledExecutorSubclassTe
44      }
45  
46      static class CustomTask<V> implements RunnableScheduledFuture<V> {
47 <        RunnableScheduledFuture<V> task;
47 >        private final RunnableScheduledFuture<V> task;
48          volatile boolean ran;
49 <        CustomTask(RunnableScheduledFuture<V> t) { task = t; }
49 >        CustomTask(RunnableScheduledFuture<V> task) { this.task = task; }
50          public boolean isPeriodic() { return task.isPeriodic(); }
51          public void run() {
52              ran = true;
# Line 199 | Line 201 | public class ScheduledExecutorSubclassTe
201      }
202  
203      /**
204 <     * scheduleAtFixedRate executes series of tasks at given rate
204 >     * scheduleAtFixedRate executes series of tasks at given rate.
205 >     * Eventually, it must hold that:
206 >     *   cycles - 1 <= elapsedMillis/delay < cycles
207       */
208      public void testFixedRateSequence() throws InterruptedException {
209          final CustomExecutor p = new CustomExecutor(1);
210          try (PoolCleaner cleaner = cleaner(p)) {
211              for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
212 <                long startTime = System.nanoTime();
213 <                int cycles = 10;
212 >                final long startTime = System.nanoTime();
213 >                final int cycles = 8;
214                  final CountDownLatch done = new CountDownLatch(cycles);
215 <                Runnable task = new CheckedRunnable() {
215 >                final Runnable task = new CheckedRunnable() {
216                      public void realRun() { done.countDown(); }};
217 <                ScheduledFuture h =
217 >                final ScheduledFuture periodicTask =
218                      p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
219 <                await(done);
220 <                h.cancel(true);
221 <                double normalizedTime =
222 <                    (double) millisElapsedSince(startTime) / delay;
223 <                if (normalizedTime >= cycles - 1 &&
224 <                    normalizedTime <= cycles)
219 >                final int totalDelayMillis = (cycles - 1) * delay;
220 >                await(done, totalDelayMillis + LONG_DELAY_MS);
221 >                periodicTask.cancel(true);
222 >                final long elapsedMillis = millisElapsedSince(startTime);
223 >                assertTrue(elapsedMillis >= totalDelayMillis);
224 >                if (elapsedMillis <= cycles * delay)
225                      return;
226 +                // else retry with longer delay
227              }
228 <            throw new AssertionError("unexpected execution rate");
228 >            fail("unexpected execution rate");
229          }
230      }
231  
232      /**
233 <     * scheduleWithFixedDelay executes series of tasks with given period
233 >     * scheduleWithFixedDelay executes series of tasks with given period.
234 >     * Eventually, it must hold that each task starts at least delay and at
235 >     * most 2 * delay after the termination of the previous task.
236       */
237      public void testFixedDelaySequence() throws InterruptedException {
238          final CustomExecutor p = new CustomExecutor(1);
239          try (PoolCleaner cleaner = cleaner(p)) {
240              for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
241 <                long startTime = System.nanoTime();
242 <                int cycles = 10;
241 >                final long startTime = System.nanoTime();
242 >                final AtomicLong previous = new AtomicLong(startTime);
243 >                final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
244 >                final int cycles = 8;
245                  final CountDownLatch done = new CountDownLatch(cycles);
246 <                Runnable task = new CheckedRunnable() {
247 <                    public void realRun() { done.countDown(); }};
248 <                ScheduledFuture h =
246 >                final int d = delay;
247 >                final Runnable task = new CheckedRunnable() {
248 >                    public void realRun() {
249 >                        long now = System.nanoTime();
250 >                        long elapsedMillis
251 >                            = NANOSECONDS.toMillis(now - previous.get());
252 >                        if (done.getCount() == cycles) { // first execution
253 >                            if (elapsedMillis >= d)
254 >                                tryLongerDelay.set(true);
255 >                        } else {
256 >                            assertTrue(elapsedMillis >= d);
257 >                            if (elapsedMillis >= 2 * d)
258 >                                tryLongerDelay.set(true);
259 >                        }
260 >                        previous.set(now);
261 >                        done.countDown();
262 >                    }};
263 >                final ScheduledFuture periodicTask =
264                      p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
265 <                await(done);
266 <                h.cancel(true);
267 <                double normalizedTime =
268 <                    (double) millisElapsedSince(startTime) / delay;
269 <                if (normalizedTime >= cycles - 1 &&
270 <                    normalizedTime <= cycles)
265 >                final int totalDelayMillis = (cycles - 1) * delay;
266 >                await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
267 >                periodicTask.cancel(true);
268 >                final long elapsedMillis = millisElapsedSince(startTime);
269 >                assertTrue(elapsedMillis >= totalDelayMillis);
270 >                if (!tryLongerDelay.get())
271                      return;
272 +                // else retry with longer delay
273              }
274 <            throw new AssertionError("unexpected execution rate");
274 >            fail("unexpected execution rate");
275          }
276      }
277  
# Line 601 | Line 626 | public class ScheduledExecutorSubclassTe
626       * getQueue returns the work queue, which contains queued tasks
627       */
628      public void testGetQueue() throws InterruptedException {
629 +        final CountDownLatch done = new CountDownLatch(1);
630          final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
631 <        try (PoolCleaner cleaner = cleaner(p)) {
631 >        try (PoolCleaner cleaner = cleaner(p, done)) {
632              final CountDownLatch threadStarted = new CountDownLatch(1);
607            final CountDownLatch done = new CountDownLatch(1);
633              ScheduledFuture[] tasks = new ScheduledFuture[5];
634              for (int i = 0; i < tasks.length; i++) {
635                  Runnable r = new CheckedRunnable() {
# Line 618 | Line 643 | public class ScheduledExecutorSubclassTe
643              BlockingQueue<Runnable> q = p.getQueue();
644              assertTrue(q.contains(tasks[tasks.length - 1]));
645              assertFalse(q.contains(tasks[0]));
621            done.countDown();
646          }
647      }
648  
# Line 626 | Line 650 | public class ScheduledExecutorSubclassTe
650       * remove(task) removes queued task, and fails to remove active task
651       */
652      public void testRemove() throws InterruptedException {
653 +        final CountDownLatch done = new CountDownLatch(1);
654          final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
655 <        try (PoolCleaner cleaner = cleaner(p)) {
655 >        try (PoolCleaner cleaner = cleaner(p, done)) {
656              ScheduledFuture[] tasks = new ScheduledFuture[5];
657              final CountDownLatch threadStarted = new CountDownLatch(1);
633            final CountDownLatch done = new CountDownLatch(1);
658              for (int i = 0; i < tasks.length; i++) {
659                  Runnable r = new CheckedRunnable() {
660                      public void realRun() throws InterruptedException {
# Line 650 | Line 674 | public class ScheduledExecutorSubclassTe
674              assertTrue(q.contains((Runnable)tasks[3]));
675              assertTrue(p.remove((Runnable)tasks[3]));
676              assertFalse(q.contains((Runnable)tasks[3]));
653            done.countDown();
677          }
678      }
679  
# Line 1099 | Line 1122 | public class ScheduledExecutorSubclassTe
1122      public void testTimedInvokeAny4() throws Exception {
1123          final ExecutorService e = new CustomExecutor(2);
1124          try (PoolCleaner cleaner = cleaner(e)) {
1125 +            long startTime = System.nanoTime();
1126              List<Callable<String>> l = new ArrayList<Callable<String>>();
1127              l.add(new NPETask());
1128              try {
1129 <                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1129 >                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1130                  shouldThrow();
1131              } catch (ExecutionException success) {
1132                  assertTrue(success.getCause() instanceof NullPointerException);
1133              }
1134 +            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1135          }
1136      }
1137  
# Line 1116 | Line 1141 | public class ScheduledExecutorSubclassTe
1141      public void testTimedInvokeAny5() throws Exception {
1142          final ExecutorService e = new CustomExecutor(2);
1143          try (PoolCleaner cleaner = cleaner(e)) {
1144 +            long startTime = System.nanoTime();
1145              List<Callable<String>> l = new ArrayList<Callable<String>>();
1146              l.add(new StringTask());
1147              l.add(new StringTask());
1148 <            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1148 >            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1149              assertSame(TEST_STRING, result);
1150 +            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1151          }
1152      }
1153  
# Line 1220 | Line 1247 | public class ScheduledExecutorSubclassTe
1247       * timed invokeAll(c) cancels tasks not completed by timeout
1248       */
1249      public void testTimedInvokeAll6() throws Exception {
1250 <        final ExecutorService e = new CustomExecutor(2);
1251 <        try (PoolCleaner cleaner = cleaner(e)) {
1252 <            for (long timeout = timeoutMillis();;) {
1250 >        for (long timeout = timeoutMillis();;) {
1251 >            final CountDownLatch done = new CountDownLatch(1);
1252 >            final Callable<String> waiter = new CheckedCallable<String>() {
1253 >                public String realCall() {
1254 >                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
1255 >                    catch (InterruptedException ok) {}
1256 >                    return "1"; }};
1257 >            final ExecutorService p = new CustomExecutor(2);
1258 >            try (PoolCleaner cleaner = cleaner(p, done)) {
1259                  List<Callable<String>> tasks = new ArrayList<>();
1260                  tasks.add(new StringTask("0"));
1261 <                tasks.add(Executors.callable(new LongPossiblyInterruptedRunnable(), TEST_STRING));
1261 >                tasks.add(waiter);
1262                  tasks.add(new StringTask("2"));
1263                  long startTime = System.nanoTime();
1264                  List<Future<String>> futures =
1265 <                    e.invokeAll(tasks, timeout, MILLISECONDS);
1265 >                    p.invokeAll(tasks, timeout, MILLISECONDS);
1266                  assertEquals(tasks.size(), futures.size());
1267                  assertTrue(millisElapsedSince(startTime) >= timeout);
1268                  for (Future future : futures)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines