SofaTracerCallable implements Callable<T> { @Override public T call() throws Exception { if (Thread.currentThread().getId() != tid) { if (currentSpan != null) { traceContext.push(currentSpan); SpanExtensionFactory.logStartedSpan(currentSpan); } } try { return wrappedCallable.call(); } finally { if (Thread.currentThread().getId() != tid) { if (currentSpan != null) { traceContext.pop(); } } } } SofaTracerCallable(Callable<T> wrappedCallable);  SofaTracerCallable(Callable<T> wrappedCallable, SofaTraceContext traceContext); @Override T call();  }
@Test public void testInstrumentedCallable() throws Exception { SofaTracerCallable wrappedCallable = Mockito.mock(SofaTracerCallable.class); Mockito.when(wrappedCallable.call()).thenReturn(span); SofaTracerCallable<Span> spanSofaTracerCallable = new SofaTracerCallable<Span>( wrappedCallable, traceContext); spanSofaTracerCallable.call(); Mockito.verify(traceContext, Mockito.times(1)).isEmpty(); Mockito.verify(traceContext, Mockito.times(1)).getCurrentSpan(); Mockito.verify(wrappedCallable, Mockito.times(1)).call(); Mockito.verifyNoMoreInteractions(traceContext, wrappedCallable); }
@Test public void testInstrumentedCallableNoCurrentSpan() throws Exception { SofaTracerCallable wrappedCallable = Mockito.mock(SofaTracerCallable.class); Mockito.when(wrappedCallable.call()).thenReturn(span); Mockito.when(traceContext.isEmpty()).thenReturn(true); SofaTracerCallable<Span> spanSofaTracerCallable = new SofaTracerCallable<Span>( wrappedCallable, traceContext); spanSofaTracerCallable.call(); Mockito.verify(traceContext, Mockito.times(1)).isEmpty(); Mockito.verify(wrappedCallable, Mockito.times(1)).call(); Mockito.verifyNoMoreInteractions(traceContext, wrappedCallable); }