Merge branch '6.0.x'

This commit is contained in:
Juergen Hoeller 2023-07-08 00:58:58 +02:00
commit bf99361abb
4 changed files with 92 additions and 93 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -58,7 +58,7 @@ abstract class AbstractSchedulingTaskExecutorTests {
@BeforeEach
void setUp(TestInfo testInfo) {
void setup(TestInfo testInfo) {
this.testName = testInfo.getTestMethod().get().getName();
this.threadNamePrefix = this.testName + "-";
this.executor = buildExecutor();
@ -88,11 +88,11 @@ abstract class AbstractSchedulingTaskExecutorTests {
TestTask task = new TestTask(this.testName, 0);
executor.execute(task);
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>"));
.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
@ -105,7 +105,7 @@ abstract class AbstractSchedulingTaskExecutorTests {
}
@Test
void submitFailingRunnable() throws Exception {
void submitFailingRunnable() {
TestTask task = new TestTask(this.testName, 0);
Future<?> future = executor.submit(task);
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() ->
@ -126,61 +126,61 @@ abstract class AbstractSchedulingTaskExecutorTests {
@Test
@SuppressWarnings("deprecation")
void submitListenableRunnable() throws Exception {
void submitListenableRunnable() {
TestTask task = new TestTask(this.testName, 1);
// Act
org.springframework.util.concurrent.ListenableFuture<?> future = executor.submitListenable(task);
future.addCallback(result -> outcome = result, ex -> outcome = ex);
// Assert
Awaitility.await()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(future::isDone);
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(future::isDone);
assertThat(outcome).isNull();
assertThreadNamePrefix(task);
}
@Test
void submitCompletableRunnable() throws Exception {
void submitCompletableRunnable() {
TestTask task = new TestTask(this.testName, 1);
// Act
CompletableFuture<Void> future = executor.submitCompletable(task);
future.whenComplete(this::storeOutcome);
// Assert
Awaitility.await()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(future::isDone);
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(future::isDone);
assertThat(outcome).isNull();
assertThreadNamePrefix(task);
}
@Test
@SuppressWarnings("deprecation")
void submitFailingListenableRunnable() throws Exception {
void submitFailingListenableRunnable() {
TestTask task = new TestTask(this.testName, 0);
org.springframework.util.concurrent.ListenableFuture<?> future = executor.submitListenable(task);
future.addCallback(result -> outcome = result, ex -> outcome = ex);
Awaitility.await()
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
assertThat(outcome.getClass()).isSameAs(RuntimeException.class);
}
@Test
void submitFailingCompletableRunnable() throws Exception {
void submitFailingCompletableRunnable() {
TestTask task = new TestTask(this.testName, 0);
CompletableFuture<?> future = executor.submitCompletable(task);
future.whenComplete(this::storeOutcome);
Awaitility.await()
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
assertThat(outcome.getClass()).isSameAs(CompletionException.class);
}
@ -195,14 +195,13 @@ abstract class AbstractSchedulingTaskExecutorTests {
future1.get(1000, TimeUnit.MILLISECONDS);
}
catch (Exception ex) {
/* ignore */
// ignore
}
Awaitility.await()
.atMost(4, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.untilAsserted(() ->
assertThatExceptionOfType(CancellationException.class).isThrownBy(() ->
future2.get(1000, TimeUnit.MILLISECONDS)));
.atMost(4, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.untilAsserted(() -> assertThatExceptionOfType(CancellationException.class)
.isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS)));
}
@Test
@ -215,14 +214,13 @@ abstract class AbstractSchedulingTaskExecutorTests {
future1.get(1000, TimeUnit.MILLISECONDS);
}
catch (Exception ex) {
/* ignore */
// ignore
}
Awaitility.await()
.atMost(4, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.untilAsserted(() ->
assertThatExceptionOfType(TimeoutException.class)
.isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS)));
.atMost(4, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.untilAsserted(() -> assertThatExceptionOfType(TimeoutException.class)
.isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS)));
}
@Test
@ -234,11 +232,11 @@ abstract class AbstractSchedulingTaskExecutorTests {
}
@Test
void submitFailingCallable() throws Exception {
void submitFailingCallable() {
TestCallable task = new TestCallable(this.testName, 0);
Future<String> future = executor.submit(task);
assertThatExceptionOfType(ExecutionException.class)
.isThrownBy(() -> future.get(1000, TimeUnit.MILLISECONDS));
.isThrownBy(() -> future.get(1000, TimeUnit.MILLISECONDS));
assertThat(future.isDone()).isTrue();
}
@ -252,44 +250,43 @@ abstract class AbstractSchedulingTaskExecutorTests {
future1.get(1000, TimeUnit.MILLISECONDS);
}
catch (Exception ex) {
/* ignore */
// ignore
}
Awaitility.await()
.atMost(4, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.untilAsserted(() ->
assertThatExceptionOfType(CancellationException.class)
.isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS)));
.atMost(4, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.untilAsserted(() -> assertThatExceptionOfType(CancellationException.class)
.isThrownBy(() -> future2.get(1000, TimeUnit.MILLISECONDS)));
}
@Test
@SuppressWarnings("deprecation")
void submitListenableCallable() throws Exception {
void submitListenableCallable() {
TestCallable task = new TestCallable(this.testName, 1);
// Act
org.springframework.util.concurrent.ListenableFuture<String> future = executor.submitListenable(task);
future.addCallback(result -> outcome = result, ex -> outcome = ex);
// Assert
Awaitility.await()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
assertThat(outcome.toString().substring(0, this.threadNamePrefix.length())).isEqualTo(this.threadNamePrefix);
}
@Test
@SuppressWarnings("deprecation")
void submitFailingListenableCallable() throws Exception {
void submitFailingListenableCallable() {
TestCallable task = new TestCallable(this.testName, 0);
// Act
org.springframework.util.concurrent.ListenableFuture<String> future = executor.submitListenable(task);
future.addCallback(result -> outcome = result, ex -> outcome = ex);
// Assert
Awaitility.await()
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
assertThat(outcome.getClass()).isSameAs(RuntimeException.class);
}
@ -306,31 +303,31 @@ abstract class AbstractSchedulingTaskExecutorTests {
}
@Test
void submitCompletableCallable() throws Exception {
void submitCompletableCallable() {
TestCallable task = new TestCallable(this.testName, 1);
// Act
CompletableFuture<String> future = this.executor.submitCompletable(task);
future.whenComplete(this::storeOutcome);
// Assert
Awaitility.await()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
assertThat(outcome.toString().substring(0, this.threadNamePrefix.length())).isEqualTo(this.threadNamePrefix);
}
@Test
void submitFailingCompletableCallable() throws Exception {
void submitFailingCompletableCallable() {
TestCallable task = new TestCallable(this.testName, 0);
// Act
CompletableFuture<String> future = this.executor.submitCompletable(task);
future.whenComplete(this::storeOutcome);
// Assert
Awaitility.await()
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
.dontCatchUncaughtExceptions()
.atMost(1, TimeUnit.SECONDS)
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> future.isDone() && outcome != null);
assertThat(outcome.getClass()).isSameAs(CompletionException.class);
}
@ -355,8 +352,6 @@ abstract class AbstractSchedulingTaskExecutorTests {
}
}
protected void assertThreadNamePrefix(TestTask task) {
assertThat(task.lastThread.getName().substring(0, this.threadNamePrefix.length())).isEqualTo(this.threadNamePrefix);
}
@ -406,8 +401,9 @@ abstract class AbstractSchedulingTaskExecutorTests {
}
if (expectedRunCount >= 0) {
if (actualRunCount.incrementAndGet() > expectedRunCount) {
RuntimeException exception = new RuntimeException(String.format("%s failure for test '%s': expectedRunCount:<%d>, actualRunCount:<%d>",
getClass().getSimpleName(), this.testName, expectedRunCount, actualRunCount.get()));
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;
}
@ -439,8 +435,9 @@ abstract class AbstractSchedulingTaskExecutorTests {
}
if (expectedRunCount >= 0) {
if (actualRunCount.incrementAndGet() > expectedRunCount) {
throw new RuntimeException(String.format("%s failure for test '%s': expectedRunCount:<%d>, actualRunCount:<%d>",
getClass().getSimpleName(), this.testName, expectedRunCount, actualRunCount.get()));
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();

View File

@ -92,19 +92,24 @@ class ConcurrentTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
private static class DecoratedRunnable implements Runnable {
@Override
public void run() {
}
}
private static class RunnableDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
return new DecoratedRunnable();
}
}
private static class DecoratedExecutor implements Executor {
@Override
public void execute(Runnable command) {
Assert.state(command instanceof DecoratedRunnable, "TaskDecorator not applied");

View File

@ -41,14 +41,14 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
class ScheduledExecutorFactoryBeanTests {
@Test
void throwsExceptionIfPoolSizeIsLessThanZero() throws Exception {
void throwsExceptionIfPoolSizeIsLessThanZero() {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
assertThatIllegalArgumentException().isThrownBy(() -> factory.setPoolSize(-1));
}
@Test
@SuppressWarnings("serial")
void shutdownNowIsPropagatedToTheExecutorOnDestroy() throws Exception {
void shutdownNowIsPropagatedToTheExecutorOnDestroy() {
final ScheduledExecutorService executor = mock();
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
@ -66,7 +66,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@SuppressWarnings("serial")
void shutdownIsPropagatedToTheExecutorOnDestroy() throws Exception {
void shutdownIsPropagatedToTheExecutorOnDestroy() {
final ScheduledExecutorService executor = mock();
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
@ -85,7 +85,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
void oneTimeExecutionIsSetUpAndFiresCorrectly() throws Exception {
void oneTimeExecutionIsSetUpAndFiresCorrectly() {
Runnable runnable = mock();
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
@ -99,7 +99,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
void fixedRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
void fixedRepeatedExecutionIsSetUpAndFiresCorrectly() {
Runnable runnable = mock();
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
@ -117,7 +117,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
void fixedRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
void fixedRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() {
Runnable runnable = mock();
willThrow(new IllegalStateException()).given(runnable).run();
@ -137,7 +137,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
void withInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
void withInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectly() {
Runnable runnable = mock();
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
@ -157,7 +157,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
void withInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
void withInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() {
Runnable runnable = mock();
willThrow(new IllegalStateException()).given(runnable).run();
@ -179,7 +179,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@SuppressWarnings("serial")
void settingThreadFactoryToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
void settingThreadFactoryToNullForcesUseOfDefaultButIsOtherwiseCool() {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
@Override
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
@ -197,7 +197,7 @@ class ScheduledExecutorFactoryBeanTests {
@Test
@SuppressWarnings("serial")
void settingRejectedExecutionHandlerToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
void settingRejectedExecutionHandlerToNullForcesUseOfDefaultButIsOtherwiseCool() {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
@Override
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
@ -211,7 +211,7 @@ class ScheduledExecutorFactoryBeanTests {
}
@Test
void objectTypeReportsCorrectType() throws Exception {
void objectTypeReportsCorrectType() {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
assertThat(factory.getObjectType()).isEqualTo(ScheduledExecutorService.class);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,8 +24,8 @@ import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.InstanceOfAssertFactories.type;
/**
@ -66,8 +66,7 @@ class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
assertThat(executor.getCorePoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getCorePoolSize()).isEqualTo(1);
assertThatThrownBy(() -> executor.setCorePoolSize(-1))
.isInstanceOf(IllegalArgumentException.class);
assertThatIllegalArgumentException().isThrownBy(() -> executor.setCorePoolSize(-1));
assertThat(executor.getCorePoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getCorePoolSize()).isEqualTo(1);
@ -89,8 +88,7 @@ class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
assertThat(executor.getMaxPoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getMaximumPoolSize()).isEqualTo(1);
assertThatThrownBy(() -> executor.setMaxPoolSize(0))
.isInstanceOf(IllegalArgumentException.class);
assertThatIllegalArgumentException().isThrownBy(() -> executor.setMaxPoolSize(0));
assertThat(executor.getMaxPoolSize()).isEqualTo(1);
assertThat(executor.getThreadPoolExecutor().getMaximumPoolSize()).isEqualTo(1);
@ -112,8 +110,7 @@ class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60);
assertThat(executor.getThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS)).isEqualTo(60);
assertThatThrownBy(() -> executor.setKeepAliveSeconds(-10))
.isInstanceOf(IllegalArgumentException.class);
assertThatIllegalArgumentException().isThrownBy(() -> executor.setKeepAliveSeconds(-10));
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60);
assertThat(executor.getThreadPoolExecutor().getKeepAliveTime(TimeUnit.SECONDS)).isEqualTo(60);
@ -123,8 +120,8 @@ class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
void queueCapacityDefault() {
assertThat(executor.getQueueCapacity()).isEqualTo(Integer.MAX_VALUE);
assertThat(executor.getThreadPoolExecutor().getQueue())
.asInstanceOf(type(LinkedBlockingQueue.class))
.extracting(BlockingQueue::remainingCapacity).isEqualTo(Integer.MAX_VALUE);
.asInstanceOf(type(LinkedBlockingQueue.class))
.extracting(BlockingQueue::remainingCapacity).isEqualTo(Integer.MAX_VALUE);
}
@Test
@ -134,8 +131,8 @@ class ThreadPoolTaskExecutorTests extends AbstractSchedulingTaskExecutorTests {
assertThat(executor.getQueueCapacity()).isZero();
assertThat(executor.getThreadPoolExecutor().getQueue())
.asInstanceOf(type(SynchronousQueue.class))
.extracting(BlockingQueue::remainingCapacity).isEqualTo(0);
.asInstanceOf(type(SynchronousQueue.class))
.extracting(BlockingQueue::remainingCapacity).isEqualTo(0);
}
@Test