package org.threadly.concurrent.wrapper.limiter; import static org.junit.Assert.*; import org.junit.Test; import org.threadly.BlockingTestRunnable; import org.threadly.concurrent.PriorityScheduler; import org.threadly.concurrent.PrioritySchedulerTest.PrioritySchedulerFactory; import org.threadly.concurrent.SchedulerService; import org.threadly.concurrent.SchedulerServiceInterfaceTest.SchedulerServiceFactory; import org.threadly.concurrent.StrictPriorityScheduler; import org.threadly.concurrent.SubmitterExecutor; import org.threadly.concurrent.SubmitterScheduler; import org.threadly.concurrent.TestCallable; import org.threadly.test.concurrent.TestRunnable; @SuppressWarnings("javadoc") public class SchedulerServiceLimiterTest extends SubmitterSchedulerLimiterTest { @Override protected SchedulerServiceLimiter getLimiter(int parallelCount) { return new SchedulerServiceLimiter(scheduler, parallelCount); } @Override protected SubmitterExecutorFactory getSubmitterExecutorFactory() { return new SchedulerLimiterFactory(); } @Test @Override @SuppressWarnings("unused") public void constructorFail() { try { new SchedulerServiceLimiter(null, 100); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } try { new SchedulerServiceLimiter(scheduler, 0); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } } @Test public void removeRunnableFromQueueTest() { BlockingTestRunnable btr = new BlockingTestRunnable(); try { SchedulerServiceLimiter limiter = getLimiter(1); limiter.execute(btr); TestRunnable tr = new TestRunnable(); assertFalse(limiter.remove(tr)); limiter.submit(tr); // verify it is in queue assertTrue(limiter.waitingTasks.size() >= 1); assertTrue(limiter.remove(tr)); } finally { btr.unblock(); } } @Test public void removeCallableFromQueueTest() { BlockingTestRunnable btr = new BlockingTestRunnable(); try { SchedulerServiceLimiter limiter = getLimiter(1); limiter.execute(btr); TestCallable tc = new TestCallable(); assertFalse(limiter.remove(tc)); limiter.submit(tc); // verify it is in queue assertTrue(limiter.waitingTasks.size() >= 1); assertTrue(limiter.remove(tc)); } finally { btr.unblock(); } } @Test public void isShutdownTest() { PriorityScheduler executor = new StrictPriorityScheduler(1); try { SchedulerServiceLimiter limiter = new SchedulerServiceLimiter(executor, 1); assertFalse(limiter.isShutdown()); executor.shutdownNow(); assertTrue(limiter.isShutdown()); } finally { executor.shutdownNow(); } } protected static class SchedulerLimiterFactory implements SchedulerServiceFactory { private final PrioritySchedulerFactory schedulerFactory; private final int minLimiterAmount; protected SchedulerLimiterFactory() { this(Integer.MAX_VALUE); } private SchedulerLimiterFactory(int minLimiterAmount) { schedulerFactory = new PrioritySchedulerFactory(); this.minLimiterAmount = minLimiterAmount; } @Override public void shutdown() { schedulerFactory.shutdown(); } @Override public SubmitterExecutor makeSubmitterExecutor(int poolSize, boolean prestartIfAvailable) { return makeSchedulerService(poolSize, prestartIfAvailable); } @Override public SubmitterScheduler makeSubmitterScheduler(int poolSize, boolean prestartIfAvailable) { return makeSchedulerService(poolSize, prestartIfAvailable); } @Override public SchedulerService makeSchedulerService(int poolSize, boolean prestartIfAvailable) { SchedulerService scheduler = schedulerFactory.makeSchedulerService(poolSize, prestartIfAvailable); int limiterAmount = Math.min(minLimiterAmount, poolSize); return new SchedulerServiceLimiter(scheduler, limiterAmount); } } }