Skip to content

Commit d7d5cbf

Browse files
committed
Simplify printing ConditionEvaluationReport when using context runner
Closes gh-13119
1 parent fc60d9f commit d7d5cbf

File tree

7 files changed

+95
-18
lines changed

7 files changed

+95
-18
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListener.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.context.support.GenericApplicationContext;
3232
import org.springframework.core.Ordered;
3333
import org.springframework.core.ResolvableType;
34+
import org.springframework.util.Assert;
3435

3536
/**
3637
* {@link ApplicationContextInitializer} that writes the {@link ConditionEvaluationReport}
@@ -45,6 +46,7 @@
4546
* @author Dave Syer
4647
* @author Phillip Webb
4748
* @author Andy Wilkinson
49+
* @author Madhura Bhave
4850
*/
4951
public class ConditionEvaluationReportLoggingListener
5052
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@@ -55,6 +57,26 @@ public class ConditionEvaluationReportLoggingListener
5557

5658
private ConditionEvaluationReport report;
5759

60+
private final LogLevel logLevelForReport;
61+
62+
public ConditionEvaluationReportLoggingListener() {
63+
this(LogLevel.DEBUG);
64+
}
65+
66+
public ConditionEvaluationReportLoggingListener(LogLevel logLevelForReport) {
67+
Assert.isTrue(isInfoOrDebug(logLevelForReport), "LogLevel must be INFO or DEBUG");
68+
this.logLevelForReport = logLevelForReport;
69+
}
70+
71+
private boolean isInfoOrDebug(LogLevel logLevelForReport) {
72+
return LogLevel.INFO.equals(logLevelForReport)
73+
|| LogLevel.DEBUG.equals(logLevelForReport);
74+
}
75+
76+
public LogLevel getLogLevelForReport() {
77+
return this.logLevelForReport;
78+
}
79+
5880
@Override
5981
public void initialize(ConfigurableApplicationContext applicationContext) {
6082
this.applicationContext = applicationContext;
@@ -97,19 +119,33 @@ public void logAutoConfigurationReport(boolean isCrashReport) {
97119
.get(this.applicationContext.getBeanFactory());
98120
}
99121
if (!this.report.getConditionAndOutcomesBySource().isEmpty()) {
100-
if (isCrashReport && this.logger.isInfoEnabled()
101-
&& !this.logger.isDebugEnabled()) {
102-
this.logger.info(String
103-
.format("%n%nError starting ApplicationContext. To display the "
104-
+ "conditions report re-run your application with "
105-
+ "'debug' enabled."));
122+
if (this.getLogLevelForReport().equals(LogLevel.INFO)) {
123+
if (this.logger.isInfoEnabled()) {
124+
this.logger.info(new ConditionEvaluationReportMessage(this.report));
125+
}
126+
else if (isCrashReport) {
127+
logMessage("info");
128+
}
106129
}
107-
if (this.logger.isDebugEnabled()) {
108-
this.logger.debug(new ConditionEvaluationReportMessage(this.report));
130+
else {
131+
if (isCrashReport && this.logger.isInfoEnabled()
132+
&& !this.logger.isDebugEnabled()) {
133+
logMessage("debug");
134+
}
135+
if (this.logger.isDebugEnabled()) {
136+
this.logger.debug(new ConditionEvaluationReportMessage(this.report));
137+
}
109138
}
110139
}
111140
}
112141

142+
private void logMessage(String logLevel) {
143+
this.logger.info(
144+
String.format("%n%nError starting ApplicationContext. To display the "
145+
+ "conditions report re-run your application with '" + logLevel
146+
+ "' enabled."));
147+
}
148+
113149
private class ConditionEvaluationReportListener
114150
implements GenericApplicationListener {
115151

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
3232
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
3333
import org.springframework.boot.context.event.ApplicationFailedEvent;
34+
import org.springframework.boot.logging.LogLevel;
3435
import org.springframework.boot.testsupport.rule.OutputCapture;
3536
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3637
import org.springframework.context.annotation.Bean;
@@ -41,13 +42,15 @@
4142
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
4243

4344
import static org.assertj.core.api.Assertions.assertThat;
45+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4446
import static org.junit.Assert.fail;
4547

4648
/**
4749
* Tests for {@link ConditionEvaluationReportLoggingListener}.
4850
*
4951
* @author Phillip Webb
5052
* @author Andy Wilkinson
53+
* @author Madhura Bhave
5154
*/
5255
public class ConditionEvaluationReportLoggingListenerTests {
5356

@@ -137,6 +140,26 @@ public void canBeUsedInNonGenericApplicationContext() {
137140
assertThat(context.getBean(ConditionEvaluationReport.class)).isNotNull();
138141
}
139142

143+
@Test
144+
public void listenerWithInfoLevelShouldLogAtInfo() {
145+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
146+
ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(
147+
LogLevel.INFO);
148+
initializer.initialize(context);
149+
context.register(Config.class);
150+
context.refresh();
151+
initializer.onApplicationEvent(new ContextRefreshedEvent(context));
152+
assertThat(this.outputCapture.toString())
153+
.contains("CONDITIONS EVALUATION REPORT");
154+
}
155+
156+
@Test
157+
public void listenerSupportsOnlyInfoAndDebug() {
158+
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
159+
() -> new ConditionEvaluationReportLoggingListener(LogLevel.TRACE))
160+
.withMessage("LogLevel must be INFO or DEBUG");
161+
}
162+
140163
@Test
141164
public void noErrorIfNotInitialized() {
142165
this.initializer

spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7659,6 +7659,23 @@ example:
76597659
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-env]
76607660
----
76617661

7662+
The runner can also be used to display the `ConditionEvaluationReport`. The report can be printed
7663+
at `INFO` or `DEBUG` level. The following example shows how to use the `ConditionEvaluationReportLoggingListener`
7664+
to print the report in auto-configuration tests.
7665+
7666+
[source,java,indent=0]
7667+
----
7668+
@Test
7669+
public void autoConfigTest {
7670+
ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(
7671+
LogLevel.INFO);
7672+
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
7673+
.withInitializer(initializer).run((context -> {
7674+
// Do something...
7675+
}));
7676+
}
7677+
----
7678+
76627679

76637680

76647681
==== Simulating a Web Context

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
100100

101101
private final Supplier<C> contextFactory;
102102

103-
private final List<ApplicationContextInitializer<C>> initializers;
103+
private final List<ApplicationContextInitializer<? super C>> initializers;
104104

105105
private final TestPropertyValues environmentProperties;
106106

@@ -132,7 +132,7 @@ protected AbstractApplicationContextRunner(Supplier<C> contextFactory) {
132132
* @param configurations the configuration
133133
*/
134134
protected AbstractApplicationContextRunner(Supplier<C> contextFactory,
135-
List<ApplicationContextInitializer<C>> initializers,
135+
List<ApplicationContextInitializer<? super C>> initializers,
136136
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
137137
ClassLoader classLoader, ApplicationContext parent,
138138
List<Configurations> configurations) {
@@ -156,7 +156,8 @@ protected AbstractApplicationContextRunner(Supplier<C> contextFactory,
156156
* @param initializer the initializer to add
157157
* @return a new instance with the updated initializers
158158
*/
159-
public SELF withInitializer(ApplicationContextInitializer<C> initializer) {
159+
public SELF withInitializer(
160+
ApplicationContextInitializer<? super ConfigurableApplicationContext> initializer) {
160161
Assert.notNull(initializer, "Initializer must not be null");
161162
return newInstance(this.contextFactory, add(this.initializers, initializer),
162163
this.environmentProperties, this.systemProperties, this.classLoader,
@@ -259,7 +260,7 @@ private <T> List<T> add(List<T> list, T element) {
259260
}
260261

261262
protected abstract SELF newInstance(Supplier<C> contextFactory,
262-
List<ApplicationContextInitializer<C>> initializers,
263+
List<ApplicationContextInitializer<? super C>> initializers,
263264
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
264265
ClassLoader classLoader, ApplicationContext parent,
265266
List<Configurations> configurations);

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ApplicationContextRunner.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public ApplicationContextRunner(
6161

6262
private ApplicationContextRunner(
6363
Supplier<ConfigurableApplicationContext> contextFactory,
64-
List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializers,
64+
List<ApplicationContextInitializer<? super ConfigurableApplicationContext>> initializers,
6565
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
6666
ClassLoader classLoader, ApplicationContext parent,
6767
List<Configurations> configurations) {
@@ -72,7 +72,7 @@ private ApplicationContextRunner(
7272
@Override
7373
protected ApplicationContextRunner newInstance(
7474
Supplier<ConfigurableApplicationContext> contextFactory,
75-
List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializers,
75+
List<ApplicationContextInitializer<? super ConfigurableApplicationContext>> initializers,
7676
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
7777
ClassLoader classLoader, ApplicationContext parent,
7878
List<Configurations> configurations) {

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public ReactiveWebApplicationContextRunner(
6161

6262
private ReactiveWebApplicationContextRunner(
6363
Supplier<ConfigurableReactiveWebApplicationContext> contextFactory,
64-
List<ApplicationContextInitializer<ConfigurableReactiveWebApplicationContext>> initializers,
64+
List<ApplicationContextInitializer<? super ConfigurableReactiveWebApplicationContext>> initializers,
6565
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
6666
ClassLoader classLoader, ApplicationContext parent,
6767
List<Configurations> configurations) {
@@ -72,7 +72,7 @@ private ReactiveWebApplicationContextRunner(
7272
@Override
7373
protected ReactiveWebApplicationContextRunner newInstance(
7474
Supplier<ConfigurableReactiveWebApplicationContext> contextFactory,
75-
List<ApplicationContextInitializer<ConfigurableReactiveWebApplicationContext>> initializers,
75+
List<ApplicationContextInitializer<? super ConfigurableReactiveWebApplicationContext>> initializers,
7676
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
7777
ClassLoader classLoader, ApplicationContext parent,
7878
List<Configurations> configurations) {

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public WebApplicationContextRunner(
6565

6666
private WebApplicationContextRunner(
6767
Supplier<ConfigurableWebApplicationContext> contextFactory,
68-
List<ApplicationContextInitializer<ConfigurableWebApplicationContext>> initializers,
68+
List<ApplicationContextInitializer<? super ConfigurableWebApplicationContext>> initializers,
6969
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
7070
ClassLoader classLoader, ApplicationContext parent,
7171
List<Configurations> configurations) {
@@ -76,7 +76,7 @@ private WebApplicationContextRunner(
7676
@Override
7777
protected WebApplicationContextRunner newInstance(
7878
Supplier<ConfigurableWebApplicationContext> contextFactory,
79-
List<ApplicationContextInitializer<ConfigurableWebApplicationContext>> initializers,
79+
List<ApplicationContextInitializer<? super ConfigurableWebApplicationContext>> initializers,
8080
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
8181
ClassLoader classLoader, ApplicationContext parent,
8282
List<Configurations> configurations) {

0 commit comments

Comments
 (0)