Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix in tests: Thread.yield() scheduled locked threads + improvements

  • Loading branch information...
commit 784d1d6ac1e21705976ff7fdfb1d6ea52f51d613 1 parent 99b436e
@Tibor17 authored
View
107 src/main/java/org/junit/experimental/ParallelComputer.java
@@ -19,7 +19,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Queue;
-
import org.junit.runner.Computer;
import org.junit.runner.Description;
import org.junit.runner.Runner;
@@ -102,12 +101,12 @@
//set if a pool is shut down externally
private final AtomicBoolean fIsShutDown;
- // disables the callers Thread for scheduling purposes until all classes finished
+ // Used if fHasSinglePoll is set. Disables this Thread for scheduling purposes until all classes finished.
private volatile CountDownLatch fClassesFinisher;
// prevents thread resources exhaustion on classes when used with single pool => gives a chance to parallelize methods
// see fSinglePoolMinConcurrentMethods above
- // used in #parallelize(): allows a number of parallel classes and methods
+ // used in #tryParallelize(): allows a number of parallel classes and methods
private volatile Semaphore fSinglePoolBalancer;
// fClassesFinisher is initialized with this value, see #getSuite() and #getParent()
@@ -175,9 +174,9 @@ private ParallelComputer(ExecutorService poolClasses, ExecutorService poolMethod
throw new IllegalArgumentException("min concurrent methods " + fSinglePoolMinConcurrentMethods + " should be >= 1");
if (fHasSinglePoll && fSinglePoolMinConcurrentMethods >= fSinglePoolMaxSize)
throw new IllegalArgumentException("min methods pool size should be less than max pool size");
- fBeforeShutdown= new ConcurrentLinkedQueue<Description>();
- fIsShutDown= new AtomicBoolean();
addDefaultShutdownHandler();
+ fBeforeShutdown= new ConcurrentLinkedQueue<Description>();
+ fIsShutDown= new AtomicBoolean(false);
}
public static Computer classes() {
@@ -265,34 +264,27 @@ public static ParallelComputer classesAndMethods(ExecutorService poolClasses, Ex
return new ParallelComputer(poolClasses, poolMethods);
}
- private Runner sequencer(final ParentRunner runner) {
- runner.setScheduler(new RunnerScheduler() {
- public void schedule(Runnable childStatement) {
- if (fIsShutDown.get()) return;
- childStatement.run();
- fBeforeShutdown.add(runner.getDescription());
- }
-
- public void finished() {
- if (fClassesFinisher != null) fClassesFinisher.countDown();
- }
- });
- return runner;
- }
-
- private Runner parallelize(final ParentRunner runner, final ExecutorService service, final boolean isClassPool) {
+ /**
+ * @return <tt>true</tt> if a parallel scheduler is set in the <tt>runner</tt>
+ */
+ private boolean tryParallelize(final ParentRunner runner, final ExecutorService service, final boolean isClasses) {
runner.setScheduler(new RunnerScheduler() {
- private final ConcurrentLinkedQueue<Future<?>> fTaskFutures
- = !isClassPool & fProvidedPools ? new ConcurrentLinkedQueue<Future<?>>() : null;
+ private final ConcurrentLinkedQueue<Future<?>> fMethodsFutures
+ = !isClasses & fProvidedPools & fParallelMethods ? new ConcurrentLinkedQueue<Future<?>>() : null;
public void schedule(Runnable childStatement) {
if (fIsShutDown.get()) return;
- if (isClassPool & fHasSinglePoll) fSinglePoolBalancer.acquireUninterruptibly();
+ if (isClasses & fHasSinglePoll) fSinglePoolBalancer.acquireUninterruptibly();
if (fIsShutDown.get()) return;
try {
- Future<?> f= service.submit(childStatement);
- fBeforeShutdown.add(runner.getDescription());
- if (!isClassPool & fProvidedPools) fTaskFutures.add(f);
+ if (service == null) {
+ fBeforeShutdown.add(runner.getDescription());
+ childStatement.run();
+ } else {
+ Future<?> f= service.submit(childStatement);
+ if (!isClasses & fProvidedPools & fParallelMethods) fMethodsFutures.add(f);
+ fBeforeShutdown.add(runner.getDescription());
+ }
} catch (RejectedExecutionException e) {
/*after external shut down*/
shutdownQuietly(false);
@@ -300,21 +292,22 @@ public void schedule(Runnable childStatement) {
}
public void finished() {
- if (isClassPool) { //wait until all test cases finished
- if (fProvidedPools) awaitClassesFinished();
+ if (isClasses) { //wait until all test cases finished
+ awaitClassesFinished();
tryFinish(service);
} else { //wait until the test case finished
if (fProvidedPools) {
- awaitClassFinished(fTaskFutures);
+ awaitClassFinished(fMethodsFutures);
if (fHasSinglePoll) fSinglePoolBalancer.release();
} else tryFinish(service);
}
}
});
- return runner;
+ return service != null;
}
private static void tryFinish(ExecutorService pool) {
+ if (pool == null) return;
try {
pool.shutdown();
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
@@ -324,8 +317,7 @@ private static void tryFinish(ExecutorService pool) {
}
@Override
- public Runner getSuite(RunnerBuilder builder, Class<?>[] classes)
- throws InitializationError {
+ public Runner getSuite(RunnerBuilder builder, Class<?>[] classes) throws InitializationError {
Runner suite= super.getSuite(builder, classes);
if (canSchedule(suite)) {
if (fHasSinglePoll) {
@@ -337,20 +329,18 @@ public Runner getSuite(RunnerBuilder builder, Class<?>[] classes)
maxConcurrentClasses= Math.min(maxConcurrentClasses, fCountClasses);
fSinglePoolBalancer= new Semaphore(maxConcurrentClasses);
}
- fClassesFinisher= fProvidedPools ? new CountDownLatch(fCountClasses) : null;
- if (fParallelClasses) parallelize((ParentRunner) suite, threadPoolClasses(), true);
+ fClassesFinisher= fHasSinglePoll ? new CountDownLatch(fCountClasses) : null;
+ tryParallelize((ParentRunner) suite, threadPoolClasses(), true);
}
return suite;
}
@Override
- protected Runner getRunner(RunnerBuilder builder, Class<?> testClass)
- throws Throwable {
+ protected Runner getRunner(RunnerBuilder builder, Class<?> testClass) throws Throwable {
Runner runner= super.getRunner(builder, testClass);
if (canSchedule(runner)) {
++fCountClasses;//incremented without been AtomicInteger because not yet concurrent access
- ParentRunner child= (ParentRunner) runner;
- runner= fParallelMethods ? parallelize(child, threadPoolMethods(), false) : sequencer(child);
+ tryParallelize((ParentRunner) runner, threadPoolMethods(), false);
}
return runner;
}
@@ -380,32 +370,34 @@ private boolean canSchedule(Runner runner) {
}
private ExecutorService threadPoolClasses() {
- return fProvidedPools ? fPoolClasses : newThreadPoolClasses();
+ return !fProvidedPools && fParallelClasses ? newThreadPoolClasses() : fPoolClasses;
}
private ExecutorService threadPoolMethods() {
- return fProvidedPools ? fPoolMethods : newThreadPoolMethods();
+ return !fProvidedPools && fParallelMethods ? newThreadPoolMethods() : fPoolMethods;
}
- private void awaitClassFinished(Queue<Future<?>> children) {
- for (Future<?> child : children) {
- try {
- child.get();
- } catch (InterruptedException e) {
- /*after called external ExecutorService#shutdownNow()*/
- shutdownQuietly(true);
- } catch (ExecutionException e) {
- /*cause fired in run-notifier*/
- } catch (CancellationException e) {
- /*cannot happen because not calling Future#cancel(boolean)*/
+ private void awaitClassFinished(Queue<Future<?>> methodsFutures) {
+ if (methodsFutures != null) {//fParallelMethods is false
+ for (Future<?> methodFuture : methodsFutures) {
+ try {
+ methodFuture.get();
+ } catch (InterruptedException e) {
+ /*after called external ExecutorService#shutdownNow()*/
+ shutdownQuietly(true);
+ } catch (ExecutionException e) {
+ /*cause fired in run-notifier*/
+ } catch (CancellationException e) {
+ /*cannot happen because not calling Future#cancel(boolean)*/
+ }
}
}
- fClassesFinisher.countDown();
+ if (fHasSinglePoll) fClassesFinisher.countDown();
}
private void awaitClassesFinished() {
try {
- fClassesFinisher.await();
+ if (fHasSinglePoll) fClassesFinisher.await();
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
@@ -431,12 +423,10 @@ private void setDefaultShutdownHandler(Executor executor) {
*/
private void shutdownQuietly(boolean shutdownNow) {
try {
- if (fIsShutDown.compareAndSet(false, true) && fCountClasses > 0) {//let other threads avoid submitting new tasks
- if (fHasSinglePoll) {
+ if (fIsShutDown.compareAndSet(false, true)) {//let other threads avoid submitting new tasks
+ if (fHasSinglePoll && fCountClasses > 0) {
//let dormant class-threads wake up and escape from balancer
fSinglePoolBalancer.release(fCountClasses);
- }
- if (fProvidedPools) {
//cached a value in volatile field to the stack as a constant for faster reads
final CountDownLatch classesFinisher= fClassesFinisher;
//signals that the total num classes could not be reached
@@ -485,7 +475,6 @@ private static void shutdown(ExecutorService pool, boolean shutdownNow) {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (executor.isShutdown()) {
- //keep using false in order to avoid calling pool's methods
shutdownQuietly(false);
}
fPoolHandler.rejectedExecution(r, executor);
View
159 src/test/java/org/junit/tests/experimental/parallel/ParallelComputerShutDownTest.java
@@ -1,57 +1,53 @@
package org.junit.tests.experimental.parallel;
-import org.junit.Test;
-import org.junit.experimental.ParallelComputer;
-import org.junit.runner.JUnitCore;
-import org.junit.runner.Result;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.ParallelComputer;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
- * Testing ParallelComputer when a pool is shut down externally.
+ * Testing ParallelComputer when a pool or parallel computer is shutdown.
*
* @author tibor17
* @since 4.12
*/
public class ParallelComputerShutDownTest {
- private static volatile CountDownLatch fTrigger;
private static volatile boolean fIsShutdown;
private static volatile boolean fShutdown1;
private static volatile boolean fShutdown2;
+ private static volatile Runnable fShutdownTask;
@Rule
- public final TestWrapper testControl= new TestWrapper(250, TimeUnit.MILLISECONDS) {
+ public final TestWrapper testControl= new TestWrapper(500, TimeUnit.MILLISECONDS) {
@Override
boolean isShutdown() {
return fIsShutdown;
}
@Override
- void shutdown() {
- fIsShutdown= true;
- }
-
- @Override
protected void before() {
- fTrigger= new CountDownLatch(1);//triggers shutdown
fIsShutdown= false;
fShutdown1= false;
fShutdown2= false;
super.before();
}
+
+ @Override
+ protected void after() {
+ super.after();
+ fShutdownTask= null;
+ }
};
@Rule
@@ -64,7 +60,7 @@ protected void before() {
public void shutdownHangs() throws InterruptedException {
thrown.handleAssertionErrors().expect(AssertionError.class);
testControl.setComputer(ParallelComputer.classesAndMethodsUnbounded());
- Thread.sleep(350L);
+ Thread.sleep(600L);
fIsShutdown= true;
}
@@ -98,12 +94,9 @@ public void two() {
public static class Shutdown1 {
@Test
- public void one() throws InterruptedException {
+ public void one() {
fShutdown1= true;
- fTrigger.countDown();
- while(!fIsShutdown) {
- Thread.yield();
- }
+ fShutdownTask.run();
}
}
@@ -150,7 +143,7 @@ public void classesAndMethodsShutdownFirstTest() {
new LinkedBlockingQueue<Runnable>());
ParallelComputer computer= ParallelComputer.classesAndMethods(pool, 1);
testControl.setComputer(computer);
- scheduleShutdown(pool);
+ fShutdownTask= createShutdownTask(pool);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -165,7 +158,7 @@ public void classesAndMethodsShutdownNowFirstTest() {
new LinkedBlockingQueue<Runnable>());
ParallelComputer computer= ParallelComputer.classesAndMethods(pool, 1);
testControl.setComputer(computer);
- scheduleShutdownNow(pool);
+ fShutdownTask= createShutdownNowTask(pool);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -180,7 +173,7 @@ public void classesAndMethodsShutdownSecondTest() {
new LinkedBlockingQueue<Runnable>());
ParallelComputer computer= ParallelComputer.classesAndMethods(pool, 1);
testControl.setComputer(computer);
- scheduleShutdown(pool);
+ fShutdownTask= createShutdownTask(pool);
Class<?>[] tests= {Shutdown2.class, Shutdown1.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -195,7 +188,7 @@ public void classesAndMethodsShutdownNowSecondTest() {
new LinkedBlockingQueue<Runnable>());
ParallelComputer computer= ParallelComputer.classesAndMethods(pool, 1);
testControl.setComputer(computer);
- scheduleShutdown(pool);
+ fShutdownTask= createShutdownTask(pool);
Class<?>[] tests= {Shutdown2.class, Shutdown1.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -210,7 +203,7 @@ public void classesAndMethodsSinglePoolShutdown() {
new LinkedBlockingQueue<Runnable>());
ParallelComputer computer= ParallelComputer.classesAndMethods(pool, 3);
testControl.setComputer(computer);
- scheduleShutdown(pool);
+ fShutdownTask= createShutdownTask(pool);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -224,7 +217,7 @@ public void classesAndMethodsSinglePoolShutdownNow() {
new LinkedBlockingQueue<Runnable>());
ParallelComputer computer= ParallelComputer.classesAndMethods(pool, 3);
testControl.setComputer(computer);
- scheduleShutdown(pool);
+ fShutdownTask= createShutdownTask(pool);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -236,7 +229,7 @@ public void classesAndMethodsShutdown() {
ExecutorService classPool= Executors.newFixedThreadPool(3);
ExecutorService methodPool= Executors.newFixedThreadPool(3);
ParallelComputer computer= ParallelComputer.classesAndMethods(classPool, methodPool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -248,7 +241,7 @@ public void classesAndMethodsShutdownNow() {
ExecutorService classPool= Executors.newFixedThreadPool(3);
ExecutorService methodPool= Executors.newFixedThreadPool(3);
ParallelComputer computer= ParallelComputer.classesAndMethods(classPool, methodPool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -259,7 +252,7 @@ public void classesAndMethodsShutdownNow() {
public void classesInfinitePoolShutdown() {
ExecutorService pool= Executors.newCachedThreadPool();
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -270,7 +263,7 @@ public void classesInfinitePoolShutdown() {
public void classesInfinitePoolShutdownNow() {
ExecutorService pool= Executors.newCachedThreadPool();
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -281,7 +274,7 @@ public void classesInfinitePoolShutdownNow() {
public void classesSimplePoolShutdown() {
ExecutorService pool= Executors.newSingleThreadExecutor();
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -292,7 +285,7 @@ public void classesSimplePoolShutdown() {
public void classesSimplePoolShutdownNow() {
ExecutorService pool= Executors.newSingleThreadExecutor();
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -303,7 +296,7 @@ public void classesSimplePoolShutdownNow() {
public void classesShutdown() {
ExecutorService pool= Executors.newFixedThreadPool(2);
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -314,7 +307,7 @@ public void classesShutdown() {
public void classesShutdownNow() {
ExecutorService pool= Executors.newFixedThreadPool(2);
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -325,7 +318,7 @@ public void classesShutdownNow() {
public void classesBigPoolShutdown() {
ExecutorService pool= Executors.newFixedThreadPool(3);
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -336,7 +329,7 @@ public void classesBigPoolShutdown() {
public void classesBigPoolShutdownNow() {
ExecutorService pool= Executors.newFixedThreadPool(3);
ParallelComputer computer= ParallelComputer.classes(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -347,7 +340,7 @@ public void classesBigPoolShutdownNow() {
public void methodsInfinitePoolShutdown1() {
final ExecutorService pool= Executors.newCachedThreadPool();
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -359,7 +352,7 @@ public void methodsInfinitePoolShutdown1() {
public void methodsInfinitePoolShutdown1Now() {
final ExecutorService pool= Executors.newCachedThreadPool();
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -371,7 +364,7 @@ public void methodsInfinitePoolShutdown1Now() {
public void methodsInfinitePoolShutdown2() {
final ExecutorService pool= Executors.newCachedThreadPool();
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown2.class, Shutdown1.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -383,7 +376,7 @@ public void methodsInfinitePoolShutdown2() {
public void methodsInfinitePoolShutdown2Now() {
final ExecutorService pool= Executors.newCachedThreadPool();
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown2.class, Shutdown1.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -395,7 +388,7 @@ public void methodsInfinitePoolShutdown2Now() {
public void methodsSimplePool() {
final ExecutorService pool= Executors.newSingleThreadExecutor();
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -407,7 +400,7 @@ public void methodsSimplePool() {
public void methods() {
ExecutorService pool= Executors.newFixedThreadPool(2);
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -419,7 +412,7 @@ public void methods() {
public void methodsBigPoolShutdown() {
ExecutorService pool= Executors.newFixedThreadPool(3);
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdown(computer);
+ fShutdownTask= createShutdownTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -431,7 +424,7 @@ public void methodsBigPoolShutdown() {
public void methodsBigPoolShutdownNow() {
ExecutorService pool= Executors.newFixedThreadPool(3);
ParallelComputer computer= ParallelComputer.methods(pool);
- scheduleShutdownNow(computer);
+ fShutdownTask= createShutdownNowTask(computer);
Class<?>[] tests= {Shutdown1.class, Shutdown2.class};
Result result= JUnitCore.runClasses(computer, tests);
assertTrue(result.wasSuccessful());
@@ -439,64 +432,38 @@ public void methodsBigPoolShutdownNow() {
assertFalse(fShutdown2);
}
- private static void scheduleShutdown(final ExecutorService pool) {
- Executors.newSingleThreadExecutor().submit(new Callable<Void>() {
- public Void call() throws InterruptedException {
- fTrigger.await();
+ private static Runnable createShutdownTask(final ExecutorService pool) {
+ return new Runnable() {
+ public void run() {
pool.shutdown();
- fIsShutdown = true;
- return null;
+ fIsShutdown= true;
}
- });
+ };
}
- private static void scheduleShutdownNow(final ExecutorService pool) {
- Executors.newSingleThreadExecutor().submit(new Callable<Void>() {
- public Void call() throws InterruptedException {
- fTrigger.await();
+ private static Runnable createShutdownNowTask(final ExecutorService pool) {
+ return new Runnable() {
+ public void run() {
pool.shutdownNow();
fIsShutdown= true;
- return null;
}
- });
- }
-
- private static Future<Void> scheduleShutdown(final ParallelComputer computer) {
- return Executors.newSingleThreadExecutor().submit(new Callable<Void>() {
- public Void call() throws InterruptedException {
- fTrigger.await();
- try {
- computer.shutdown(false);
- return null;
- } finally {
- fIsShutdown= true;
- }
- }
- });
- }
-
- private static Future<Void> scheduleShutdownNow(final ParallelComputer computer) {
- return Executors.newSingleThreadExecutor().submit(new Callable<Void>() {
- public Void call() throws InterruptedException {
- fTrigger.await();
- try {
- computer.shutdown(true);
- return null;
- } finally {
- fIsShutdown= true;
- }
+ };
+ }
+
+ private static Runnable createShutdownTask(final ParallelComputer computer) {
+ return new Runnable() {
+ public void run() {
+ computer.shutdown(false);
+ fIsShutdown= true;
}
- });
+ };
}
- private static Runnable createShutdownWatcher(final ExecutorService... pools) {
+ private static Runnable createShutdownNowTask(final ParallelComputer computer) {
return new Runnable() {
public void run() {
- for (ExecutorService pool : pools) {
- try {
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
- } catch (InterruptedException e) {}
- }
+ computer.shutdown(true);
+ fIsShutdown= true;
}
};
}
View
58 src/test/java/org/junit/tests/experimental/parallel/TestWrapper.java
@@ -1,5 +1,6 @@
package org.junit.tests.experimental.parallel;
+import java.util.concurrent.ScheduledExecutorService;
import org.junit.experimental.ParallelComputer;
import org.junit.rules.ExternalResource;
@@ -15,9 +16,9 @@
* @since 4.12
*/
abstract class TestWrapper extends ExternalResource {
- private Runnable fShutdownWatcher;
- private ScheduledFuture<Boolean> fShutdownElapsed;
- private ParallelComputer fComputer;
+ private ScheduledExecutorService fTimer;
+ private ScheduledFuture<Boolean> fTimerResult;
+ private volatile ParallelComputer fComputer;
//timer's delay after which shutdown the computer
private final long fDelay;
@@ -29,7 +30,6 @@
}
abstract boolean isShutdown();
- abstract void shutdown();
final void setComputer(ParallelComputer computer) {
fComputer= computer;
@@ -37,51 +37,39 @@ final void setComputer(ParallelComputer computer) {
@Override
protected void before() {
- fShutdownElapsed= scheduleShutdownTimer();
+ scheduleShutdownTimer();
}
@Override
protected void after() {
- assertDelayedShutdownNotDone(fShutdownElapsed);
- Runnable shutdownWatcher= fShutdownWatcher;
- fShutdownWatcher= null;
- if (shutdownWatcher != null) shutdownWatcher.run();
+ assertDelayedShutdownNotDone();
}
- private void assertDelayedShutdownNotDone(ScheduledFuture<Boolean> shutdownTimer) {
+ private void assertDelayedShutdownNotDone() {
+ if (fComputer == null) return;
+ if (fTimerResult.isDone()) fail();
+ if (!isShutdown()) fail("why the test returned without any shutdown?");
+ fTimer.shutdownNow();
try {
- if (fComputer == null) return;
- if (shutdownTimer.isDone()) fail();
- if (!isShutdown()) fail("why the test returned without any shutdown?");
- } finally {
- cancel(shutdownTimer);
- }
- }
-
- private void cancel(ScheduledFuture<Boolean> timer) {
- try {
- if (timer.cancel(true)) timer.get();
- } catch (Exception e) {
- }
+ fTimer.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException e) {e.printStackTrace(System.err);}
}
/**
* Releases resources by computer's shutdown after a delay has elapsed
* when pool#shutdown() could not stop the pool in unit tests.
- *
- * @return {@link java.util.concurrent.ScheduledFuture#get()}
- * <tt>false</tt> if computer is already shutdown by other thread
+ * The <tt>fTimerResult#get()</tt> returns <tt>false</tt> if computer
+ * is already shutdown by other thread.
*/
- private ScheduledFuture<Boolean> scheduleShutdownTimer() {
- return Executors.newSingleThreadScheduledExecutor().schedule(new Callable<Boolean>() {
- public Boolean call() throws InterruptedException {
- try {
- if (isShutdown()) return false;
- if (fComputer != null) fComputer.shutdown(true);
- return true;
- } finally {
- shutdown();
+ private void scheduleShutdownTimer() {
+ fTimer= Executors.newSingleThreadScheduledExecutor();
+ fTimerResult= fTimer.schedule(new Callable<Boolean>() {
+ public Boolean call() {
+ if (isShutdown()) return false;
+ if (fComputer != null) {
+ fComputer.shutdown(true);
}
+ return true;
}
}, fDelay, fScale);
}
Please sign in to comment.
Something went wrong with that request. Please try again.