@Test public void code_coverage_hoops() throws Exception { // jump! // doChannelInactive() does some debug logging if the logger has debug logging enabled. Logger loggerMock = mock(Logger.class); doReturn(true).when(loggerMock).isDebugEnabled(); Whitebox.setInternalState(handler, "logger", loggerMock); handler.doChannelInactive(ctxMock); doReturn(false).when(loggerMock).isDebugEnabled(); handler.doChannelInactive(ctxMock); } }
@Test public void doChannelInactive_does_not_explode_if_crazy_exception_occurs() throws Exception { // given doThrow(new RuntimeException("kaboom")).when(proxyRouterProcessingStateAttributeMock).get(); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@Test public void doChannelInactive_does_not_explode_if_span_is_missing() throws Exception { // given Assertions.assertThat(state.getDistributedTraceStack()).isNull(); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@Test public void doChannelInactive_does_not_propagate_unexpected_exception_while_handling_access_logging( ) throws Exception { // given HttpProcessingState stateSpy = spy(state); doReturn(stateSpy).when(stateAttributeMock).get(); doThrow(new RuntimeException("intentional exception")) .when(accessLoggerMock).log(any(), any(), any(), any()); Assertions.assertThat(stateSpy.isTraceCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isFalse(); verify(requestInfoMock, never()).releaseAllResources(); verify(proxyRouterStateMock, never()).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock, never()).cancelDownstreamRequest(any()); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then // Verify that the exception was thrown. verify(accessLoggerMock).log(any(), any(), any(), any()); // Verify that no other finalization logic was impacted. Assertions.assertThat(stateSpy.isTraceCompletedOrScheduled()).isTrue(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isTrue(); verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@DataProvider(value = { "true", "false" }) @Test public void doChannelInactive_completes_metrics_if_necessary_and_HttpProcessingState_is_not_null( boolean stateIsNull ) throws Exception { // given ChannelPipelineFinalizerHandler handlerSpy = spy(handler); if (stateIsNull) { doReturn(null).when(stateAttributeMock).get(); } // when PipelineContinuationBehavior result = handlerSpy.doChannelInactive(ctxMock); // then if (stateIsNull) { verify(handlerSpy, never()).handleMetricsForCompletedRequestIfNotAlreadyDone(any(HttpProcessingState.class)); } else { verify(handlerSpy).handleMetricsForCompletedRequestIfNotAlreadyDone(state); } }
@Test public void doChannelInactive_does_not_propagate_unexpected_exception_while_releasing_request_resources( ) throws Exception { // given HttpProcessingState stateSpy = spy(state); doReturn(stateSpy).when(stateAttributeMock).get(); doThrow(new RuntimeException("intentional exception")) .when(requestInfoMock).releaseAllResources(); Assertions.assertThat(stateSpy.isTraceCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isFalse(); verify(requestInfoMock, never()).releaseAllResources(); verify(proxyRouterStateMock, never()).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock, never()).cancelDownstreamRequest(any()); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then // Verify that the exception was thrown. verify(requestInfoMock).releaseAllResources(); // Verify that no other finalization logic was impacted. Assertions.assertThat(stateSpy.isTraceCompletedOrScheduled()).isTrue(); Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isTrue(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isTrue(); verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@Test public void doChannelInactive_does_not_propagate_unexpected_exception_while_handling_tracing_completion( ) throws Exception { // given HttpProcessingState stateSpy = spy(state); doReturn(stateSpy).when(stateAttributeMock).get(); doThrow(new RuntimeException("intentional exception")) .when(stateSpy).handleTracingResponseTaggingAndFinalSpanNameIfNotAlreadyDone(); Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isFalse(); verify(requestInfoMock, never()).releaseAllResources(); verify(proxyRouterStateMock, never()).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock, never()).cancelDownstreamRequest(any()); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then // Verify that the exception was thrown. verify(stateSpy).handleTracingResponseTaggingAndFinalSpanNameIfNotAlreadyDone(); // Verify that no other finalization logic was impacted. Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isTrue(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isTrue(); verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@Test public void doChannelInactive_does_not_propagate_unexpected_exception_while_releasing_proxy_router_state_resources( ) throws Exception { // given HttpProcessingState stateSpy = spy(state); doReturn(stateSpy).when(stateAttributeMock).get(); doThrow(new RuntimeException("intentional exception")) .when(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(stateSpy.isTraceCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isFalse(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isFalse(); verify(requestInfoMock, never()).releaseAllResources(); verify(proxyRouterStateMock, never()).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock, never()).cancelDownstreamRequest(any()); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then // Verify that the exception was thrown. verify(requestInfoMock).releaseAllResources(); // Verify that no other finalization logic was impacted. Assertions.assertThat(stateSpy.isTraceCompletedOrScheduled()).isTrue(); Assertions.assertThat(stateSpy.isAccessLogCompletedOrScheduled()).isTrue(); Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isTrue(); verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock);
@Test public void doChannelInactive_does_not_try_to_recomplete_span_if_already_completed() throws Exception { // given Span span = setupTracingForChannelInactive(false); Deque<Span> deque = new LinkedList<>(); deque.add(span); Tracer.getInstance().registerWithThread(deque); Tracer.getInstance().completeRequestSpan(); Assertions.assertThat(span.isCompleted()).isTrue(); long durationNanosBefore = span.getDurationNanos(); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then Assertions.assertThat(span.isCompleted()).isTrue(); // no change Assertions.assertThat(span.getDurationNanos()).isEqualTo(durationNanosBefore); verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@DataProvider(value = { "true | true", "false | true", "true | false", "false | false" }, splitBy = "\\|") @Test public void doChannelInactive_completes_releases_resources_and_completes_tracing_if_necessary( boolean tracingAlreadyDone, boolean responseSendingCompleted ) throws Exception { // given Span span = setupTracingForChannelInactive(tracingAlreadyDone); doReturn(responseSendingCompleted).when(responseInfoMock).isResponseSendingLastChunkSent(); if (responseSendingCompleted) { state.setResponseWriterFinalChunkChannelFuture(mock(ChannelFuture.class)); } // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then Assertions.assertThat(span.isCompleted()).isEqualTo(!tracingAlreadyDone); Assertions.assertThat(state.isTraceCompletedOrScheduled()).isTrue(); verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }
@DataProvider(value = { "true | false", "false | true" }, splitBy = "\\|") @Test public void doChannelInactive_should_not_call_accessLogger_if_accessLogger_is_null_or_access_logging_already_scheduled( boolean accessLoggerIsNull, boolean accessLoggingAlreadyScheduled ) throws Exception { // given if (accessLoggerIsNull) Whitebox.setInternalState(handler, "accessLogger", null); state.setAccessLogCompletedOrScheduled(accessLoggingAlreadyScheduled); // when handler.doChannelInactive(ctxMock); // then verifyZeroInteractions(accessLoggerMock); Assertions.assertThat(state.isAccessLogCompletedOrScheduled()).isEqualTo(accessLoggingAlreadyScheduled); }
handler.doChannelInactive(ctxMock);
@DataProvider(value = { "true | false", "false | true", "true | true" }, splitBy = "\\|") @Test public void doChannelInactive_does_what_it_can_when_the_RequestInfo_or_ResponseInfo_is_null( boolean requestInfoIsNull, boolean responseInfoIsNull ) throws Exception { // given Span span = setupTracingForChannelInactive(false); if (requestInfoIsNull) state.setRequestInfo(null); if (responseInfoIsNull) state.setResponseInfo(null, null); // when PipelineContinuationBehavior result = handler.doChannelInactive(ctxMock); // then Assertions.assertThat(span.isCompleted()).isTrue(); Assertions.assertThat(state.isTraceCompletedOrScheduled()).isTrue(); if (requestInfoIsNull) verifyZeroInteractions(requestInfoMock); else verify(requestInfoMock).releaseAllResources(); verify(proxyRouterStateMock).cancelRequestStreaming(any(), any()); verify(proxyRouterStateMock).cancelDownstreamRequest(any()); Assertions.assertThat(result).isEqualTo(PipelineContinuationBehavior.CONTINUE); }