@Test
  public void testExecuteHttpCodeNoSuccess() throws Exception {

    final SpanId mockSpanId = mock(SpanId.class);
    when(mockSpanId.getTraceId()).thenReturn(TRACE_ID);
    when(mockSpanId.getSpanId()).thenReturn(SPAN_ID);
    when(mockSpanId.getParentSpanId()).thenReturn(PARENT_SPAN_ID);

    when(mockClientTracer.startNewSpan(PATH)).thenReturn(mockSpanId);
    when(mockClientResponse.getStatus()).thenReturn(SERVER_ERROR_STATUS);

    assertSame(mockClientResponse, interceptor.execute(mockExecutionContext));

    final InOrder inOrder = inOrder(mockClientTracer, mockClientRequest, mockExecutionContext);

    inOrder.verify(mockClientTracer).startNewSpan(PATH);
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.Sampled.getName(), "true");
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.TraceId.getName(), TRACE_ID_HEX);
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.SpanId.getName(), SPAN_ID_HEX);
    inOrder
        .verify(mockClientRequest)
        .header(BraveHttpHeaders.ParentSpanId.getName(), PARENT_SPAN_ID_HEX);
    inOrder.verify(mockClientTracer).setCurrentClientServiceName(CONTEXT_PATH);
    inOrder
        .verify(mockClientTracer)
        .submitBinaryAnnotation(REQUEST_ANNOTATION, HTTP_METHOD + " " + URI);
    inOrder.verify(mockClientTracer).setClientSent();
    inOrder.verify(mockExecutionContext).proceed();
    inOrder
        .verify(mockClientTracer)
        .submitBinaryAnnotation("http.responsecode", SERVER_ERROR_STATUS);
    inOrder.verify(mockClientTracer).submitAnnotation("failure");
    inOrder.verify(mockClientTracer).setClientReceived();
    verifyNoMoreInteractions(mockClientTracer);
  }
  @Test
  public void testExecuteTracingNoParentSpan() throws Exception {

    final SpanId mockSpanId = mock(SpanId.class);
    when(mockSpanId.getTraceId()).thenReturn(TRACE_ID);
    when(mockSpanId.getSpanId()).thenReturn(SPAN_ID);
    when(mockSpanId.getParentSpanId()).thenReturn(null);

    when(mockClientTracer.startNewSpan(PATH)).thenReturn(mockSpanId);
    assertSame(mockClientResponse, interceptor.execute(mockExecutionContext));

    final InOrder inOrder = inOrder(mockClientTracer, mockClientRequest, mockExecutionContext);

    inOrder.verify(mockClientTracer).startNewSpan(PATH);
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.Sampled.getName(), "true");
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.TraceId.getName(), TRACE_ID_HEX);
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.SpanId.getName(), SPAN_ID_HEX);
    inOrder.verify(mockClientTracer).setCurrentClientServiceName(CONTEXT_PATH);
    inOrder
        .verify(mockClientTracer)
        .submitBinaryAnnotation(REQUEST_ANNOTATION, HTTP_METHOD + " " + URI);
    inOrder.verify(mockClientTracer).setClientSent();
    inOrder.verify(mockExecutionContext).proceed();
    inOrder
        .verify(mockClientTracer)
        .submitBinaryAnnotation(HTTP_RESPONSE_CODE_ANNOTATION, OK_STATUS);
    inOrder.verify(mockClientTracer).setClientReceived();
    verifyNoMoreInteractions(mockClientTracer);
  }
  @Before
  public void setup() throws IOException {
    clientTracer = mock(ClientTracer.class);
    spanId = mock(SpanId.class);
    when(spanId.getParentSpanId()).thenReturn(null);
    when(spanId.getSpanId()).thenReturn(SPAN_ID);
    when(spanId.getTraceId()).thenReturn(TRACE_ID);

    responseProvider = new DefaultHttpResponseProvider(true);
    mockServer = new MockHttpServer(PORT, responseProvider);
    mockServer.start();
  }
  @Test
  public void testExecuteProceedThrowsException() throws Exception {

    final SpanId mockSpanId = mock(SpanId.class);
    when(mockSpanId.getTraceId()).thenReturn(TRACE_ID);
    when(mockSpanId.getSpanId()).thenReturn(SPAN_ID);
    when(mockSpanId.getParentSpanId()).thenReturn(PARENT_SPAN_ID);

    when(mockClientTracer.startNewSpan(PATH)).thenReturn(mockSpanId);
    final IllegalStateException exception = new IllegalStateException("Test exception");
    when(mockExecutionContext.proceed()).thenThrow(exception);

    try {
      interceptor.execute(mockExecutionContext);
      fail("Expected exception.");
    } catch (final IllegalStateException e) {
      assertSame(exception, e);
    }

    final InOrder inOrder = inOrder(mockClientTracer, mockClientRequest, mockExecutionContext);

    inOrder.verify(mockClientTracer).startNewSpan(PATH);
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.Sampled.getName(), "true");
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.TraceId.getName(), TRACE_ID_HEX);
    inOrder.verify(mockClientRequest).header(BraveHttpHeaders.SpanId.getName(), SPAN_ID_HEX);
    inOrder
        .verify(mockClientRequest)
        .header(BraveHttpHeaders.ParentSpanId.getName(), Long.toHexString(PARENT_SPAN_ID));
    inOrder.verify(mockClientTracer).setCurrentClientServiceName(CONTEXT_PATH);
    inOrder
        .verify(mockClientTracer)
        .submitBinaryAnnotation(REQUEST_ANNOTATION, HTTP_METHOD + " " + URI);
    inOrder.verify(mockClientTracer).setClientSent();
    inOrder.verify(mockExecutionContext).proceed();
    inOrder.verify(mockClientTracer).submitBinaryAnnotation(HTTP_RESPONSE_CODE_ANNOTATION, 0);
    inOrder.verify(mockClientTracer).submitAnnotation("failure");
    inOrder.verify(mockClientTracer).setClientReceived();
    verifyNoMoreInteractions(mockClientTracer);
  }
  private static SpanCollectingReporter testServiceInvocation(boolean sampled) throws Exception {
    SpanCollectingReporter reporter = new SpanCollectingReporter();

    Brave brave =
        new Brave.Builder(TEST_SERVICE)
            .reporter(reporter)
            .traceSampler(Sampler.create(1.0f))
            .build();

    @SuppressWarnings("unchecked")
    Service<ThriftCall, ThriftReply> delegate = mock(Service.class);

    TraceData traceData =
        TraceData.builder()
            .sample(sampled)
            .spanId(SpanId.builder().traceId(1).spanId(2).parentId(3L).build())
            .build();

    TracingServiceImpl stub = new TracingServiceImpl(delegate, brave, traceData);

    ThriftCall req = new ThriftCall(0, HelloService.Iface.class, "hello", "trustin");
    DefaultRequestLog reqLog = new DefaultRequestLog();
    reqLog.start(mock(Channel.class), SessionProtocol.H2C, "localhost", TEST_METHOD, "/");
    reqLog.end();

    ServiceRequestContext ctx = mock(ServiceRequestContext.class);
    // AbstractTracingService prefers RpcRequest.method() to ctx.method(), so "POST" should be
    // ignored.
    when(ctx.method()).thenReturn("POST");
    when(ctx.requestLogFuture()).thenReturn(reqLog);
    ctx.onEnter(ArgumentMatchers.isA(Runnable.class));
    ctx.onExit(ArgumentMatchers.isA(Runnable.class));

    ThriftReply res = new ThriftReply(0, "Hello, trustin!");
    when(delegate.serve(ctx, req)).thenReturn(res);

    // do invoke
    stub.serve(ctx, req);

    verify(delegate, times(1)).serve(eq(ctx), eq(req));
    return reporter;
  }