From d597d2e1597bbbd75967325a906669f9bc455081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Basl=C3=A9?= Date: Mon, 18 Nov 2024 16:30:16 +0100 Subject: [PATCH] Fix WebClientIntegrationTest#applyAttributesToNativeRequest flaky test For Reactor Netty and Reactor Netty 2 (with Netty 5), the attributes are stored as an `Attribute` on the netty channel. Reactor Netty replaces the channel with a static placeholder one once the request has been processed and as such, capturing the native request in the test will lead to asserting an attribute-less channel. This change switches to capturing the `Attribute` itself, which is a value-holder that can be asserted later on. Closes gh-33909 --- .../client/WebClientIntegrationTests.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index 35abb5e76a0..f30a99f8a1d 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -83,7 +83,6 @@ import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import org.springframework.web.testfixture.xml.Pojo; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.junit.jupiter.params.provider.Arguments.argumentSet; /** @@ -108,6 +107,7 @@ class WebClientIntegrationTests { static Stream arguments() { return Stream.of( argumentSet("Reactor Netty", new ReactorClientHttpConnector()), + argumentSet("Reactor Netty 2", new ReactorNetty2ClientHttpConnector()), argumentSet("JDK", new JdkClientHttpConnector()), argumentSet("Jetty", new JettyClientHttpConnector()), argumentSet("HttpComponents", new HttpComponentsClientHttpConnector()) @@ -193,8 +193,6 @@ class WebClientIntegrationTests { @ParameterizedWebClientTest void applyAttributesToNativeRequest(ClientHttpConnector connector) { - assumeFalse(connector instanceof ReactorClientHttpConnector, - "Temporarily disabling flaky test for Reactor Netty"); startServer(connector); prepareResponse(response -> {}); @@ -202,20 +200,32 @@ class WebClientIntegrationTests { Mono result = this.webClient.get() .uri("/pojo") .attribute("foo","bar") - .httpRequest(clientHttpRequest -> nativeRequest.set(clientHttpRequest.getNativeRequest())) + .httpRequest(clientHttpRequest -> { + if (clientHttpRequest instanceof ChannelOperations nettyReq) { + nativeRequest.set(nettyReq.channel().attr(ReactorClientHttpConnector.ATTRIBUTES_KEY)); + } + else if (clientHttpRequest instanceof reactor.netty5.channel.ChannelOperations nettyReq) { + nativeRequest.set(nettyReq.channel().attr(ReactorNetty2ClientHttpConnector.ATTRIBUTES_KEY)); + } + else { + nativeRequest.set(clientHttpRequest.getNativeRequest()); + } + }) .retrieve() .bodyToMono(Void.class); StepVerifier.create(result).expectComplete().verify(); - if (nativeRequest.get() instanceof ChannelOperations nativeReq) { - Attribute> attributes = nativeReq.channel().attr(ReactorClientHttpConnector.ATTRIBUTES_KEY); + if (nativeRequest.get() instanceof Attribute) { + @SuppressWarnings("unchecked") + Attribute> attributes = (Attribute>) nativeRequest.get(); assertThat(attributes.get()).isNotNull(); assertThat(attributes.get()).containsEntry("foo", "bar"); } - else if (nativeRequest.get() instanceof reactor.netty5.channel.ChannelOperations nativeReq) { + else if (nativeRequest.get() instanceof io.netty5.util.Attribute) { + @SuppressWarnings("unchecked") io.netty5.util.Attribute> attributes = - nativeReq.channel().attr(ReactorNetty2ClientHttpConnector.ATTRIBUTES_KEY); + (io.netty5.util.Attribute>) nativeRequest.get(); assertThat(attributes.get()).isNotNull(); assertThat(attributes.get()).containsEntry("foo", "bar"); }