package org.redisson.executor; import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.redisson.BaseTest; import static org.redisson.BaseTest.createConfig; import org.redisson.RedissonNode; import org.redisson.RedissonRuntimeEnvironment; import org.redisson.api.RExecutorService; import org.redisson.api.RScheduledExecutorService; import org.redisson.config.Config; import org.redisson.config.RedissonNodeConfig; public class RedissonExecutorServiceTest extends BaseTest { private static RedissonNode node; @BeforeClass public static void beforeClass() throws IOException, InterruptedException { BaseTest.beforeClass(); if (!RedissonRuntimeEnvironment.isTravis) { Config config = createConfig(); RedissonNodeConfig nodeConfig = new RedissonNodeConfig(config); nodeConfig.setExecutorServiceWorkers(Collections.singletonMap("test", 1)); node = RedissonNode.create(nodeConfig); node.start(); } } @AfterClass public static void afterClass() throws IOException, InterruptedException { BaseTest.afterClass(); if (!RedissonRuntimeEnvironment.isTravis) { node.shutdown(); } } @Before @Override public void before() throws IOException, InterruptedException { super.before(); if (RedissonRuntimeEnvironment.isTravis) { Config config = createConfig(); RedissonNodeConfig nodeConfig = new RedissonNodeConfig(config); nodeConfig.setExecutorServiceWorkers(Collections.singletonMap("test", 1)); node = RedissonNode.create(nodeConfig); node.start(); } } @After @Override public void after() throws InterruptedException { super.after(); if (RedissonRuntimeEnvironment.isTravis) { node.shutdown(); } } private void cancel(ScheduledFuture<?> future1) throws InterruptedException, ExecutionException { assertThat(future1.cancel(true)).isTrue(); boolean canceled = false; try { future1.get(); } catch (CancellationException e) { canceled = true; } assertThat(canceled).isTrue(); } @Test public void testShutdownWithCancelAndOfflineExecutor() throws InterruptedException, ExecutionException { RScheduledExecutorService executor = redisson.getExecutorService("test2"); ScheduledFuture<?> future1 = executor.schedule(new RunnableRedissonTask("executed1"), 1, TimeUnit.SECONDS); cancel(future1); Thread.sleep(2000); assertThat(redisson.getAtomicLong("executed1").isExists()).isFalse(); assertThat(executor.delete()).isFalse(); } @Test public void testMultipleTasks() throws InterruptedException, ExecutionException, TimeoutException { RExecutorService e = redisson.getExecutorService("test"); e.execute(new RunnableTask()); Future<?> f = e.submit(new RunnableTask2()); f.get(); Future<String> fs = e.submit(new CallableTask()); assertThat(fs.get()).isEqualTo(CallableTask.RESULT); Future<Integer> f2 = e.submit(new RunnableTask(), 12); assertThat(f2.get()).isEqualTo(12); String invokeResult = e.invokeAny(Arrays.asList(new CallableTask(), new CallableTask(), new CallableTask())); assertThat(invokeResult).isEqualTo(CallableTask.RESULT); String a = e.invokeAny(Arrays.asList(new CallableTask(), new CallableTask(), new CallableTask()), 5, TimeUnit.SECONDS); assertThat(a).isEqualTo(CallableTask.RESULT); List<CallableTask> invokeAllParams = Arrays.asList(new CallableTask(), new CallableTask(), new CallableTask()); List<Future<String>> allResult = e.invokeAll(invokeAllParams); assertThat(allResult).hasSize(invokeAllParams.size()); for (Future<String> future : allResult) { assertThat(future.get()).isEqualTo(CallableTask.RESULT); } List<CallableTask> invokeAllParams1 = Arrays.asList(new CallableTask(), new CallableTask(), new CallableTask()); List<Future<String>> allResult1 = e.invokeAll(invokeAllParams1, 5, TimeUnit.SECONDS); assertThat(allResult1).hasSize(invokeAllParams.size()); for (Future<String> future : allResult1) { assertThat(future.get()).isEqualTo(CallableTask.RESULT); } } @Test(expected = RejectedExecutionException.class) public void testRejectExecute() throws InterruptedException, ExecutionException { RExecutorService e = redisson.getExecutorService("test"); e.execute(new RunnableTask()); Future<?> f1 = e.submit(new RunnableTask2()); Future<String> f2 = e.submit(new CallableTask()); e.shutdown(); f1.get(); assertThat(f2.get()).isEqualTo(CallableTask.RESULT); assertThat(e.isShutdown()).isTrue(); e.execute(new RunnableTask()); } @Test(expected = RejectedExecutionException.class) public void testRejectSubmitRunnable() throws InterruptedException, ExecutionException { RExecutorService e = redisson.getExecutorService("test"); e.execute(new RunnableTask()); Future<?> f1 = e.submit(new RunnableTask2()); Future<String> f2 = e.submit(new CallableTask()); e.shutdown(); f1.get(); assertThat(f2.get()).isEqualTo(CallableTask.RESULT); assertThat(e.isShutdown()).isTrue(); e.submit(new RunnableTask2()); } @Test(expected = RejectedExecutionException.class) public void testRejectSubmitCallable() throws InterruptedException, ExecutionException { RExecutorService e = redisson.getExecutorService("test"); e.execute(new RunnableTask()); Future<?> f1 = e.submit(new RunnableTask2()); Future<String> f2 = e.submit(new CallableTask()); e.shutdown(); f1.get(); assertThat(f2.get()).isEqualTo(CallableTask.RESULT); assertThat(e.isShutdown()).isTrue(); e.submit(new CallableTask()); } @Test(expected = RejectedExecutionException.class) public void testEmptyRejectSubmitRunnable() throws InterruptedException, ExecutionException { RExecutorService e = redisson.getExecutorService("test"); e.shutdown(); assertThat(e.isShutdown()).isTrue(); e.submit(new RunnableTask2()); } @Test public void testShutdown() throws InterruptedException { RExecutorService e = redisson.getExecutorService("test"); assertThat(e.isShutdown()).isFalse(); assertThat(e.isTerminated()).isFalse(); e.execute(new RunnableTask()); e.shutdown(); assertThat(e.isShutdown()).isTrue(); assertThat(e.awaitTermination(5, TimeUnit.SECONDS)).isTrue(); assertThat(e.isTerminated()).isTrue(); } @Test public void testShutdownEmpty() throws InterruptedException { RExecutorService e = redisson.getExecutorService("test"); assertThat(e.isShutdown()).isFalse(); assertThat(e.isTerminated()).isFalse(); e.shutdown(); assertThat(e.isShutdown()).isTrue(); assertThat(e.awaitTermination(5, TimeUnit.SECONDS)).isTrue(); assertThat(e.isTerminated()).isTrue(); } @Test public void testResetShutdownState() throws InterruptedException, ExecutionException { for (int i = 0; i < 10; i++) { RExecutorService e = redisson.getExecutorService("test"); e.execute(new RunnableTask()); assertThat(e.isShutdown()).isFalse(); e.shutdown(); assertThat(e.isShutdown()).isTrue(); assertThat(e.awaitTermination(10, TimeUnit.SECONDS)).isTrue(); assertThat(e.isTerminated()).isTrue(); assertThat(e.delete()).isTrue(); assertThat(e.isShutdown()).isFalse(); assertThat(e.isTerminated()).isFalse(); Future<?> future = e.submit(new RunnableTask()); future.get(); } } @Test public void testRedissonInjected() throws InterruptedException, ExecutionException { Future<Long> s1 = redisson.getExecutorService("test").submit(new CallableRedissonTask(1L)); Future<Long> s2 = redisson.getExecutorService("test").submit(new CallableRedissonTask(2L)); Future<Long> s3 = redisson.getExecutorService("test").submit(new CallableRedissonTask(30L)); Future<Void> s4 = (Future<Void>) redisson.getExecutorService("test").submit(new RunnableRedissonTask("runnableCounter")); List<Long> results = Arrays.asList(s1.get(), s2.get(), s3.get()); assertThat(results).containsOnlyOnce(33L); s4.get(); assertThat(redisson.getAtomicLong("runnableCounter").get()).isEqualTo(100L); } @Test public void testParameterizedTask() throws InterruptedException, ExecutionException { Future<String> future = redisson.getExecutorService("test").submit(new ParameterizedTask("testparam")); assertThat(future.get()).isEqualTo("testparam"); } @Test(expected = IllegalArgumentException.class) public void testAnonymousRunnable() { redisson.getExecutorService("test").submit(new Runnable() { @Override public void run() { } }); } @Test(expected = IllegalArgumentException.class) public void testAnonymousCallable() { redisson.getExecutorService("test").submit(new Callable<Object>() { @Override public Object call() throws Exception { return null; } }); } public class TaskCallableClass implements Callable<String> { @Override public String call() throws Exception { return "123"; } } @Test(expected = IllegalArgumentException.class) public void testNonStaticInnerClassCallable() { redisson.getExecutorService("test").submit(new TaskCallableClass()); } public static class TaskStaticCallableClass implements Callable<String> { @Override public String call() throws Exception { return "123"; } } @Test public void testInnerClassCallable() throws InterruptedException, ExecutionException { String res = redisson.getExecutorService("test").submit(new TaskStaticCallableClass()).get(); assertThat(res).isEqualTo("123"); } public class TaskRunnableClass implements Runnable { @Override public void run() { } } @Test(expected = IllegalArgumentException.class) public void testNonStaticInnerClassRunnable() { redisson.getExecutorService("test").submit(new TaskRunnableClass()); } public static class TaskStaticRunnableClass implements Runnable { @Override public void run() { } } @Test public void testInnerClassRunnable() throws InterruptedException, ExecutionException { redisson.getExecutorService("test").submit(new TaskStaticRunnableClass()).get(); } @Test(expected = IllegalArgumentException.class) public void testAnonymousRunnableExecute() { redisson.getExecutorService("test").execute(new Runnable() { @Override public void run() { } }); } }