package org.jgroups.tests;
import org.jgroups.Global;
import org.jgroups.util.NoProgressException;
import org.jgroups.util.Util;
import org.testng.annotations.Test;
import java.util.concurrent.*;
/**
* @author Bela Ban
*/
@Test(groups=Global.FUNCTIONAL,singleThreaded=true)
public class RejectionPoliciesTest {
public void testCustomPolicy() {
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, queue);
RejectedExecutionHandler handler = Util.parseRejectionPolicy("custom=org.jgroups.tests.RejectionPoliciesTest$FooPolicy");
executor.setRejectedExecutionHandler(handler);
BlockingRunnable blocker = new BlockingRunnable();
executor.execute(blocker);
try {
executor.execute(new NorunRunnable());
assert false;
} catch (FooException foo) {
} catch (Throwable t) {
assert false;
} finally {
blocker.stop = true;
}
}
public void testDeadlockDetectionPolicy1() {
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, queue);
RejectedExecutionHandler handler = Util.parseRejectionPolicy("progress_check");
executor.setRejectedExecutionHandler(handler);
BlockingRunnable blocker = new BlockingRunnable();
executor.execute(blocker);
executor.execute(new NorunRunnable()); // should silently fail
try {
Thread.sleep(11000);
} catch (InterruptedException e) {
assert false;
}
try {
executor.execute(new NorunRunnable());
assert false;
} catch (NoProgressException e) {
} catch (Throwable t) {
assert false;
} finally {
blocker.stop = true;
}
}
public void testDeadlockDetectionPolicy2() {
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, queue);
RejectedExecutionHandler handler = Util.parseRejectionPolicy(
"progress_check=period:15000,fallback:custom=org.jgroups.tests.RejectionPoliciesTest$FooPolicy");
executor.setRejectedExecutionHandler(handler);
BlockingRunnable blocker = new BlockingRunnable();
executor.execute(blocker);
try {
executor.execute(new NorunRunnable()); // should fail with fallback = FooPolicy
assert false;
} catch (FooException foo) {
} catch (Throwable t) {
assert false;
}
try {
Thread.sleep(11000);
} catch (InterruptedException e) {
assert false;
}
try {
executor.execute(new NorunRunnable()); // non-default period: still FooPolicy
assert false;
} catch (FooException foo) {
} catch (Throwable t) {
assert false;
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
assert false;
}
try {
executor.execute(new NorunRunnable());
assert false;
} catch (NoProgressException e) {
} catch (Throwable t) {
assert false;
} finally {
blocker.stop = true;
}
}
public static class FooPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
throw new FooException();
}
}
public static class FooException extends RuntimeException {}
public static class BlockingRunnable implements Runnable {
public volatile boolean stop = false;
@Override
public void run() {
while (!stop) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
}
}
public static class NorunRunnable implements Runnable {
@Override
public void run() {
assert false; // this shouldn't be executed
}
}
}