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.49 by jsr166, Mon Oct 5 21:54:33 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 105 | Line 107 | public class ScheduledExecutorSubclassTe
107              final Runnable task = new CheckedRunnable() {
108                  public void realRun() { done.countDown(); }};
109              p.execute(task);
110 <            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
110 >            await(done);
111          }
112      }
113  
# Line 113 | Line 115 | public class ScheduledExecutorSubclassTe
115       * delayed schedule of callable successfully executes after delay
116       */
117      public void testSchedule1() throws Exception {
118 +        final CountDownLatch done = new CountDownLatch(1);
119          final CustomExecutor p = new CustomExecutor(1);
120 <        try (PoolCleaner cleaner = cleaner(p)) {
120 >        try (PoolCleaner cleaner = cleaner(p, done)) {
121              final long startTime = System.nanoTime();
119            final CountDownLatch done = new CountDownLatch(1);
122              Callable task = new CheckedCallable<Boolean>() {
123                  public Boolean realCall() {
124                      done.countDown();
# Line 126 | Line 128 | public class ScheduledExecutorSubclassTe
128              Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
129              assertSame(Boolean.TRUE, f.get());
130              assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
129            assertTrue(done.await(0L, MILLISECONDS));
131          }
132      }
133  
# Line 200 | 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 <                done.await();
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 <                done.await();
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 363 | Line 387 | public class ScheduledExecutorSubclassTe
387       * thread becomes active
388       */
389      public void testGetActiveCount() throws InterruptedException {
390 +        final CountDownLatch done = new CountDownLatch(1);
391          final ThreadPoolExecutor p = new CustomExecutor(2);
392 <        try (PoolCleaner cleaner = cleaner(p)) {
392 >        try (PoolCleaner cleaner = cleaner(p, done)) {
393              final CountDownLatch threadStarted = new CountDownLatch(1);
369            final CountDownLatch done = new CountDownLatch(1);
394              assertEquals(0, p.getActiveCount());
395              p.execute(new CheckedRunnable() {
396                  public void realRun() throws InterruptedException {
397                      threadStarted.countDown();
398                      assertEquals(1, p.getActiveCount());
399 <                    done.await();
399 >                    await(done);
400                  }});
401 <            assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
401 >            await(threadStarted);
402              assertEquals(1, p.getActiveCount());
379            done.countDown();
403          }
404      }
405  
# Line 427 | Line 450 | public class ScheduledExecutorSubclassTe
450       */
451      public void testGetLargestPoolSize() throws InterruptedException {
452          final int THREADS = 3;
453 +        final CountDownLatch done = new CountDownLatch(1);
454          final ThreadPoolExecutor p = new CustomExecutor(THREADS);
455 <        try (PoolCleaner cleaner = cleaner(p)) {
455 >        try (PoolCleaner cleaner = cleaner(p, done)) {
456              final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
433            final CountDownLatch done = new CountDownLatch(1);
457              assertEquals(0, p.getLargestPoolSize());
458              for (int i = 0; i < THREADS; i++)
459                  p.execute(new CheckedRunnable() {
460                      public void realRun() throws InterruptedException {
461                          threadsStarted.countDown();
462 <                        done.await();
462 >                        await(done);
463                          assertEquals(THREADS, p.getLargestPoolSize());
464                      }});
465 <            assertTrue(threadsStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
465 >            await(threadsStarted);
466              assertEquals(THREADS, p.getLargestPoolSize());
444            done.countDown();
467          }
468          assertEquals(THREADS, p.getLargestPoolSize());
469      }
# Line 451 | Line 473 | public class ScheduledExecutorSubclassTe
473       * become active
474       */
475      public void testGetPoolSize() throws InterruptedException {
476 +        final CountDownLatch done = new CountDownLatch(1);
477          final ThreadPoolExecutor p = new CustomExecutor(1);
478 <        try (PoolCleaner cleaner = cleaner(p)) {
478 >        try (PoolCleaner cleaner = cleaner(p, done)) {
479              final CountDownLatch threadStarted = new CountDownLatch(1);
457            final CountDownLatch done = new CountDownLatch(1);
480              assertEquals(0, p.getPoolSize());
481              p.execute(new CheckedRunnable() {
482                  public void realRun() throws InterruptedException {
483                      threadStarted.countDown();
484                      assertEquals(1, p.getPoolSize());
485 <                    done.await();
485 >                    await(done);
486                  }});
487 <            assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
487 >            await(threadStarted);
488              assertEquals(1, p.getPoolSize());
467            done.countDown();
489          }
490      }
491  
# Line 483 | Line 504 | public class ScheduledExecutorSubclassTe
504              p.execute(new CheckedRunnable() {
505                  public void realRun() throws InterruptedException {
506                      threadStarted.countDown();
507 <                    done.await();
507 >                    await(done);
508                  }});
509 <            assertTrue(threadStarted.await(LONG_DELAY_MS, MILLISECONDS));
509 >            await(threadStarted);
510              assertEquals(1, p.getTaskCount());
511              assertEquals(0, p.getCompletedTaskCount());
512              for (int i = 0; i < TASKS; i++) {
# Line 494 | Line 515 | public class ScheduledExecutorSubclassTe
515                      public void realRun() throws InterruptedException {
516                          threadStarted.countDown();
517                          assertEquals(1 + TASKS, p.getTaskCount());
518 <                        done.await();
518 >                        await(done);
519                      }});
520              }
521              assertEquals(1 + TASKS, p.getTaskCount());
# Line 556 | Line 577 | public class ScheduledExecutorSubclassTe
577       * isTerminated is false before termination, true after
578       */
579      public void testIsTerminated() throws InterruptedException {
580 +        final CountDownLatch done = new CountDownLatch(1);
581          final ThreadPoolExecutor p = new CustomExecutor(1);
582          try (PoolCleaner cleaner = cleaner(p)) {
583              final CountDownLatch threadStarted = new CountDownLatch(1);
562            final CountDownLatch done = new CountDownLatch(1);
563            assertFalse(p.isTerminated());
584              p.execute(new CheckedRunnable() {
585                  public void realRun() throws InterruptedException {
586                      assertFalse(p.isTerminated());
587                      threadStarted.countDown();
588 <                    done.await();
588 >                    await(done);
589                  }});
590 <            assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
590 >            await(threadStarted);
591 >            assertFalse(p.isTerminated());
592              assertFalse(p.isTerminating());
593              done.countDown();
594              try { p.shutdown(); } catch (SecurityException ok) { return; }
# Line 580 | Line 601 | public class ScheduledExecutorSubclassTe
601       * isTerminating is not true when running or when terminated
602       */
603      public void testIsTerminating() throws InterruptedException {
604 +        final CountDownLatch done = new CountDownLatch(1);
605          final ThreadPoolExecutor p = new CustomExecutor(1);
606          try (PoolCleaner cleaner = cleaner(p)) {
607              final CountDownLatch threadStarted = new CountDownLatch(1);
586            final CountDownLatch done = new CountDownLatch(1);
608              assertFalse(p.isTerminating());
609              p.execute(new CheckedRunnable() {
610                  public void realRun() throws InterruptedException {
611                      assertFalse(p.isTerminating());
612                      threadStarted.countDown();
613 <                    done.await();
613 >                    await(done);
614                  }});
615 <            assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
615 >            await(threadStarted);
616              assertFalse(p.isTerminating());
617              done.countDown();
618              try { p.shutdown(); } catch (SecurityException ok) { return; }
# Line 605 | 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);
611            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() {
636                      public void realRun() throws InterruptedException {
637                          threadStarted.countDown();
638 <                        done.await();
638 >                        await(done);
639                      }};
640                  tasks[i] = p.schedule(r, 1, MILLISECONDS);
641              }
642 <            assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
642 >            await(threadStarted);
643              BlockingQueue<Runnable> q = p.getQueue();
644              assertTrue(q.contains(tasks[tasks.length - 1]));
645              assertFalse(q.contains(tasks[0]));
625            done.countDown();
646          }
647      }
648  
# Line 630 | 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);
637            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 {
661                          threadStarted.countDown();
662 <                        done.await();
662 >                        await(done);
663                      }};
664                  tasks[i] = p.schedule(r, 1, MILLISECONDS);
665              }
666 <            assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
666 >            await(threadStarted);
667              BlockingQueue<Runnable> q = p.getQueue();
668              assertFalse(p.remove((Runnable)tasks[0]));
669              assertTrue(q.contains((Runnable)tasks[4]));
# Line 654 | 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]));
657            done.countDown();
677          }
678      }
679  
# Line 706 | Line 725 | public class ScheduledExecutorSubclassTe
725          }};
726          for (int i = 0; i < count; i++)
727              p.execute(waiter);
728 <        assertTrue(threadsStarted.await(LONG_DELAY_MS, MILLISECONDS));
728 >        await(threadsStarted);
729          assertEquals(poolSize, p.getActiveCount());
730          assertEquals(0, p.getCompletedTaskCount());
731          final List<Runnable> queuedTasks;
# Line 1103 | 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 1120 | 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 1224 | 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