Make TaskExecutor and TaskScheduler tests more robust
This commit is contained in:
parent
c4ef002392
commit
763f7b9be8
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -23,11 +23,13 @@ import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.awaitility.Awaitility;
|
import org.awaitility.Awaitility;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInfo;
|
||||||
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||||
|
|
@ -41,24 +43,27 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 5.0.5
|
* @since 5.0.5
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSchedulingTaskExecutorTests {
|
abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
|
|
||||||
static final String THREAD_NAME_PREFIX = "test-";
|
static final String THREAD_NAME_PREFIX = "test-";
|
||||||
|
|
||||||
private AsyncListenableTaskExecutor executor;
|
private AsyncListenableTaskExecutor executor;
|
||||||
|
|
||||||
|
protected String testName;
|
||||||
|
|
||||||
private volatile Object outcome;
|
private volatile Object outcome;
|
||||||
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void initExecutor() {
|
void setUp(TestInfo testInfo) {
|
||||||
executor = buildExecutor();
|
this.testName = testInfo.getTestMethod().get().getName();
|
||||||
|
this.executor = buildExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract AsyncListenableTaskExecutor buildExecutor();
|
protected abstract AsyncListenableTaskExecutor buildExecutor();
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void shutdownExecutor() throws Exception {
|
void shutdownExecutor() throws Exception {
|
||||||
if (executor instanceof DisposableBean) {
|
if (executor instanceof DisposableBean) {
|
||||||
((DisposableBean) executor).destroy();
|
((DisposableBean) executor).destroy();
|
||||||
}
|
}
|
||||||
|
|
@ -66,23 +71,28 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void executeRunnable() {
|
void executeRunnable() {
|
||||||
TestTask task = new TestTask(1);
|
TestTask task = new TestTask(this.testName, 1);
|
||||||
executor.execute(task);
|
executor.execute(task);
|
||||||
await(task);
|
await(task);
|
||||||
assertThreadNamePrefix(task);
|
assertThreadNamePrefix(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void executeFailingRunnable() {
|
void executeFailingRunnable() {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
executor.execute(task);
|
executor.execute(task);
|
||||||
// nothing to assert
|
Awaitility.await()
|
||||||
|
.dontCatchUncaughtExceptions()
|
||||||
|
.atMost(1, TimeUnit.SECONDS)
|
||||||
|
.pollInterval(10, TimeUnit.MILLISECONDS)
|
||||||
|
.until(() -> task.exception.get() != null && task.exception.get().getMessage().equals(
|
||||||
|
"TestTask failure for test 'executeFailingRunnable': expectedRunCount:<0>, actualRunCount:<1>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitRunnable() throws Exception {
|
void submitRunnable() throws Exception {
|
||||||
TestTask task = new TestTask(1);
|
TestTask task = new TestTask(this.testName, 1);
|
||||||
Future<?> future = executor.submit(task);
|
Future<?> future = executor.submit(task);
|
||||||
Object result = future.get(1000, TimeUnit.MILLISECONDS);
|
Object result = future.get(1000, TimeUnit.MILLISECONDS);
|
||||||
assertThat(result).isNull();
|
assertThat(result).isNull();
|
||||||
|
|
@ -90,8 +100,8 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitFailingRunnable() throws Exception {
|
void submitFailingRunnable() throws Exception {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
Future<?> future = executor.submit(task);
|
Future<?> future = executor.submit(task);
|
||||||
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() ->
|
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() ->
|
||||||
future.get(1000, TimeUnit.MILLISECONDS));
|
future.get(1000, TimeUnit.MILLISECONDS));
|
||||||
|
|
@ -99,9 +109,9 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitRunnableWithGetAfterShutdown() throws Exception {
|
void submitRunnableWithGetAfterShutdown() throws Exception {
|
||||||
Future<?> future1 = executor.submit(new TestTask(-1));
|
Future<?> future1 = executor.submit(new TestTask(this.testName, -1));
|
||||||
Future<?> future2 = executor.submit(new TestTask(-1));
|
Future<?> future2 = executor.submit(new TestTask(this.testName, -1));
|
||||||
shutdownExecutor();
|
shutdownExecutor();
|
||||||
assertThatExceptionOfType(CancellationException.class).isThrownBy(() -> {
|
assertThatExceptionOfType(CancellationException.class).isThrownBy(() -> {
|
||||||
future1.get(1000, TimeUnit.MILLISECONDS);
|
future1.get(1000, TimeUnit.MILLISECONDS);
|
||||||
|
|
@ -110,8 +120,8 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitListenableRunnable() throws Exception {
|
void submitListenableRunnable() throws Exception {
|
||||||
TestTask task = new TestTask(1);
|
TestTask task = new TestTask(this.testName, 1);
|
||||||
// Act
|
// Act
|
||||||
ListenableFuture<?> future = executor.submitListenable(task);
|
ListenableFuture<?> future = executor.submitListenable(task);
|
||||||
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
||||||
|
|
@ -125,8 +135,8 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitFailingListenableRunnable() throws Exception {
|
void submitFailingListenableRunnable() throws Exception {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
ListenableFuture<?> future = executor.submitListenable(task);
|
ListenableFuture<?> future = executor.submitListenable(task);
|
||||||
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
||||||
|
|
||||||
|
|
@ -139,9 +149,9 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitListenableRunnableWithGetAfterShutdown() throws Exception {
|
void submitListenableRunnableWithGetAfterShutdown() throws Exception {
|
||||||
ListenableFuture<?> future1 = executor.submitListenable(new TestTask(-1));
|
ListenableFuture<?> future1 = executor.submitListenable(new TestTask(this.testName, -1));
|
||||||
ListenableFuture<?> future2 = executor.submitListenable(new TestTask(-1));
|
ListenableFuture<?> future2 = executor.submitListenable(new TestTask(this.testName, -1));
|
||||||
shutdownExecutor();
|
shutdownExecutor();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -159,16 +169,16 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitCallable() throws Exception {
|
void submitCallable() throws Exception {
|
||||||
TestCallable task = new TestCallable(1);
|
TestCallable task = new TestCallable(this.testName, 1);
|
||||||
Future<String> future = executor.submit(task);
|
Future<String> future = executor.submit(task);
|
||||||
String result = future.get(1000, TimeUnit.MILLISECONDS);
|
String result = future.get(1000, TimeUnit.MILLISECONDS);
|
||||||
assertThat(result.substring(0, THREAD_NAME_PREFIX.length())).isEqualTo(THREAD_NAME_PREFIX);
|
assertThat(result.substring(0, THREAD_NAME_PREFIX.length())).isEqualTo(THREAD_NAME_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitFailingCallable() throws Exception {
|
void submitFailingCallable() throws Exception {
|
||||||
TestCallable task = new TestCallable(0);
|
TestCallable task = new TestCallable(this.testName, 0);
|
||||||
Future<String> future = executor.submit(task);
|
Future<String> future = executor.submit(task);
|
||||||
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() ->
|
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() ->
|
||||||
future.get(1000, TimeUnit.MILLISECONDS));
|
future.get(1000, TimeUnit.MILLISECONDS));
|
||||||
|
|
@ -176,9 +186,9 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitCallableWithGetAfterShutdown() throws Exception {
|
void submitCallableWithGetAfterShutdown() throws Exception {
|
||||||
Future<?> future1 = executor.submit(new TestCallable(-1));
|
Future<?> future1 = executor.submit(new TestCallable(this.testName, -1));
|
||||||
Future<?> future2 = executor.submit(new TestCallable(-1));
|
Future<?> future2 = executor.submit(new TestCallable(this.testName, -1));
|
||||||
shutdownExecutor();
|
shutdownExecutor();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -196,8 +206,8 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitListenableCallable() throws Exception {
|
void submitListenableCallable() throws Exception {
|
||||||
TestCallable task = new TestCallable(1);
|
TestCallable task = new TestCallable(this.testName, 1);
|
||||||
// Act
|
// Act
|
||||||
ListenableFuture<String> future = executor.submitListenable(task);
|
ListenableFuture<String> future = executor.submitListenable(task);
|
||||||
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
||||||
|
|
@ -210,8 +220,8 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitFailingListenableCallable() throws Exception {
|
void submitFailingListenableCallable() throws Exception {
|
||||||
TestCallable task = new TestCallable(0);
|
TestCallable task = new TestCallable(this.testName, 0);
|
||||||
// Act
|
// Act
|
||||||
ListenableFuture<String> future = executor.submitListenable(task);
|
ListenableFuture<String> future = executor.submitListenable(task);
|
||||||
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
future.addCallback(result -> outcome = result, ex -> outcome = ex);
|
||||||
|
|
@ -225,9 +235,9 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitListenableCallableWithGetAfterShutdown() throws Exception {
|
void submitListenableCallableWithGetAfterShutdown() throws Exception {
|
||||||
ListenableFuture<?> future1 = executor.submitListenable(new TestCallable(-1));
|
ListenableFuture<?> future1 = executor.submitListenable(new TestCallable(this.testName, -1));
|
||||||
ListenableFuture<?> future2 = executor.submitListenable(new TestCallable(-1));
|
ListenableFuture<?> future2 = executor.submitListenable(new TestCallable(this.testName, -1));
|
||||||
shutdownExecutor();
|
shutdownExecutor();
|
||||||
assertThatExceptionOfType(CancellationException.class).isThrownBy(() -> {
|
assertThatExceptionOfType(CancellationException.class).isThrownBy(() -> {
|
||||||
future1.get(1000, TimeUnit.MILLISECONDS);
|
future1.get(1000, TimeUnit.MILLISECONDS);
|
||||||
|
|
@ -255,17 +265,22 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class TestTask implements Runnable {
|
static class TestTask implements Runnable {
|
||||||
|
|
||||||
private final int expectedRunCount;
|
private final int expectedRunCount;
|
||||||
|
|
||||||
|
private final String testName;
|
||||||
|
|
||||||
private final AtomicInteger actualRunCount = new AtomicInteger();
|
private final AtomicInteger actualRunCount = new AtomicInteger();
|
||||||
|
|
||||||
private final CountDownLatch latch;
|
private final AtomicReference<Exception> exception = new AtomicReference<>();
|
||||||
|
|
||||||
private Thread lastThread;
|
final CountDownLatch latch;
|
||||||
|
|
||||||
TestTask(int expectedRunCount) {
|
Thread lastThread;
|
||||||
|
|
||||||
|
TestTask(String testName, int expectedRunCount) {
|
||||||
|
this.testName = testName;
|
||||||
this.expectedRunCount = expectedRunCount;
|
this.expectedRunCount = expectedRunCount;
|
||||||
this.latch = (expectedRunCount > 0 ? new CountDownLatch(expectedRunCount) : null);
|
this.latch = (expectedRunCount > 0 ? new CountDownLatch(expectedRunCount) : null);
|
||||||
}
|
}
|
||||||
|
|
@ -280,7 +295,10 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
if (expectedRunCount >= 0) {
|
if (expectedRunCount >= 0) {
|
||||||
if (actualRunCount.incrementAndGet() > expectedRunCount) {
|
if (actualRunCount.incrementAndGet() > expectedRunCount) {
|
||||||
throw new RuntimeException("intentional test failure");
|
RuntimeException exception = new RuntimeException(String.format("%s failure for test '%s': expectedRunCount:<%d>, actualRunCount:<%d>",
|
||||||
|
getClass().getSimpleName(), this.testName, expectedRunCount, actualRunCount.get()));
|
||||||
|
this.exception.set(exception);
|
||||||
|
throw exception;
|
||||||
}
|
}
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
@ -288,13 +306,16 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class TestCallable implements Callable<String> {
|
static class TestCallable implements Callable<String> {
|
||||||
|
|
||||||
|
private final String testName;
|
||||||
|
|
||||||
private final int expectedRunCount;
|
private final int expectedRunCount;
|
||||||
|
|
||||||
private final AtomicInteger actualRunCount = new AtomicInteger();
|
private final AtomicInteger actualRunCount = new AtomicInteger();
|
||||||
|
|
||||||
TestCallable(int expectedRunCount) {
|
TestCallable(String testName, int expectedRunCount) {
|
||||||
|
this.testName = testName;
|
||||||
this.expectedRunCount = expectedRunCount;
|
this.expectedRunCount = expectedRunCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,7 +328,8 @@ public abstract class AbstractSchedulingTaskExecutorTests {
|
||||||
}
|
}
|
||||||
if (expectedRunCount >= 0) {
|
if (expectedRunCount >= 0) {
|
||||||
if (actualRunCount.incrementAndGet() > expectedRunCount) {
|
if (actualRunCount.incrementAndGet() > expectedRunCount) {
|
||||||
throw new RuntimeException("intentional test failure");
|
throw new RuntimeException(String.format("%s failure for test '%s': expectedRunCount:<%d>, actualRunCount:<%d>",
|
||||||
|
getClass().getSimpleName(), this.testName, expectedRunCount, actualRunCount.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Thread.currentThread().getName();
|
return Thread.currentThread().getName();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.scheduling.concurrent;
|
package org.springframework.scheduling.concurrent;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.RunnableFuture;
|
import java.util.concurrent.RunnableFuture;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
@ -28,11 +27,13 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||||
import org.springframework.core.task.NoOpRunnable;
|
import org.springframework.core.task.NoOpRunnable;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rick Evans
|
* @author Rick Evans
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
public class ConcurrentTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
|
class ConcurrentTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
|
||||||
|
|
||||||
private final ThreadPoolExecutor concurrentExecutor =
|
private final ThreadPoolExecutor concurrentExecutor =
|
||||||
new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
|
new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
|
||||||
|
|
@ -46,9 +47,8 @@ public class ConcurrentTaskExecutorTests extends AbstractSchedulingTaskExecutorT
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void shutdownExecutor() {
|
void shutdownExecutor() {
|
||||||
List<Runnable> remainingTasks = concurrentExecutor.shutdownNow();
|
for (Runnable task : concurrentExecutor.shutdownNow()) {
|
||||||
for (Runnable task : remainingTasks) {
|
|
||||||
if (task instanceof RunnableFuture) {
|
if (task instanceof RunnableFuture) {
|
||||||
((RunnableFuture<?>) task).cancel(true);
|
((RunnableFuture<?>) task).cancel(true);
|
||||||
}
|
}
|
||||||
|
|
@ -57,25 +57,22 @@ public class ConcurrentTaskExecutorTests extends AbstractSchedulingTaskExecutorT
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void zeroArgCtorResultsInDefaultTaskExecutorBeingUsed() {
|
void zeroArgCtorResultsInDefaultTaskExecutorBeingUsed() {
|
||||||
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor();
|
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor();
|
||||||
// must not throw a NullPointerException
|
assertThatCode(() -> executor.execute(new NoOpRunnable())).doesNotThrowAnyException();
|
||||||
executor.execute(new NoOpRunnable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void passingNullExecutorToCtorResultsInDefaultTaskExecutorBeingUsed() {
|
void passingNullExecutorToCtorResultsInDefaultTaskExecutorBeingUsed() {
|
||||||
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor(null);
|
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor(null);
|
||||||
// must not throw a NullPointerException
|
assertThatCode(() -> executor.execute(new NoOpRunnable())).doesNotThrowAnyException();
|
||||||
executor.execute(new NoOpRunnable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void passingNullExecutorToSetterResultsInDefaultTaskExecutorBeingUsed() {
|
void passingNullExecutorToSetterResultsInDefaultTaskExecutorBeingUsed() {
|
||||||
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor();
|
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor();
|
||||||
executor.setConcurrentExecutor(null);
|
executor.setConcurrentExecutor(null);
|
||||||
// must not throw a NullPointerException
|
assertThatCode(() -> executor.execute(new NoOpRunnable())).doesNotThrowAnyException();
|
||||||
executor.execute(new NoOpRunnable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -24,7 +24,7 @@ import org.springframework.scheduling.support.TaskUtils;
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 5.0.5
|
* @since 5.0.5
|
||||||
*/
|
*/
|
||||||
public class DecoratedThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
|
class DecoratedThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AsyncListenableTaskExecutor buildExecutor() {
|
protected AsyncListenableTaskExecutor buildExecutor() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -38,17 +38,17 @@ import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
|
||||||
* @author Rick Evans
|
* @author Rick Evans
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
public class ScheduledExecutorFactoryBeanTests {
|
class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testThrowsExceptionIfPoolSizeIsLessThanZero() throws Exception {
|
void throwsExceptionIfPoolSizeIsLessThanZero() throws Exception {
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
assertThatIllegalArgumentException().isThrownBy(() -> factory.setPoolSize(-1));
|
assertThatIllegalArgumentException().isThrownBy(() -> factory.setPoolSize(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public void testShutdownNowIsPropagatedToTheExecutorOnDestroy() throws Exception {
|
void shutdownNowIsPropagatedToTheExecutorOnDestroy() throws Exception {
|
||||||
final ScheduledExecutorService executor = mock(ScheduledExecutorService.class);
|
final ScheduledExecutorService executor = mock(ScheduledExecutorService.class);
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
||||||
|
|
@ -57,9 +57,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
|
factory.setScheduledExecutorTasks(new NoOpScheduledExecutorTask());
|
||||||
new NoOpScheduledExecutorTask()
|
|
||||||
});
|
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
factory.destroy();
|
factory.destroy();
|
||||||
|
|
||||||
|
|
@ -68,7 +66,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public void testShutdownIsPropagatedToTheExecutorOnDestroy() throws Exception {
|
void shutdownIsPropagatedToTheExecutorOnDestroy() throws Exception {
|
||||||
final ScheduledExecutorService executor = mock(ScheduledExecutorService.class);
|
final ScheduledExecutorService executor = mock(ScheduledExecutorService.class);
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
||||||
|
|
@ -77,9 +75,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
|
factory.setScheduledExecutorTasks(new NoOpScheduledExecutorTask());
|
||||||
new NoOpScheduledExecutorTask()
|
|
||||||
});
|
|
||||||
factory.setWaitForTasksToCompleteOnShutdown(true);
|
factory.setWaitForTasksToCompleteOnShutdown(true);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
factory.destroy();
|
factory.destroy();
|
||||||
|
|
@ -89,13 +85,11 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnabledForTestGroups(PERFORMANCE)
|
@EnabledForTestGroups(PERFORMANCE)
|
||||||
public void testOneTimeExecutionIsSetUpAndFiresCorrectly() throws Exception {
|
void oneTimeExecutionIsSetUpAndFiresCorrectly() throws Exception {
|
||||||
Runnable runnable = mock(Runnable.class);
|
Runnable runnable = mock(Runnable.class);
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
|
factory.setScheduledExecutorTasks(new ScheduledExecutorTask(runnable));
|
||||||
new ScheduledExecutorTask(runnable)
|
|
||||||
});
|
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
pauseToLetTaskStart(1);
|
pauseToLetTaskStart(1);
|
||||||
factory.destroy();
|
factory.destroy();
|
||||||
|
|
@ -105,7 +99,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnabledForTestGroups(PERFORMANCE)
|
@EnabledForTestGroups(PERFORMANCE)
|
||||||
public void testFixedRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
|
void fixedRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
|
||||||
Runnable runnable = mock(Runnable.class);
|
Runnable runnable = mock(Runnable.class);
|
||||||
|
|
||||||
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
|
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
|
||||||
|
|
@ -113,7 +107,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
task.setFixedRate(true);
|
task.setFixedRate(true);
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{task});
|
factory.setScheduledExecutorTasks(task);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
pauseToLetTaskStart(2);
|
pauseToLetTaskStart(2);
|
||||||
factory.destroy();
|
factory.destroy();
|
||||||
|
|
@ -123,7 +117,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnabledForTestGroups(PERFORMANCE)
|
@EnabledForTestGroups(PERFORMANCE)
|
||||||
public void testFixedRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
|
void fixedRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
|
||||||
Runnable runnable = mock(Runnable.class);
|
Runnable runnable = mock(Runnable.class);
|
||||||
willThrow(new IllegalStateException()).given(runnable).run();
|
willThrow(new IllegalStateException()).given(runnable).run();
|
||||||
|
|
||||||
|
|
@ -132,7 +126,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
task.setFixedRate(true);
|
task.setFixedRate(true);
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{task});
|
factory.setScheduledExecutorTasks(task);
|
||||||
factory.setContinueScheduledExecutionAfterException(true);
|
factory.setContinueScheduledExecutionAfterException(true);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
pauseToLetTaskStart(2);
|
pauseToLetTaskStart(2);
|
||||||
|
|
@ -143,7 +137,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnabledForTestGroups(PERFORMANCE)
|
@EnabledForTestGroups(PERFORMANCE)
|
||||||
public void testWithInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
|
void withInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
|
||||||
Runnable runnable = mock(Runnable.class);
|
Runnable runnable = mock(Runnable.class);
|
||||||
|
|
||||||
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
|
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
|
||||||
|
|
@ -151,7 +145,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
task.setDelay(3000); // nice long wait...
|
task.setDelay(3000); // nice long wait...
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[] {task});
|
factory.setScheduledExecutorTasks(task);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
pauseToLetTaskStart(1);
|
pauseToLetTaskStart(1);
|
||||||
// invoke destroy before tasks have even been scheduled...
|
// invoke destroy before tasks have even been scheduled...
|
||||||
|
|
@ -163,7 +157,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnabledForTestGroups(PERFORMANCE)
|
@EnabledForTestGroups(PERFORMANCE)
|
||||||
public void testWithInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
|
void withInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
|
||||||
Runnable runnable = mock(Runnable.class);
|
Runnable runnable = mock(Runnable.class);
|
||||||
willThrow(new IllegalStateException()).given(runnable).run();
|
willThrow(new IllegalStateException()).given(runnable).run();
|
||||||
|
|
||||||
|
|
@ -172,7 +166,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
task.setDelay(3000); // nice long wait...
|
task.setDelay(3000); // nice long wait...
|
||||||
|
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[] {task});
|
factory.setScheduledExecutorTasks(task);
|
||||||
factory.setContinueScheduledExecutionAfterException(true);
|
factory.setContinueScheduledExecutionAfterException(true);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
pauseToLetTaskStart(1);
|
pauseToLetTaskStart(1);
|
||||||
|
|
@ -185,7 +179,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public void testSettingThreadFactoryToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
|
void settingThreadFactoryToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
||||||
@Override
|
@Override
|
||||||
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
|
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
|
||||||
|
|
@ -193,9 +187,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
return super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler);
|
return super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
|
factory.setScheduledExecutorTasks(new NoOpScheduledExecutorTask());
|
||||||
new NoOpScheduledExecutorTask()
|
|
||||||
});
|
|
||||||
factory.setThreadFactory(null); // the null must not propagate
|
factory.setThreadFactory(null); // the null must not propagate
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
factory.destroy();
|
factory.destroy();
|
||||||
|
|
@ -203,7 +195,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public void testSettingRejectedExecutionHandlerToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
|
void settingRejectedExecutionHandlerToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
|
||||||
@Override
|
@Override
|
||||||
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
|
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
|
||||||
|
|
@ -211,16 +203,14 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
return super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler);
|
return super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
|
factory.setScheduledExecutorTasks(new NoOpScheduledExecutorTask());
|
||||||
new NoOpScheduledExecutorTask()
|
|
||||||
});
|
|
||||||
factory.setRejectedExecutionHandler(null); // the null must not propagate
|
factory.setRejectedExecutionHandler(null); // the null must not propagate
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
factory.destroy();
|
factory.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testObjectTypeReportsCorrectType() throws Exception {
|
void objectTypeReportsCorrectType() throws Exception {
|
||||||
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
|
||||||
assertThat(factory.getObjectType()).isEqualTo(ScheduledExecutorService.class);
|
assertThat(factory.getObjectType()).isEqualTo(ScheduledExecutorService.class);
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +227,7 @@ public class ScheduledExecutorFactoryBeanTests {
|
||||||
|
|
||||||
private static class NoOpScheduledExecutorTask extends ScheduledExecutorTask {
|
private static class NoOpScheduledExecutorTask extends ScheduledExecutorTask {
|
||||||
|
|
||||||
public NoOpScheduledExecutorTask() {
|
NoOpScheduledExecutorTask() {
|
||||||
super(new NoOpRunnable());
|
super(new NoOpRunnable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -31,10 +31,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
/**
|
/**
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
public class ThreadPoolExecutorFactoryBeanTests {
|
class ThreadPoolExecutorFactoryBeanTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultExecutor() throws Exception {
|
void defaultExecutor() throws Exception {
|
||||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExecutorConfig.class);
|
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExecutorConfig.class);
|
||||||
ExecutorService executor = context.getBean(ExecutorService.class);
|
ExecutorService executor = context.getBean(ExecutorService.class);
|
||||||
|
|
||||||
|
|
@ -46,10 +46,10 @@ public class ThreadPoolExecutorFactoryBeanTests {
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class ExecutorConfig {
|
static class ExecutorConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ThreadPoolExecutorFactoryBean executor() {
|
ThreadPoolExecutorFactoryBean executor() {
|
||||||
return new ThreadPoolExecutorFactoryBean();
|
return new ThreadPoolExecutorFactoryBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -22,7 +22,7 @@ import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 5.0.5
|
* @since 5.0.5
|
||||||
*/
|
*/
|
||||||
public class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
|
class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AsyncListenableTaskExecutor buildExecutor() {
|
protected AsyncListenableTaskExecutor buildExecutor() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.scheduling.concurrent;
|
package org.springframework.scheduling.concurrent;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
@ -37,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
/**
|
/**
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Sam Brannen
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests {
|
public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutorTests {
|
||||||
|
|
@ -53,8 +53,8 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void executeFailingRunnableWithErrorHandler() {
|
void executeFailingRunnableWithErrorHandler() {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
||||||
scheduler.setErrorHandler(errorHandler);
|
scheduler.setErrorHandler(errorHandler);
|
||||||
scheduler.execute(task);
|
scheduler.execute(task);
|
||||||
|
|
@ -63,8 +63,8 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitFailingRunnableWithErrorHandler() throws Exception {
|
void submitFailingRunnableWithErrorHandler() throws Exception {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
||||||
scheduler.setErrorHandler(errorHandler);
|
scheduler.setErrorHandler(errorHandler);
|
||||||
Future<?> future = scheduler.submit(task);
|
Future<?> future = scheduler.submit(task);
|
||||||
|
|
@ -75,8 +75,8 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitFailingCallableWithErrorHandler() throws Exception {
|
void submitFailingCallableWithErrorHandler() throws Exception {
|
||||||
TestCallable task = new TestCallable(0);
|
TestCallable task = new TestCallable(this.testName, 0);
|
||||||
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
||||||
scheduler.setErrorHandler(errorHandler);
|
scheduler.setErrorHandler(errorHandler);
|
||||||
Future<String> future = scheduler.submit(task);
|
Future<String> future = scheduler.submit(task);
|
||||||
|
|
@ -87,8 +87,8 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scheduleOneTimeTask() throws Exception {
|
void scheduleOneTimeTask() throws Exception {
|
||||||
TestTask task = new TestTask(1);
|
TestTask task = new TestTask(this.testName, 1);
|
||||||
Future<?> future = scheduler.schedule(task, new Date());
|
Future<?> future = scheduler.schedule(task, new Date());
|
||||||
Object result = future.get(1000, TimeUnit.MILLISECONDS);
|
Object result = future.get(1000, TimeUnit.MILLISECONDS);
|
||||||
assertThat(result).isNull();
|
assertThat(result).isNull();
|
||||||
|
|
@ -97,17 +97,16 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scheduleOneTimeFailingTaskWithoutErrorHandler() throws Exception {
|
void scheduleOneTimeFailingTaskWithoutErrorHandler() throws Exception {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
Future<?> future = scheduler.schedule(task, new Date());
|
Future<?> future = scheduler.schedule(task, new Date());
|
||||||
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() ->
|
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> future.get(1000, TimeUnit.MILLISECONDS));
|
||||||
future.get(1000, TimeUnit.MILLISECONDS));
|
|
||||||
assertThat(future.isDone()).isTrue();
|
assertThat(future.isDone()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scheduleOneTimeFailingTaskWithErrorHandler() throws Exception {
|
void scheduleOneTimeFailingTaskWithErrorHandler() throws Exception {
|
||||||
TestTask task = new TestTask(0);
|
TestTask task = new TestTask(this.testName, 0);
|
||||||
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
TestErrorHandler errorHandler = new TestErrorHandler(1);
|
||||||
scheduler.setErrorHandler(errorHandler);
|
scheduler.setErrorHandler(errorHandler);
|
||||||
Future<?> future = scheduler.schedule(task, new Date());
|
Future<?> future = scheduler.schedule(task, new Date());
|
||||||
|
|
@ -118,8 +117,8 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scheduleTriggerTask() throws Exception {
|
void scheduleTriggerTask() throws Exception {
|
||||||
TestTask task = new TestTask(3);
|
TestTask task = new TestTask(this.testName, 3);
|
||||||
Future<?> future = scheduler.schedule(task, new TestTrigger(3));
|
Future<?> future = scheduler.schedule(task, new TestTrigger(3));
|
||||||
Object result = future.get(1000, TimeUnit.MILLISECONDS);
|
Object result = future.get(1000, TimeUnit.MILLISECONDS);
|
||||||
assertThat(result).isNull();
|
assertThat(result).isNull();
|
||||||
|
|
@ -128,8 +127,8 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scheduleMultipleTriggerTasks() throws Exception {
|
void scheduleMultipleTriggerTasks() throws Exception {
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
scheduleTriggerTask();
|
scheduleTriggerTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -158,52 +157,6 @@ public class ThreadPoolTaskSchedulerTests extends AbstractSchedulingTaskExecutor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class TestTask implements Runnable {
|
|
||||||
|
|
||||||
private final int expectedRunCount;
|
|
||||||
|
|
||||||
private final AtomicInteger actualRunCount = new AtomicInteger();
|
|
||||||
|
|
||||||
private final CountDownLatch latch;
|
|
||||||
|
|
||||||
private Thread lastThread;
|
|
||||||
|
|
||||||
TestTask(int expectedRunCount) {
|
|
||||||
this.expectedRunCount = expectedRunCount;
|
|
||||||
this.latch = new CountDownLatch(expectedRunCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
lastThread = Thread.currentThread();
|
|
||||||
if (actualRunCount.incrementAndGet() > expectedRunCount) {
|
|
||||||
throw new RuntimeException("intentional test failure");
|
|
||||||
}
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static class TestCallable implements Callable<String> {
|
|
||||||
|
|
||||||
private final int expectedRunCount;
|
|
||||||
|
|
||||||
private final AtomicInteger actualRunCount = new AtomicInteger();
|
|
||||||
|
|
||||||
TestCallable(int expectedRunCount) {
|
|
||||||
this.expectedRunCount = expectedRunCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String call() throws Exception {
|
|
||||||
if (actualRunCount.incrementAndGet() > expectedRunCount) {
|
|
||||||
throw new RuntimeException("intentional test failure");
|
|
||||||
}
|
|
||||||
return Thread.currentThread().getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static class TestErrorHandler implements ErrorHandler {
|
private static class TestErrorHandler implements ErrorHandler {
|
||||||
|
|
||||||
private final CountDownLatch latch;
|
private final CountDownLatch latch;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue