diff --git a/core/spring-boot-test/build.gradle b/core/spring-boot-test/build.gradle index 5f8f7156e70..33f9c7827de 100644 --- a/core/spring-boot-test/build.gradle +++ b/core/spring-boot-test/build.gradle @@ -61,6 +61,7 @@ dependencies { testRuntimeOnly("org.aspectj:aspectjrt") testRuntimeOnly("org.aspectj:aspectjweaver") testRuntimeOnly("org.junit.vintage:junit-vintage-engine") + testRuntimeOnly("org.slf4j:jul-to-slf4j") } tasks.named("compileTestJava") { diff --git a/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/LoggingApplicationListenerTcfCacheContextPausingTests.java b/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/LoggingApplicationListenerTcfCacheContextPausingTests.java new file mode 100644 index 00000000000..64e607ee507 --- /dev/null +++ b/core/spring-boot-test/src/test/java/org/springframework/boot/test/context/LoggingApplicationListenerTcfCacheContextPausingTests.java @@ -0,0 +1,93 @@ +/* + * Copyright 2012-present 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.context; + +import java.util.logging.Logger; + +import org.junit.jupiter.api.ClassOrderer; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestClassOrder; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.context.logging.LoggingApplicationListener; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link LoggingApplicationListener} when the test context framework pauses a + * context while it's in the cache. + * + * @author Raphael Vullriede + */ +@SpringBootTest +@ExtendWith(OutputCaptureExtension.class) +@TestClassOrder(ClassOrderer.ClassName.class) +class LoggingApplicationListenerTcfCacheContextPausingTests { + + private static void assertJulOutputIsLogged(CapturedOutput output) { + Logger.getLogger("test").severe("Hello from JUL"); + assertThat(output).contains("Hello from JUL"); + } + + @Nested + @Import(TestConfig.class) + @TestPropertySource(properties = "context=one") + class ContextOne { + + @Test + void test(CapturedOutput output) { + assertJulOutputIsLogged(output); + } + + } + + @Nested + @Import(TestConfig.class) + @TestPropertySource(properties = "context=two") + class ContextTwo { + + @Test + void test(CapturedOutput output) { + assertJulOutputIsLogged(output); + } + + } + + @Nested + @Import(TestConfig.class) + @TestPropertySource(properties = "context=one") + class ReuseContextOne { + + @Test + void test(CapturedOutput output) { + assertJulOutputIsLogged(output); + } + + } + + @SpringBootConfiguration(proxyBeanMethods = false) + static class TestConfig { + + } + +} diff --git a/core/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java b/core/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java index d5b60317135..bb199a37c31 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java @@ -488,6 +488,11 @@ public class LoggingApplicationListener implements GenericApplicationListener { return Integer.MIN_VALUE + 1; } + @Override + public boolean isPauseable() { + return false; + } + } }