diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java index 395fd4de9a..86ffbea6cb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2024 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. @@ -20,13 +20,18 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.List; +import java.util.function.Function; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTestInvocationContextProvider.WebEndpointsInvocationContext; +import org.springframework.context.ConfigurableApplicationContext; + /** - * Signals that a test should be performed against all web endpoint implementations - * (Jersey, Web MVC, and WebFlux) + * Signals that a test should be run against one or more of the web endpoint + * infrastructure implementations (Jersey, Web MVC, and WebFlux) * * @author Andy Wilkinson */ @@ -36,4 +41,42 @@ import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(WebEndpointTestInvocationContextProvider.class) public @interface WebEndpointTest { + /** + * The infrastructure against which the test should run. + * @return the infrastructure to run the tests against + */ + Infrastructure[] infrastructure() default { Infrastructure.JERSEY, Infrastructure.MVC, Infrastructure.WEBFLUX }; + + enum Infrastructure { + + /** + * Actuator running on the Jersey-based infrastructure. + */ + JERSEY("Jersey", WebEndpointTestInvocationContextProvider::createJerseyContext), + + /** + * Actuator running on the WebMVC-based infrastructure. + */ + MVC("WebMvc", WebEndpointTestInvocationContextProvider::createWebMvcContext), + + /** + * Actuator running on the WebFlux-based infrastructure. + */ + WEBFLUX("WebFlux", WebEndpointTestInvocationContextProvider::createWebFluxContext); + + private final String name; + + private final Function>, ConfigurableApplicationContext> contextFactory; + + Infrastructure(String name, Function>, ConfigurableApplicationContext> contextFactory) { + this.name = name; + this.contextFactory = contextFactory; + } + + WebEndpointsInvocationContext createInvocationContext() { + return new WebEndpointsInvocationContext(this.name, this.contextFactory); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java index debfdb6078..c0ac708f20 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -36,6 +36,7 @@ import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolver; import org.junit.jupiter.api.extension.TestTemplateInvocationContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; +import org.junit.platform.commons.util.AnnotationUtils; import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; @@ -45,6 +46,7 @@ import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDisco import org.springframework.boot.actuate.endpoint.web.jersey.JerseyEndpointResourceFactory; import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; @@ -91,16 +93,14 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation @Override public Stream provideTestTemplateInvocationContexts( ExtensionContext extensionContext) { - return Stream.of( - new WebEndpointsInvocationContext("Jersey", - WebEndpointTestInvocationContextProvider::createJerseyContext), - new WebEndpointsInvocationContext("WebMvc", - WebEndpointTestInvocationContextProvider::createWebMvcContext), - new WebEndpointsInvocationContext("WebFlux", - WebEndpointTestInvocationContextProvider::createWebFluxContext)); + WebEndpointTest webEndpointTest = AnnotationUtils + .findAnnotation(extensionContext.getRequiredTestMethod(), WebEndpointTest.class) + .orElseThrow(() -> new IllegalStateException("Unable to find WebEndpointTest annotation on %s" + .formatted(extensionContext.getRequiredTestMethod()))); + return Stream.of(webEndpointTest.infrastructure()).distinct().map(Infrastructure::createInvocationContext); } - private static ConfigurableApplicationContext createJerseyContext(List> classes) { + static ConfigurableApplicationContext createJerseyContext(List> classes) { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); classes.add(JerseyEndpointConfiguration.class); context.register(ClassUtils.toClassArray(classes)); @@ -108,7 +108,7 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation return context; } - private static ConfigurableApplicationContext createWebMvcContext(List> classes) { + static ConfigurableApplicationContext createWebMvcContext(List> classes) { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); classes.add(WebMvcEndpointConfiguration.class); context.register(ClassUtils.toClassArray(classes)); @@ -116,7 +116,7 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation return context; } - private static ConfigurableApplicationContext createWebFluxContext(List> classes) { + static ConfigurableApplicationContext createWebFluxContext(List> classes) { AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext(); classes.add(WebFluxEndpointConfiguration.class); context.register(ClassUtils.toClassArray(classes));