Simplify printing ConditionEvaluationReport when using context runner
Closes gh-13119
This commit is contained in:
parent
fc60d9f6d4
commit
d7d5cbf959
|
@ -31,6 +31,7 @@ import org.springframework.context.event.GenericApplicationListener;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ApplicationContextInitializer} that writes the {@link ConditionEvaluationReport}
|
* {@link ApplicationContextInitializer} that writes the {@link ConditionEvaluationReport}
|
||||||
|
@ -45,6 +46,7 @@ import org.springframework.core.ResolvableType;
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
|
* @author Madhura Bhave
|
||||||
*/
|
*/
|
||||||
public class ConditionEvaluationReportLoggingListener
|
public class ConditionEvaluationReportLoggingListener
|
||||||
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||||
|
@ -55,6 +57,26 @@ public class ConditionEvaluationReportLoggingListener
|
||||||
|
|
||||||
private ConditionEvaluationReport report;
|
private ConditionEvaluationReport report;
|
||||||
|
|
||||||
|
private final LogLevel logLevelForReport;
|
||||||
|
|
||||||
|
public ConditionEvaluationReportLoggingListener() {
|
||||||
|
this(LogLevel.DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConditionEvaluationReportLoggingListener(LogLevel logLevelForReport) {
|
||||||
|
Assert.isTrue(isInfoOrDebug(logLevelForReport), "LogLevel must be INFO or DEBUG");
|
||||||
|
this.logLevelForReport = logLevelForReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInfoOrDebug(LogLevel logLevelForReport) {
|
||||||
|
return LogLevel.INFO.equals(logLevelForReport)
|
||||||
|
|| LogLevel.DEBUG.equals(logLevelForReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogLevel getLogLevelForReport() {
|
||||||
|
return this.logLevelForReport;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
|
@ -97,18 +119,32 @@ public class ConditionEvaluationReportLoggingListener
|
||||||
.get(this.applicationContext.getBeanFactory());
|
.get(this.applicationContext.getBeanFactory());
|
||||||
}
|
}
|
||||||
if (!this.report.getConditionAndOutcomesBySource().isEmpty()) {
|
if (!this.report.getConditionAndOutcomesBySource().isEmpty()) {
|
||||||
|
if (this.getLogLevelForReport().equals(LogLevel.INFO)) {
|
||||||
|
if (this.logger.isInfoEnabled()) {
|
||||||
|
this.logger.info(new ConditionEvaluationReportMessage(this.report));
|
||||||
|
}
|
||||||
|
else if (isCrashReport) {
|
||||||
|
logMessage("info");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (isCrashReport && this.logger.isInfoEnabled()
|
if (isCrashReport && this.logger.isInfoEnabled()
|
||||||
&& !this.logger.isDebugEnabled()) {
|
&& !this.logger.isDebugEnabled()) {
|
||||||
this.logger.info(String
|
logMessage("debug");
|
||||||
.format("%n%nError starting ApplicationContext. To display the "
|
|
||||||
+ "conditions report re-run your application with "
|
|
||||||
+ "'debug' enabled."));
|
|
||||||
}
|
}
|
||||||
if (this.logger.isDebugEnabled()) {
|
if (this.logger.isDebugEnabled()) {
|
||||||
this.logger.debug(new ConditionEvaluationReportMessage(this.report));
|
this.logger.debug(new ConditionEvaluationReportMessage(this.report));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logMessage(String logLevel) {
|
||||||
|
this.logger.info(
|
||||||
|
String.format("%n%nError starting ApplicationContext. To display the "
|
||||||
|
+ "conditions report re-run your application with '" + logLevel
|
||||||
|
+ "' enabled."));
|
||||||
|
}
|
||||||
|
|
||||||
private class ConditionEvaluationReportListener
|
private class ConditionEvaluationReportListener
|
||||||
implements GenericApplicationListener {
|
implements GenericApplicationListener {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
|
||||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||||
|
import org.springframework.boot.logging.LogLevel;
|
||||||
import org.springframework.boot.testsupport.rule.OutputCapture;
|
import org.springframework.boot.testsupport.rule.OutputCapture;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -41,6 +42,7 @@ import org.springframework.mock.web.MockServletContext;
|
||||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,6 +50,7 @@ import static org.junit.Assert.fail;
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
|
* @author Madhura Bhave
|
||||||
*/
|
*/
|
||||||
public class ConditionEvaluationReportLoggingListenerTests {
|
public class ConditionEvaluationReportLoggingListenerTests {
|
||||||
|
|
||||||
|
@ -137,6 +140,26 @@ public class ConditionEvaluationReportLoggingListenerTests {
|
||||||
assertThat(context.getBean(ConditionEvaluationReport.class)).isNotNull();
|
assertThat(context.getBean(ConditionEvaluationReport.class)).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listenerWithInfoLevelShouldLogAtInfo() {
|
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||||
|
ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(
|
||||||
|
LogLevel.INFO);
|
||||||
|
initializer.initialize(context);
|
||||||
|
context.register(Config.class);
|
||||||
|
context.refresh();
|
||||||
|
initializer.onApplicationEvent(new ContextRefreshedEvent(context));
|
||||||
|
assertThat(this.outputCapture.toString())
|
||||||
|
.contains("CONDITIONS EVALUATION REPORT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listenerSupportsOnlyInfoAndDebug() {
|
||||||
|
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
|
||||||
|
() -> new ConditionEvaluationReportLoggingListener(LogLevel.TRACE))
|
||||||
|
.withMessage("LogLevel must be INFO or DEBUG");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noErrorIfNotInitialized() {
|
public void noErrorIfNotInitialized() {
|
||||||
this.initializer
|
this.initializer
|
||||||
|
|
|
@ -7659,6 +7659,23 @@ example:
|
||||||
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-env]
|
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-env]
|
||||||
----
|
----
|
||||||
|
|
||||||
|
The runner can also be used to display the `ConditionEvaluationReport`. The report can be printed
|
||||||
|
at `INFO` or `DEBUG` level. The following example shows how to use the `ConditionEvaluationReportLoggingListener`
|
||||||
|
to print the report in auto-configuration tests.
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
@Test
|
||||||
|
public void autoConfigTest {
|
||||||
|
ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(
|
||||||
|
LogLevel.INFO);
|
||||||
|
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withInitializer(initializer).run((context -> {
|
||||||
|
// Do something...
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==== Simulating a Web Context
|
==== Simulating a Web Context
|
||||||
|
|
|
@ -100,7 +100,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
|
||||||
|
|
||||||
private final Supplier<C> contextFactory;
|
private final Supplier<C> contextFactory;
|
||||||
|
|
||||||
private final List<ApplicationContextInitializer<C>> initializers;
|
private final List<ApplicationContextInitializer<? super C>> initializers;
|
||||||
|
|
||||||
private final TestPropertyValues environmentProperties;
|
private final TestPropertyValues environmentProperties;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
|
||||||
* @param configurations the configuration
|
* @param configurations the configuration
|
||||||
*/
|
*/
|
||||||
protected AbstractApplicationContextRunner(Supplier<C> contextFactory,
|
protected AbstractApplicationContextRunner(Supplier<C> contextFactory,
|
||||||
List<ApplicationContextInitializer<C>> initializers,
|
List<ApplicationContextInitializer<? super C>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
@ -156,7 +156,8 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
|
||||||
* @param initializer the initializer to add
|
* @param initializer the initializer to add
|
||||||
* @return a new instance with the updated initializers
|
* @return a new instance with the updated initializers
|
||||||
*/
|
*/
|
||||||
public SELF withInitializer(ApplicationContextInitializer<C> initializer) {
|
public SELF withInitializer(
|
||||||
|
ApplicationContextInitializer<? super ConfigurableApplicationContext> initializer) {
|
||||||
Assert.notNull(initializer, "Initializer must not be null");
|
Assert.notNull(initializer, "Initializer must not be null");
|
||||||
return newInstance(this.contextFactory, add(this.initializers, initializer),
|
return newInstance(this.contextFactory, add(this.initializers, initializer),
|
||||||
this.environmentProperties, this.systemProperties, this.classLoader,
|
this.environmentProperties, this.systemProperties, this.classLoader,
|
||||||
|
@ -259,7 +260,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract SELF newInstance(Supplier<C> contextFactory,
|
protected abstract SELF newInstance(Supplier<C> contextFactory,
|
||||||
List<ApplicationContextInitializer<C>> initializers,
|
List<ApplicationContextInitializer<? super C>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations);
|
List<Configurations> configurations);
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class ApplicationContextRunner extends
|
||||||
|
|
||||||
private ApplicationContextRunner(
|
private ApplicationContextRunner(
|
||||||
Supplier<ConfigurableApplicationContext> contextFactory,
|
Supplier<ConfigurableApplicationContext> contextFactory,
|
||||||
List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializers,
|
List<ApplicationContextInitializer<? super ConfigurableApplicationContext>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
@ -72,7 +72,7 @@ public class ApplicationContextRunner extends
|
||||||
@Override
|
@Override
|
||||||
protected ApplicationContextRunner newInstance(
|
protected ApplicationContextRunner newInstance(
|
||||||
Supplier<ConfigurableApplicationContext> contextFactory,
|
Supplier<ConfigurableApplicationContext> contextFactory,
|
||||||
List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializers,
|
List<ApplicationContextInitializer<? super ConfigurableApplicationContext>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
|
|
@ -61,7 +61,7 @@ public final class ReactiveWebApplicationContextRunner extends
|
||||||
|
|
||||||
private ReactiveWebApplicationContextRunner(
|
private ReactiveWebApplicationContextRunner(
|
||||||
Supplier<ConfigurableReactiveWebApplicationContext> contextFactory,
|
Supplier<ConfigurableReactiveWebApplicationContext> contextFactory,
|
||||||
List<ApplicationContextInitializer<ConfigurableReactiveWebApplicationContext>> initializers,
|
List<ApplicationContextInitializer<? super ConfigurableReactiveWebApplicationContext>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
@ -72,7 +72,7 @@ public final class ReactiveWebApplicationContextRunner extends
|
||||||
@Override
|
@Override
|
||||||
protected ReactiveWebApplicationContextRunner newInstance(
|
protected ReactiveWebApplicationContextRunner newInstance(
|
||||||
Supplier<ConfigurableReactiveWebApplicationContext> contextFactory,
|
Supplier<ConfigurableReactiveWebApplicationContext> contextFactory,
|
||||||
List<ApplicationContextInitializer<ConfigurableReactiveWebApplicationContext>> initializers,
|
List<ApplicationContextInitializer<? super ConfigurableReactiveWebApplicationContext>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ public final class WebApplicationContextRunner extends
|
||||||
|
|
||||||
private WebApplicationContextRunner(
|
private WebApplicationContextRunner(
|
||||||
Supplier<ConfigurableWebApplicationContext> contextFactory,
|
Supplier<ConfigurableWebApplicationContext> contextFactory,
|
||||||
List<ApplicationContextInitializer<ConfigurableWebApplicationContext>> initializers,
|
List<ApplicationContextInitializer<? super ConfigurableWebApplicationContext>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
@ -76,7 +76,7 @@ public final class WebApplicationContextRunner extends
|
||||||
@Override
|
@Override
|
||||||
protected WebApplicationContextRunner newInstance(
|
protected WebApplicationContextRunner newInstance(
|
||||||
Supplier<ConfigurableWebApplicationContext> contextFactory,
|
Supplier<ConfigurableWebApplicationContext> contextFactory,
|
||||||
List<ApplicationContextInitializer<ConfigurableWebApplicationContext>> initializers,
|
List<ApplicationContextInitializer<? super ConfigurableWebApplicationContext>> initializers,
|
||||||
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
|
||||||
ClassLoader classLoader, ApplicationContext parent,
|
ClassLoader classLoader, ApplicationContext parent,
|
||||||
List<Configurations> configurations) {
|
List<Configurations> configurations) {
|
||||||
|
|
Loading…
Reference in New Issue