Merge branch '3.0.x'

Closes gh-35360
pull/35366/head
Moritz Halbritter 2 years ago
commit c00e6ebbdf

@ -37,6 +37,7 @@ import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ConfigurationClassPostProcessor; import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
@ -45,8 +46,9 @@ import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
* {@link ContextCustomizerFactory} that globally disables metrics export and tracing * {@link ContextCustomizerFactory} that globally disables metrics export and tracing in
* unless {@link AutoConfigureObservability} is set on the test class. * tests. The behaviour can be controlled with {@link AutoConfigureObservability} on the
* test class or via the {@value #AUTO_CONFIGURE_PROPERTY} property.
* <p> * <p>
* Registers {@link Tracer#NOOP} if tracing is disabled, micrometer-tracing is on the * Registers {@link Tracer#NOOP} if tracing is disabled, micrometer-tracing is on the
* classpath, and the user hasn't supplied their own {@link Tracer}. * classpath, and the user hasn't supplied their own {@link Tracer}.
@ -56,43 +58,53 @@ import org.springframework.util.ClassUtils;
*/ */
class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory { class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory {
static final String AUTO_CONFIGURE_PROPERTY = "spring.test.observability.auto-configure";
@Override @Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) { List<ContextConfigurationAttributes> configAttributes) {
AutoConfigureObservability annotation = TestContextAnnotationUtils.findMergedAnnotation(testClass, AutoConfigureObservability annotation = TestContextAnnotationUtils.findMergedAnnotation(testClass,
AutoConfigureObservability.class); AutoConfigureObservability.class);
if (annotation == null) { return new DisableObservabilityContextCustomizer(annotation);
return new DisableObservabilityContextCustomizer(true, true);
}
return new DisableObservabilityContextCustomizer(!annotation.metrics(), !annotation.tracing());
} }
private static class DisableObservabilityContextCustomizer implements ContextCustomizer { private static class DisableObservabilityContextCustomizer implements ContextCustomizer {
private final boolean disableMetrics; private final AutoConfigureObservability annotation;
private final boolean disableTracing;
DisableObservabilityContextCustomizer(boolean disableMetrics, boolean disableTracing) { DisableObservabilityContextCustomizer(AutoConfigureObservability annotation) {
this.disableMetrics = disableMetrics; this.annotation = annotation;
this.disableTracing = disableTracing;
} }
@Override @Override
public void customizeContext(ConfigurableApplicationContext context, public void customizeContext(ConfigurableApplicationContext context,
MergedContextConfiguration mergedContextConfiguration) { MergedContextConfiguration mergedContextConfiguration) {
if (this.disableMetrics) { if (areMetricsDisabled(context.getEnvironment())) {
TestPropertyValues TestPropertyValues
.of("management.defaults.metrics.export.enabled=false", .of("management.defaults.metrics.export.enabled=false",
"management.simple.metrics.export.enabled=true") "management.simple.metrics.export.enabled=true")
.applyTo(context); .applyTo(context);
} }
if (this.disableTracing) { if (isTracingDisabled(context.getEnvironment())) {
TestPropertyValues.of("management.tracing.enabled=false").applyTo(context); TestPropertyValues.of("management.tracing.enabled=false").applyTo(context);
registerNoopTracer(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) { private void registerNoopTracer(ConfigurableApplicationContext context) {
if (AotDetector.useGeneratedArtifacts()) { if (AotDetector.useGeneratedArtifacts()) {
return; return;
@ -121,12 +133,12 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory
return false; return false;
} }
DisableObservabilityContextCustomizer that = (DisableObservabilityContextCustomizer) o; DisableObservabilityContextCustomizer that = (DisableObservabilityContextCustomizer) o;
return this.disableMetrics == that.disableMetrics && this.disableTracing == that.disableTracing; return Objects.equals(this.annotation, that.annotation);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.disableMetrics, this.disableTracing); return Objects.hash(this.annotation);
} }
} }

@ -11,6 +11,12 @@
"type": "org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrint", "type": "org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrint",
"description": "MVC Print option.", "description": "MVC Print option.",
"defaultValue": "default" "defaultValue": "default"
},
{
"name": "spring.test.observability.auto-configure",
"type": "java.lang.Boolean",
"description": "Whether observability should be auto-configured in tests.",
"defaultValue": "false"
} }
] ]
} }

@ -29,6 +29,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext; import org.springframework.context.support.GenericApplicationContext;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -135,12 +136,68 @@ class ObservabilityContextCustomizerFactoryTests {
} }
@Test @Test
void hashCodeAndEquals() { void notEquals() {
ContextCustomizer customizer1 = createContextCustomizer(OnlyMetrics.class); ContextCustomizer customizer1 = createContextCustomizer(OnlyMetrics.class);
ContextCustomizer customizer2 = createContextCustomizer(OnlyTracing.class); ContextCustomizer customizer2 = createContextCustomizer(OnlyTracing.class);
assertThat(customizer1).isNotEqualTo(customizer2); 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) { private void applyCustomizerToContext(ContextCustomizer customizer, ConfigurableApplicationContext context) {
customizer.customizeContext(context, null); customizer.customizeContext(context, null);
} }
@ -194,6 +251,11 @@ class ObservabilityContextCustomizerFactoryTests {
} }
@AutoConfigureObservability(metrics = false, tracing = false)
static class WithDisabledAnnotation {
}
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
static class CustomTracer { static class CustomTracer {

Loading…
Cancel
Save