@Test
  public void traceSyncTableBatchEndpoint() throws Exception {
    final Connection connection = connectionRule.getConnection();
    try (final Table table = connection.getTable(TEST_TABLE)) {
      final Descriptors.MethodDescriptor descriptor =
        TestProtobufRpcProto.getDescriptor().findMethodByName("echo");
      final EchoRequestProto request = EchoRequestProto.newBuilder().setMessage("hello").build();
      final Map<byte[], EchoResponseProto> response = TraceUtil.trace(() -> {
        try {
          return table.batchCoprocessorService(descriptor, request, null, null,
            EchoResponseProto.getDefaultInstance());
        } catch (Throwable t) {
          throw new RuntimeException(t);
        }
      }, testName.getMethodName());
      assertNotNull(response);
      assertThat(response.values(),
        everyItem(allOf(notNullValue(), hasProperty("message", equalTo("hello")))));
    }

    final Matcher<SpanData> parentMatcher = allOf(hasName(testName.getMethodName()), hasEnded());
    waitForAndLog(parentMatcher);
    final List<SpanData> spans = otelClassRule.getSpans();

    final SpanData testSpan =
      spans.stream().filter(parentMatcher::matches).findFirst().orElseThrow(AssertionError::new);
    final Matcher<SpanData> tableOpMatcher = allOf(hasName(containsString("COPROC_EXEC")),
      hasParentSpanId(testSpan), hasStatusWithCode(StatusCode.OK));
    assertThat(spans, hasItem(tableOpMatcher));
    final SpanData tableOpSpan =
      spans.stream().filter(tableOpMatcher::matches).findFirst().orElseThrow(AssertionError::new);
    final Matcher<SpanData> rpcMatcher = allOf(hasName("hbase.pb.ClientService/ExecService"),
      hasParentSpanId(tableOpSpan), hasStatusWithCode(StatusCode.OK));
    assertThat(spans, hasItem(rpcMatcher));
  }
Test cases to verify tracing coprocessor Endpoint execution
hbase-endpoint/src/test/java/org/apache/hadoop/hbase/coprocessor/TestCoprocessorEndpointTracing.java