diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java
index ab1791fb215..918777baf1e 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java
@@ -37,6 +37,7 @@ import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.Ordered;
+import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
@@ -45,8 +46,9 @@ import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.util.ClassUtils;
/**
- * {@link ContextCustomizerFactory} that globally disables metrics export and tracing
- * unless {@link AutoConfigureObservability} is set on the test class.
+ * {@link ContextCustomizerFactory} that globally disables metrics export and tracing in
+ * tests. The behaviour can be controlled with {@link AutoConfigureObservability} on the
+ * test class or via the {@value #AUTO_CONFIGURE_PROPERTY} property.
*
* Registers {@link Tracer#NOOP} if tracing is disabled, micrometer-tracing is on the
* classpath, and the user hasn't supplied their own {@link Tracer}.
@@ -56,43 +58,53 @@ import org.springframework.util.ClassUtils;
*/
class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory {
+ static final String AUTO_CONFIGURE_PROPERTY = "spring.test.observability.auto-configure";
+
@Override
public ContextCustomizer createContextCustomizer(Class> testClass,
List configAttributes) {
AutoConfigureObservability annotation = TestContextAnnotationUtils.findMergedAnnotation(testClass,
AutoConfigureObservability.class);
- if (annotation == null) {
- return new DisableObservabilityContextCustomizer(true, true);
- }
- return new DisableObservabilityContextCustomizer(!annotation.metrics(), !annotation.tracing());
+ return new DisableObservabilityContextCustomizer(annotation);
}
private static class DisableObservabilityContextCustomizer implements ContextCustomizer {
- private final boolean disableMetrics;
+ private final AutoConfigureObservability annotation;
- private final boolean disableTracing;
-
- DisableObservabilityContextCustomizer(boolean disableMetrics, boolean disableTracing) {
- this.disableMetrics = disableMetrics;
- this.disableTracing = disableTracing;
+ DisableObservabilityContextCustomizer(AutoConfigureObservability annotation) {
+ this.annotation = annotation;
}
@Override
public void customizeContext(ConfigurableApplicationContext context,
MergedContextConfiguration mergedContextConfiguration) {
- if (this.disableMetrics) {
+ if (areMetricsDisabled(context.getEnvironment())) {
TestPropertyValues
.of("management.defaults.metrics.export.enabled=false",
"management.simple.metrics.export.enabled=true")
.applyTo(context);
}
- if (this.disableTracing) {
+ if (isTracingDisabled(context.getEnvironment())) {
TestPropertyValues.of("management.tracing.enabled=false").applyTo(context);
registerNoopTracer(context);
}
}
+ private boolean areMetricsDisabled(Environment environment) {
+ if (this.annotation != null) {
+ return !this.annotation.metrics();
+ }
+ return !environment.getProperty(AUTO_CONFIGURE_PROPERTY, Boolean.class, false);
+ }
+
+ private boolean isTracingDisabled(Environment environment) {
+ if (this.annotation != null) {
+ return !this.annotation.tracing();
+ }
+ return !environment.getProperty(AUTO_CONFIGURE_PROPERTY, Boolean.class, false);
+ }
+
private void registerNoopTracer(ConfigurableApplicationContext context) {
if (AotDetector.useGeneratedArtifacts()) {
return;
@@ -121,12 +133,12 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory
return false;
}
DisableObservabilityContextCustomizer that = (DisableObservabilityContextCustomizer) o;
- return this.disableMetrics == that.disableMetrics && this.disableTracing == that.disableTracing;
+ return Objects.equals(this.annotation, that.annotation);
}
@Override
public int hashCode() {
- return Objects.hash(this.disableMetrics, this.disableTracing);
+ return Objects.hash(this.annotation);
}
}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json
index aae714fa7ad..32a5f8cfd47 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json
@@ -11,6 +11,12 @@
"type": "org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrint",
"description": "MVC Print option.",
"defaultValue": "default"
+ },
+ {
+ "name": "spring.test.observability.auto-configure",
+ "type": "java.lang.Boolean",
+ "description": "Whether observability should be auto-configured in tests.",
+ "defaultValue": "false"
}
]
-}
\ No newline at end of file
+}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java
index a234182bbba..d8e46424c52 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java
@@ -29,6 +29,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.ContextCustomizer;
import static org.assertj.core.api.Assertions.assertThat;
@@ -135,12 +136,68 @@ class ObservabilityContextCustomizerFactoryTests {
}
@Test
- void hashCodeAndEquals() {
+ void notEquals() {
ContextCustomizer customizer1 = createContextCustomizer(OnlyMetrics.class);
ContextCustomizer customizer2 = createContextCustomizer(OnlyTracing.class);
assertThat(customizer1).isNotEqualTo(customizer2);
}
+ @Test
+ void equals() {
+ ContextCustomizer customizer1 = createContextCustomizer(OnlyMetrics.class);
+ ContextCustomizer customizer2 = createContextCustomizer(OnlyMetrics.class);
+ assertThat(customizer1).isEqualTo(customizer2);
+ assertThat(customizer1).hasSameHashCodeAs(customizer2);
+ }
+
+ @Test
+ void metricsAndTracingCanBeEnabledViaProperty() {
+ ContextCustomizer customizer = createContextCustomizer(NoAnnotation.class);
+ ConfigurableApplicationContext context = new GenericApplicationContext();
+ MockEnvironment environment = new MockEnvironment();
+ environment.setProperty("spring.test.observability.auto-configure", "true");
+ context.setEnvironment(environment);
+ applyCustomizerToContext(customizer, context);
+ assertThatMetricsAreEnabled(context);
+ assertThatTracingIsEnabled(context);
+ }
+
+ @Test
+ void metricsAndTracingCanBeDisabledViaProperty() {
+ ContextCustomizer customizer = createContextCustomizer(NoAnnotation.class);
+ ConfigurableApplicationContext context = new GenericApplicationContext();
+ MockEnvironment environment = new MockEnvironment();
+ environment.setProperty("spring.test.observability.auto-configure", "false");
+ context.setEnvironment(environment);
+ applyCustomizerToContext(customizer, context);
+ assertThatMetricsAreDisabled(context);
+ assertThatTracingIsDisabled(context);
+ }
+
+ @Test
+ void annotationTakesPrecedenceOverDisabledProperty() {
+ ContextCustomizer customizer = createContextCustomizer(WithAnnotation.class);
+ ConfigurableApplicationContext context = new GenericApplicationContext();
+ MockEnvironment environment = new MockEnvironment();
+ environment.setProperty("spring.test.observability.auto-configure", "false");
+ context.setEnvironment(environment);
+ applyCustomizerToContext(customizer, context);
+ assertThatMetricsAreEnabled(context);
+ assertThatTracingIsEnabled(context);
+ }
+
+ @Test
+ void annotationTakesPrecedenceOverEnabledProperty() {
+ ContextCustomizer customizer = createContextCustomizer(WithDisabledAnnotation.class);
+ ConfigurableApplicationContext context = new GenericApplicationContext();
+ MockEnvironment environment = new MockEnvironment();
+ environment.setProperty("spring.test.observability.auto-configure", "true");
+ context.setEnvironment(environment);
+ applyCustomizerToContext(customizer, context);
+ assertThatMetricsAreDisabled(context);
+ assertThatTracingIsDisabled(context);
+ }
+
private void applyCustomizerToContext(ContextCustomizer customizer, ConfigurableApplicationContext context) {
customizer.customizeContext(context, null);
}
@@ -194,6 +251,11 @@ class ObservabilityContextCustomizerFactoryTests {
}
+ @AutoConfigureObservability(metrics = false, tracing = false)
+ static class WithDisabledAnnotation {
+
+ }
+
@Configuration(proxyBeanMethods = false)
static class CustomTracer {