@After public void afterMethod() { resetTracingAndMdc(); }
@Before public void beforeMethod() { channelMock = mock(Channel.class); ctxMock = mock(ChannelHandlerContext.class); stateAttributeMock = mock(Attribute.class); state = new HttpProcessingState(); doReturn(channelMock).when(ctxMock).channel(); doReturn(stateAttributeMock).when(channelMock).attr(ChannelAttributes.HTTP_PROCESSING_STATE_ATTRIBUTE_KEY); doReturn(state).when(stateAttributeMock).get(); runnableMock = mock(Runnable.class); throwExceptionDuringCall = false; currentSpanStackWhenRunnableWasCalled = new ArrayList<>(); currentMdcInfoWhenRunnableWasCalled = new ArrayList<>(); doAnswer(invocation -> { currentSpanStackWhenRunnableWasCalled.add(Tracer.getInstance().getCurrentSpanStackCopy()); currentMdcInfoWhenRunnableWasCalled.add(MDC.getCopyOfContextMap()); if (throwExceptionDuringCall) throw new RuntimeException("kaboom"); return null; }).when(runnableMock).run(); resetTracingAndMdc(); }
@DataProvider(value = { "true", "false" }) @Test public void run_handles_tracing_and_mdc_info_as_expected(boolean throwException) { // given throwExceptionDuringCall = throwException; Tracer.getInstance().startRequestWithRootSpan("foo"); Deque<Span> spanStack = Tracer.getInstance().getCurrentSpanStackCopy(); Map<String, String> mdcInfo = MDC.getCopyOfContextMap(); RunnableWithTracingAndMdcSupport instance = new RunnableWithTracingAndMdcSupport( runnableMock, spanStack, mdcInfo ); resetTracingAndMdc(); assertThat(Tracer.getInstance().getCurrentSpanStackCopy()).isNull(); assertThat(MDC.getCopyOfContextMap()).isEmpty(); // when Throwable ex = catchThrowable(() -> instance.run()); // then verify(runnableMock).run(); if (throwException) assertThat(ex).isNotNull(); else assertThat(ex).isNull(); assertThat(currentSpanStackWhenRunnableWasCalled.get(0)).isEqualTo(spanStack); assertThat(currentMdcInfoWhenRunnableWasCalled.get(0)).isEqualTo(mdcInfo); assertThat(Tracer.getInstance().getCurrentSpanStackCopy()).isNull(); assertThat(MDC.getCopyOfContextMap()).isEmpty(); }