Browse Source

Remove static state from CF web endpoint integration tests

The mocks being static meant that their state was shared across each
test in the class. This resulted in the tests being order dependent.
This commit uses instance variables to hold the mocks, thereby
ensuring that they're recreated for each test as part of the standard
JUnit lifecycle.

Closes gh-38363
pull/38403/head
Andy Wilkinson 2 years ago
parent
commit
c2156d6803
  1. 28
      spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java
  2. 43
      spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java

28
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java

@ -75,22 +75,23 @@ import static org.mockito.Mockito.mock; @@ -75,22 +75,23 @@ import static org.mockito.Mockito.mock;
*/
class CloudFoundryWebFluxEndpointIntegrationTests {
private static ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
private final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
private static ReactiveCloudFoundrySecurityService securityService = mock(
ReactiveCloudFoundrySecurityService.class);
private final ReactiveCloudFoundrySecurityService securityService = mock(ReactiveCloudFoundrySecurityService.class);
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
AnnotationConfigReactiveWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class,
ReactiveWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(TestEndpointConfiguration.class)
.withBean(ReactiveTokenValidator.class, () -> this.tokenValidator)
.withBean(ReactiveCloudFoundrySecurityService.class, () -> this.securityService)
.withPropertyValues("server.port=0");
@Test
void operationWithSecurityInterceptorForbidden() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
@ -102,8 +103,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests { @@ -102,8 +103,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
@Test
void operationWithSecurityInterceptorSuccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
@ -131,8 +132,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests { @@ -131,8 +132,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithFullAccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
@ -169,7 +170,7 @@ class CloudFoundryWebFluxEndpointIntegrationTests { @@ -169,7 +170,7 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
void linksToOtherEndpointsForbidden() {
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
"invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
willThrow(exception).given(this.tokenValidator).validate(any());
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
@ -181,8 +182,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests { @@ -181,8 +182,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithRestrictedAccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
@ -232,7 +233,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests { @@ -232,7 +233,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
static class CloudFoundryReactiveConfiguration {
@Bean
CloudFoundrySecurityInterceptor interceptor() {
CloudFoundrySecurityInterceptor interceptor(ReactiveTokenValidator tokenValidator,
ReactiveCloudFoundrySecurityService securityService) {
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
}

43
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java

@ -42,6 +42,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMapping; @@ -42,6 +42,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
@ -70,13 +71,13 @@ import static org.mockito.Mockito.mock; @@ -70,13 +71,13 @@ import static org.mockito.Mockito.mock;
*/
class CloudFoundryMvcWebEndpointIntegrationTests {
private static TokenValidator tokenValidator = mock(TokenValidator.class);
private final TokenValidator tokenValidator = mock(TokenValidator.class);
private static CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
private final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
@Test
void operationWithSecurityInterceptorForbidden() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication/test")
@ -89,7 +90,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests { @@ -89,7 +90,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
void operationWithSecurityInterceptorSuccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication/test")
@ -119,7 +120,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests { @@ -119,7 +120,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithFullAccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication")
@ -157,7 +158,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests { @@ -157,7 +158,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
void linksToOtherEndpointsForbidden() {
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
"invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
willThrow(exception).given(this.tokenValidator).validate(any());
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication")
@ -170,7 +171,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests { @@ -170,7 +171,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithRestrictedAccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication")
@ -198,26 +199,23 @@ class CloudFoundryMvcWebEndpointIntegrationTests { @@ -198,26 +199,23 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
.doesNotExist());
}
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(Class<?>... config) {
return new AnnotationConfigServletWebServerApplicationContext(config);
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
.withUserConfiguration(configuration, CloudFoundryMvcConfiguration.class)
.withBean(TokenValidator.class, () -> this.tokenValidator)
.withBean(CloudFoundrySecurityService.class, () -> this.securityService)
.run((context) -> consumer.accept(context, WebTestClient.bindToServer()
.baseUrl("http://localhost:" + getPort(
(AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext()))
.responseTimeout(Duration.ofMinutes(5))
.build()));
}
private int getPort(AnnotationConfigServletWebServerApplicationContext context) {
return context.getWebServer().getPort();
}
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
try (AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(configuration,
CloudFoundryMvcConfiguration.class)) {
consumer.accept(context,
WebTestClient.bindToServer()
.baseUrl("http://localhost:" + getPort(context))
.responseTimeout(Duration.ofMinutes(5))
.build());
}
}
private String mockAccessToken() {
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu"
+ "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ."
@ -229,7 +227,8 @@ class CloudFoundryMvcWebEndpointIntegrationTests { @@ -229,7 +227,8 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
static class CloudFoundryMvcConfiguration {
@Bean
CloudFoundrySecurityInterceptor interceptor() {
CloudFoundrySecurityInterceptor interceptor(TokenValidator tokenValidator,
CloudFoundrySecurityService securityService) {
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
}

Loading…
Cancel
Save