|
23 | 23 | import io.netty.channel.ChannelDuplexHandler;
|
24 | 24 | import io.netty.channel.ChannelHandlerContext;
|
25 | 25 | import io.netty.channel.ChannelInboundHandlerAdapter;
|
| 26 | +import io.netty.channel.ChannelOption; |
26 | 27 | import io.netty.channel.ChannelOutboundHandlerAdapter;
|
27 | 28 | import io.netty.channel.ChannelPipeline;
|
28 | 29 | import io.netty.channel.ChannelPromise;
|
|
98 | 99 | import static reactor.netty.Metrics.DATA_RECEIVED_TIME;
|
99 | 100 | import static reactor.netty.Metrics.DATA_SENT;
|
100 | 101 | import static reactor.netty.Metrics.DATA_SENT_TIME;
|
| 102 | +import static reactor.netty.Metrics.ERROR; |
101 | 103 | import static reactor.netty.Metrics.ERRORS;
|
102 | 104 | import static reactor.netty.Metrics.HTTP_CLIENT_PREFIX;
|
103 | 105 | import static reactor.netty.Metrics.HTTP_SERVER_PREFIX;
|
@@ -730,12 +732,16 @@ void testServerConnectionsMicrometerConnectionClose(HttpProtocol[] serverProtoco
|
730 | 732 | assertThat(ServerCloseHandler.INSTANCE.awaitClientClosedOnServer()).as("awaitClientClosedOnServer timeout").isTrue();
|
731 | 733 | assertGauge(registry, SERVER_CONNECTIONS_TOTAL, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(0);
|
732 | 734 | assertGauge(registry, SERVER_CONNECTIONS_ACTIVE, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(0);
|
| 735 | + // https://github.com/reactor/reactor-netty/issues/3060 |
| 736 | + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/6").hasCountGreaterThanOrEqualTo(1); |
733 | 737 | }
|
734 | 738 | else {
|
735 | 739 | // make sure the client stream is closed on the server side before checking server metrics
|
736 | 740 | assertThat(StreamCloseHandler.INSTANCE.awaitClientClosedOnServer()).as("awaitClientClosedOnServer timeout").isTrue();
|
737 | 741 | assertGauge(registry, SERVER_CONNECTIONS_TOTAL, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(1);
|
738 | 742 | assertGauge(registry, SERVER_STREAMS_ACTIVE, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(0);
|
| 743 | + // https://github.com/reactor/reactor-netty/issues/3060 |
| 744 | + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/6").hasCountGreaterThanOrEqualTo(1); |
739 | 745 | // in case of H2, the tearDown method will ensure client socket is closed on the server side
|
740 | 746 | }
|
741 | 747 | }
|
@@ -828,13 +834,17 @@ void testServerConnectionsRecorderConnectionClose(HttpProtocol[] serverProtocols
|
828 | 834 | assertThat(ServerRecorder.INSTANCE.onActiveConnectionsAmount.get()).isEqualTo(0);
|
829 | 835 | assertThat(ServerRecorder.INSTANCE.onActiveConnectionsLocalAddr.get()).isEqualTo(address);
|
830 | 836 | assertThat(ServerRecorder.INSTANCE.onInactiveConnectionsLocalAddr.get()).isEqualTo(address);
|
| 837 | + // https://github.com/reactor/reactor-netty/issues/3060 |
| 838 | + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/7").hasCountGreaterThanOrEqualTo(1); |
831 | 839 | }
|
832 | 840 | else {
|
833 | 841 | assertThat(StreamCloseHandler.INSTANCE.awaitClientClosedOnServer()).as("awaitClientClosedOnServer timeout").isTrue();
|
834 | 842 | assertThat(ServerRecorder.INSTANCE.onServerConnectionsAmount.get()).isEqualTo(1);
|
835 | 843 | assertThat(ServerRecorder.INSTANCE.onActiveConnectionsAmount.get()).isEqualTo(0);
|
836 | 844 | assertThat(ServerRecorder.INSTANCE.onActiveConnectionsLocalAddr.get()).isEqualTo(address);
|
837 | 845 | assertThat(ServerRecorder.INSTANCE.onInactiveConnectionsLocalAddr.get()).isEqualTo(address);
|
| 846 | + // https://github.com/reactor/reactor-netty/issues/3060 |
| 847 | + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/7").hasCountGreaterThanOrEqualTo(1); |
838 | 848 | // in case of H2, the tearDown method will ensure client socket is closed on the server side
|
839 | 849 | }
|
840 | 850 | }
|
@@ -967,6 +977,27 @@ void testIssue2956(boolean isCustomRecorder, boolean isHttp2) throws Exception {
|
967 | 977 | }
|
968 | 978 | }
|
969 | 979 |
|
| 980 | + @ParameterizedTest |
| 981 | + @MethodSource("httpCompatibleProtocols") |
| 982 | + void testIssue3060ConnectTimeoutException(HttpProtocol[] serverProtocols, HttpProtocol[] clientProtocols, |
| 983 | + @Nullable ProtocolSslContextSpec serverCtx, @Nullable ProtocolSslContextSpec clientCtx) throws Exception { |
| 984 | + CountDownLatch latch = new CountDownLatch(1); |
| 985 | + customizeClientOptions(httpClient, clientCtx, clientProtocols) |
| 986 | + .remoteAddress(() -> new InetSocketAddress("1.1.1.1", 11111)) |
| 987 | + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10) |
| 988 | + .doOnChannelInit((o, c, address) -> c.closeFuture().addListener(f -> latch.countDown())) |
| 989 | + .post() |
| 990 | + .uri("/1") |
| 991 | + .send(ByteBufFlux.fromString(Mono.just("hello"))) |
| 992 | + .responseContent() |
| 993 | + .subscribe(); |
| 994 | + |
| 995 | + assertThat(latch.await(30, TimeUnit.SECONDS)).as("latch await").isTrue(); |
| 996 | + |
| 997 | + String[] summaryTags = new String[]{REMOTE_ADDRESS, "1.1.1.1:11111", STATUS, ERROR}; |
| 998 | + assertTimer(registry, CLIENT_CONNECT_TIME, summaryTags).hasCountEqualTo(1); |
| 999 | + } |
| 1000 | + |
970 | 1001 | static Stream<Arguments> combinationsIssue2956() {
|
971 | 1002 | return Stream.of(
|
972 | 1003 | // isCustomRecorder, isHttp2
|
|
0 commit comments