package org.threadly.concurrent.wrapper.limiter; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.threadly.TestConstants.TEST_QTY; import java.util.concurrent.RejectedExecutionException; import org.junit.Test; import org.threadly.concurrent.AbstractSubmitterScheduler; import org.threadly.concurrent.DoNothingRunnable; import org.threadly.concurrent.PrioritySchedulerTest.PrioritySchedulerFactory; import org.threadly.concurrent.SubmitterExecutor; import org.threadly.concurrent.SubmitterScheduler; import org.threadly.concurrent.SubmitterSchedulerInterfaceTest; import org.threadly.test.concurrent.TestableScheduler; @SuppressWarnings("javadoc") public class SubmitterSchedulerQueueLimitRejectorTest extends SubmitterSchedulerInterfaceTest { @Override protected SubmitterSchedulerFactory getSubmitterSchedulerFactory() { return new SubmitterSchedulerQueueRejectorFactory(); } @Override protected boolean isSingleThreaded() { return true; // not single threaded, but limit might cause execution delay } @SuppressWarnings("unused") @Test (expected = IllegalArgumentException.class) public void constructorFail() { new SubmitterSchedulerQueueLimitRejector(null, TEST_QTY); } @Test public void getQueuedTaskCountTest() { TestableScheduler testableScheduler = new TestableScheduler(); SchedulerServiceQueueLimitRejector queueRejector = new SchedulerServiceQueueLimitRejector(testableScheduler, TEST_QTY); for (int i = 0; i < TEST_QTY; i++) { assertEquals(i, queueRejector.getQueuedTaskCount()); queueRejector.execute(DoNothingRunnable.instance()); } testableScheduler.tick(); assertEquals(0, queueRejector.getQueuedTaskCount()); } @Test public void getSetQueueLimitTest() { TestableScheduler testableScheduler = new TestableScheduler(); SubmitterSchedulerQueueLimitRejector queueRejector = new SubmitterSchedulerQueueLimitRejector(testableScheduler, TEST_QTY); assertEquals(TEST_QTY, queueRejector.getQueueLimit()); queueRejector.setQueueLimit(TEST_QTY * 2); assertEquals(TEST_QTY * 2, queueRejector.getQueueLimit()); } @Test public void rejectTest() { TestableScheduler testableScheduler = new TestableScheduler(); SubmitterSchedulerQueueLimitRejector queueRejector = new SubmitterSchedulerQueueLimitRejector(testableScheduler, TEST_QTY); for (int i = 0; i < TEST_QTY; i++) { queueRejector.execute(DoNothingRunnable.instance()); } try { queueRejector.execute(DoNothingRunnable.instance()); fail("Exception should have thrown"); } catch (RejectedExecutionException e) { // expected } // verify the task was never added assertEquals(TEST_QTY, testableScheduler.tick()); // we should be able to add again now for (int i = 0; i < TEST_QTY; i++) { queueRejector.execute(DoNothingRunnable.instance()); } } @Test public void rejectedExecutionExceptionCountTest() { SubmitterSchedulerQueueLimitRejector queueRejector = new SubmitterSchedulerQueueLimitRejector(new AbstractSubmitterScheduler() { @Override public void scheduleWithFixedDelay(Runnable task, long initialDelay, long recurringDelay) { throw new UnsupportedOperationException(); } @Override public void scheduleAtFixedRate(Runnable task, long initialDelay, long period) { throw new UnsupportedOperationException(); } @Override protected void doSchedule(Runnable task, long delayInMillis) { throw new RejectedExecutionException(); } }, TEST_QTY); try { queueRejector.schedule(DoNothingRunnable.instance(), 1000); fail("Exception should have thrown"); } catch (RejectedExecutionException e) { // expected } assertEquals(0, queueRejector.getQueuedTaskCount()); } private static class SubmitterSchedulerQueueRejectorFactory implements SubmitterSchedulerFactory { private final PrioritySchedulerFactory schedulerFactory = new PrioritySchedulerFactory(); @Override public SubmitterExecutor makeSubmitterExecutor(int poolSize, boolean prestartIfAvailable) { return makeSubmitterScheduler(poolSize, prestartIfAvailable); } @Override public SubmitterScheduler makeSubmitterScheduler(int poolSize, boolean prestartIfAvailable) { SubmitterScheduler scheduler = schedulerFactory.makeSubmitterScheduler(poolSize, prestartIfAvailable); return new SubmitterSchedulerQueueLimitRejector(scheduler, Integer.MAX_VALUE); } @Override public void shutdown() { schedulerFactory.shutdown(); } } }