From 687251c1b0659b4c1aaf8864ef4c023884bcc0fe Mon Sep 17 00:00:00 2001 From: KirillKurdyukov Date: Fri, 24 Jul 2026 17:34:24 +0300 Subject: [PATCH] rollback otel tests --- query/pom.xml | 12 - .../tech/ydb/query/impl/QueryTracingTest.java | 6 + ...nTelemetryQueryTracingIntegrationTest.java | 584 ------------------ 3 files changed, 6 insertions(+), 596 deletions(-) delete mode 100644 query/src/test/java/tech/ydb/query/opentelemetry/OpenTelemetryQueryTracingIntegrationTest.java diff --git a/query/pom.xml b/query/pom.xml index 5ddbb0e02..433adbfa1 100644 --- a/query/pom.xml +++ b/query/pom.xml @@ -36,18 +36,6 @@ true - - io.opentelemetry - opentelemetry-sdk - ${opentelemetry.version} - test - - - io.opentelemetry - opentelemetry-sdk-testing - ${opentelemetry.version} - test - junit junit diff --git a/query/src/test/java/tech/ydb/query/impl/QueryTracingTest.java b/query/src/test/java/tech/ydb/query/impl/QueryTracingTest.java index 9d1701328..5ce7053f7 100644 --- a/query/src/test/java/tech/ydb/query/impl/QueryTracingTest.java +++ b/query/src/test/java/tech/ydb/query/impl/QueryTracingTest.java @@ -586,6 +586,12 @@ boolean hasLongAttribute(String key) { @Override public String getId() { + // Transport reads TRACEPARENT via getId() on the call path; span must already be current. + Assert.assertSame( + "Span must be current when getId() is called (missing makeCurrent?)", + this, + tracer.currentSpan.get() + ); return name + ":" + kind; } diff --git a/query/src/test/java/tech/ydb/query/opentelemetry/OpenTelemetryQueryTracingIntegrationTest.java b/query/src/test/java/tech/ydb/query/opentelemetry/OpenTelemetryQueryTracingIntegrationTest.java deleted file mode 100644 index 1dc0bf4ba..000000000 --- a/query/src/test/java/tech/ydb/query/opentelemetry/OpenTelemetryQueryTracingIntegrationTest.java +++ /dev/null @@ -1,584 +0,0 @@ -package tech.ydb.query.opentelemetry; - -import java.time.Duration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.context.Scope; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -import tech.ydb.auth.TokenAuthProvider; -import tech.ydb.common.transaction.TxMode; -import tech.ydb.core.Result; -import tech.ydb.core.Status; -import tech.ydb.core.StatusCode; -import tech.ydb.core.UnexpectedResultException; -import tech.ydb.core.grpc.GrpcTransport; -import tech.ydb.core.tracing.OpenTelemetryTracer; -import tech.ydb.query.QueryClient; -import tech.ydb.query.QuerySession; -import tech.ydb.query.QueryTransaction; -import tech.ydb.query.result.QueryInfo; -import tech.ydb.query.tools.SessionRetryContext; -import tech.ydb.table.Session; -import tech.ydb.table.TableClient; -import tech.ydb.table.query.DataQueryResult; -import tech.ydb.table.query.Params; -import tech.ydb.table.transaction.TableTransaction; -import tech.ydb.test.junit4.YdbHelperRule; - -public class OpenTelemetryQueryTracingIntegrationTest { - @ClassRule - public static final YdbHelperRule YDB = new YdbHelperRule(); - - private static final AttributeKey DB_SYSTEM_NAME = AttributeKey.stringKey("db.system.name"); - private static final AttributeKey DB_NAMESPACE = AttributeKey.stringKey("db.namespace"); - private static final AttributeKey SERVER_ADDRESS = AttributeKey.stringKey("server.address"); - private static final AttributeKey SERVER_PORT = AttributeKey.longKey("server.port"); - - private static final AttributeKey STATUS_CODE = AttributeKey.stringKey("db.response.status_code"); - private static final AttributeKey ERROR_TYPE = AttributeKey.stringKey("error.type"); - - private static InMemorySpanExporter spanExporter; - private static SdkTracerProvider tracerProvider; - private static Tracer appTracer; - private static GrpcTransport transport; - - private QueryClient queryClient; - - @BeforeClass - public static void initTransport() { - spanExporter = InMemorySpanExporter.create(); - tracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) - .build(); - OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setTracerProvider(tracerProvider) - .build(); - appTracer = openTelemetry.getTracer("test.app"); - transport = GrpcTransport.forEndpoint(YDB.endpoint(), YDB.database()) - .withAuthProvider(new TokenAuthProvider(YDB.authToken())) - .withTracer(OpenTelemetryTracer.fromOpenTelemetry(openTelemetry)) - .build(); - } - - @AfterClass - public static void closeTransport() { - transport.close(); - tracerProvider.close(); - spanExporter.close(); - } - - @Before - public void initClients() { - spanExporter.reset(); - queryClient = QueryClient.newClient(transport).build(); - } - - @After - public void closeClients() { - queryClient.close(); - } - - /** - * Finished spans for assertions. {@link SimpleSpanProcessor} exports to {@link InMemorySpanExporter} - * synchronously from {@code Span.end()}, so {@link SdkTracerProvider#forceFlush()} is unnecessary here - * and was flaky under load (timeouts / non-success completion codes). - */ - private static List exportedSpans() { - return spanExporter.getFinishedSpanItems(); - } - - /** - * After {@code CompletableFuture#join()} the outer {@code ydb.RunWithRetry} span may not be - * ended/exported yet; poll until it appears (or timeout) before counting it in assertions. - */ - private List exportedSpansWhenRunWithRetryPresent() { - long deadlineMs = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(30); - while (System.currentTimeMillis() < deadlineMs) { - List spans = spanExporter.getFinishedSpanItems(); - boolean hasOuter = spans.stream().anyMatch(s -> "ydb.RunWithRetry".equals(s.getName())); - if (hasOuter) { - return spanExporter.getFinishedSpanItems(); - } - try { - Thread.sleep(5); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new AssertionError(e); - } - } - return exportedSpans(); - } - - @Test - public void queryClientSpansHaveBaseAttributes() { - try (QuerySession session = queryClient.createSession(Duration.ofSeconds(5)).join().getValue()) { - assertSpanOK("ydb.CreateSession", 1); - assertSpanOK("ydb.ExecuteQuery", 0); - assertSpanOK("ydb.Commit", 0); - assertSpanOK("ydb.Rollback", 0); - - session.createQuery("SELECT 1", TxMode.NONE).execute().join().getStatus().expectSuccess(); - - assertSpanOK("ydb.ExecuteQuery", 1); - assertSpanOK("ydb.Commit", 0); - assertSpanOK("ydb.Rollback", 0); - - Result txCommit = session.beginTransaction(TxMode.SERIALIZABLE_RW).join(); - txCommit.getStatus().expectSuccess(); - - assertSpanOK("ydb.ExecuteQuery", 1); - assertSpanOK("ydb.Commit", 0); - assertSpanOK("ydb.Rollback", 0); - - Result queryInCommitTx = txCommit.getValue().createQuery("SELECT 1").execute().join(); - queryInCommitTx.getStatus().expectSuccess(); - Result commitResult = txCommit.getValue().commit().join(); - commitResult.getStatus().expectSuccess(); - - assertSpanOK("ydb.ExecuteQuery", 2); - assertSpanOK("ydb.Commit", 1); - assertSpanOK("ydb.Rollback", 0); - - Result txRollback = session.beginTransaction(TxMode.SERIALIZABLE_RW).join(); - txRollback.getStatus().expectSuccess(); - Result queryInRollbackTx = txRollback.getValue().createQuery("SELECT 1").execute().join(); - queryInRollbackTx.getStatus().expectSuccess(); - Status rollbackStatus = txRollback.getValue().rollback().join(); - rollbackStatus.expectSuccess(); - } - - assertSpanOK("ydb.CreateSession", 1); - assertSpanOK("ydb.ExecuteQuery", 3); - assertSpanOK("ydb.Commit", 1); - assertSpanOK("ydb.Rollback", 1); - } - - @Test - public void queryClientErrorSpans() { - try (QuerySession session = queryClient.createSession(Duration.ofSeconds(5)).join().getValue()) { - assertSpanOK("ydb.CreateSession", 1); - - Status status = session.createQuery("SELECT 'u'u - 1;", TxMode.NONE).execute().join().getStatus(); - Assert.assertEquals(StatusCode.GENERIC_ERROR, status.getCode()); - - assertSpanError("ydb.ExecuteQuery", 1, status); - } - } - - @Test - public void tableClientProxySpansHaveBaseAttributes() { - try (TableClient tableClient = QueryClient.newTableClient(transport).build()) { - try (Session session = tableClient.createSession(Duration.ofSeconds(5)).join().getValue()) { - TableTransaction txCommit = session.createNewTransaction(TxMode.SERIALIZABLE_RW); - Result queryInCommitTx = txCommit.executeDataQuery("SELECT 1", Params.empty()).join(); - queryInCommitTx.getStatus().expectSuccess(); - Status commitStatus = txCommit.commit().join(); - commitStatus.expectSuccess(); - - TableTransaction txRollback = session.createNewTransaction(TxMode.SERIALIZABLE_RW); - Result queryInRollbackTx = txRollback.executeDataQuery("SELECT 1", Params.empty()).join(); - queryInRollbackTx.getStatus().expectSuccess(); - Status rollbackStatus = txRollback.rollback().join(); - rollbackStatus.expectSuccess(); - } - } - - assertSpanOK("ydb.CreateSession", 1); - assertSpanOK("ydb.ExecuteQuery", 2); - assertSpanOK("ydb.Commit", 1); - assertSpanOK("ydb.Rollback", 1); - } - - @Test - public void sdkSpanIsChildOfApplicationSpan() { - try (QuerySession session = queryClient.createSession(Duration.ofSeconds(5)).join().getValue()) { - io.opentelemetry.api.trace.Span appSpan = appTracer.spanBuilder("app.parent").startSpan(); - try (Scope scope = appSpan.makeCurrent()) { - Assert.assertNotNull(scope); - session.createQuery("SELECT 1", TxMode.NONE).execute().join().getStatus().expectSuccess(); - } finally { - appSpan.end(); - } - - List spans = exportedSpans(); - SpanData sdkSpan = null; - for (SpanData span : spans) { - if ("ydb.ExecuteQuery".equals(span.getName())) { - sdkSpan = span; - break; - } - } - - Assert.assertNotNull("SDK span not found", sdkSpan); - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), sdkSpan.getTraceId()); - Assert.assertEquals(appSpan.getSpanContext().getSpanId(), sdkSpan.getParentSpanId()); - } - } - - @Test - public void retrySpanIsParentForRpcSpans() { - AtomicInteger attempt = new AtomicInteger(); - SessionRetryContext retryContext = SessionRetryContext.create(queryClient) - .maxRetries(1) - .backoffSlot(Duration.ofMillis(1)) - .fastBackoffSlot(Duration.ofMillis(1)) - .build(); - - io.opentelemetry.api.trace.Span appSpan = appTracer.spanBuilder("app.parent.retry").startSpan(); - try (Scope scope = appSpan.makeCurrent()) { - Assert.assertNotNull(scope); - Status status = retryContext.supplyStatus(session -> { - if (attempt.getAndIncrement() == 0) { - return CompletableFuture.completedFuture(Status.of(StatusCode.OVERLOADED)); - } - return session.createQuery("SELECT 1", TxMode.NONE).execute().thenApply(Result::getStatus); - }).join(); - status.expectSuccess(); - } finally { - appSpan.end(); - } - - List spans = exportedSpansWhenRunWithRetryPresent(); - SpanData querySpan = null; - String executeSpanId = null; - Set retrySpanIds = new HashSet<>(); - int executeSpansCount = 0; - int retrySpansCount = 0; - - for (SpanData span : spans) { - if ("ydb.RunWithRetry".equals(span.getName())) { - executeSpansCount++; - executeSpanId = span.getSpanId(); - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), span.getTraceId()); - Assert.assertEquals(appSpan.getSpanContext().getSpanId(), span.getParentSpanId()); - } - if ("ydb.Try".equals(span.getName())) { - retrySpansCount++; - retrySpanIds.add(span.getSpanId()); - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), span.getTraceId()); - } - if ("ydb.ExecuteQuery".equals(span.getName())) { - querySpan = span; - } - } - - Assert.assertEquals(1, executeSpansCount); - Assert.assertNotNull(executeSpanId); - Assert.assertEquals(2, retrySpansCount); - for (SpanData span : spans) { - if ("ydb.Try".equals(span.getName())) { - Assert.assertEquals(executeSpanId, span.getParentSpanId()); - } - } - Assert.assertNotNull("Retry should produce query rpc span", querySpan); - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), querySpan.getTraceId()); - Assert.assertTrue("RPC span parent must be Retry span", - retrySpanIds.contains(querySpan.getParentSpanId())); - } - - @Test - public void tableProxyRetrySpanIsParentForRpcSpans() { - AtomicInteger attempt = new AtomicInteger(); - io.opentelemetry.api.trace.Span appSpan = appTracer.spanBuilder("app.parent.table.retry").startSpan(); - try (Scope scope = appSpan.makeCurrent()) { - Assert.assertNotNull(scope); - try (TableClient tableClient = QueryClient.newTableClient(transport).build()) { - tech.ydb.table.SessionRetryContext retryContext = tech.ydb.table.SessionRetryContext.create(tableClient) - .maxRetries(1) - .backoffSlot(Duration.ofMillis(1)) - .fastBackoffSlot(Duration.ofMillis(1)) - .build(); - - Status status = retryContext.supplyStatus(session -> { - if (attempt.getAndIncrement() == 0) { - return CompletableFuture.completedFuture(Status.of(StatusCode.OVERLOADED)); - } - TableTransaction tx = session.createNewTransaction(TxMode.SERIALIZABLE_RW); - Result queryResult = tx.executeDataQuery("SELECT 1", Params.empty()).join(); - queryResult.getStatus().expectSuccess(); - return tx.commit(); - }).join(); - status.expectSuccess(); - } - } finally { - appSpan.end(); - } - - assertSpanOK("ydb.CreateSession", 1); - assertSpanOK("ydb.ExecuteQuery", 1); - assertSpanOK("ydb.Commit", 1); - - List spans = exportedSpansWhenRunWithRetryPresent(); - String executeSpanId = null; - int executeSpansCount = 0; - Set retrySpanIds = new HashSet<>(); - - for (SpanData span : spans) { - if ("ydb.RunWithRetry".equals(span.getName())) { - executeSpansCount++; - executeSpanId = span.getSpanId(); - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), span.getTraceId()); - Assert.assertEquals(appSpan.getSpanContext().getSpanId(), span.getParentSpanId()); - } - if ("ydb.Try".equals(span.getName())) { - retrySpanIds.add(span.getSpanId()); - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), span.getTraceId()); - } - } - Assert.assertEquals(1, executeSpansCount); - Assert.assertNotNull(executeSpanId); - for (SpanData span : spans) { - if ("ydb.Try".equals(span.getName())) { - Assert.assertEquals(executeSpanId, span.getParentSpanId()); - } - } - Assert.assertEquals(2, retrySpanIds.size()); - - int createSessionChildren = 0; - int executeQueryChildren = 0; - int commitChildren = 0; - - for (SpanData span : spans) { - if ("ydb.CreateSession".equals(span.getName()) && retrySpanIds.contains(span.getParentSpanId())) { - createSessionChildren++; - } - if ("ydb.ExecuteQuery".equals(span.getName()) && retrySpanIds.contains(span.getParentSpanId())) { - executeQueryChildren++; - } - if ("ydb.Commit".equals(span.getName()) && retrySpanIds.contains(span.getParentSpanId())) { - commitChildren++; - } - } - - Assert.assertTrue("CreateSession span must be child of Retry", createSessionChildren >= 1); - Assert.assertTrue("ExecuteQuery span must be child of Retry", executeQueryChildren >= 1); - Assert.assertTrue("Commit span must be child of Retry", commitChildren >= 1); - } - - @Test - public void nonRetryableExceptionProducesErrorRetrySpan() { - SessionRetryContext retryContext = SessionRetryContext.create(queryClient) - .maxRetries(5) - .backoffSlot(Duration.ofMillis(1)) - .fastBackoffSlot(Duration.ofMillis(1)) - .build(); - - RuntimeException thrown; - try { - retryContext.supplyStatus(session -> { - throw new IllegalStateException("boom"); - }).join(); - throw new AssertionError("Exception expected"); - } catch (RuntimeException ex) { - thrown = ex; - } - - Assert.assertNotNull(thrown.getCause()); - Assert.assertTrue(thrown.getCause() instanceof IllegalStateException); - assertSpanOK("ydb.CreateSession", 1); - assertSpanOK("ydb.ExecuteQuery", 0); - - List spans = exportedSpansWhenRunWithRetryPresent(); - int executeSpans = 0; - int errorExecuteSpans = 0; - int retrySpans = 0; - int errorRetrySpans = 0; - for (SpanData span : spans) { - if ("ydb.RunWithRetry".equals(span.getName())) { - executeSpans++; - if (io.opentelemetry.api.trace.StatusCode.ERROR.equals(span.getStatus().getStatusCode())) { - errorExecuteSpans++; - } - } - if (!"ydb.Try".equals(span.getName())) { - continue; - } - retrySpans++; - if (io.opentelemetry.api.trace.StatusCode.ERROR.equals(span.getStatus().getStatusCode())) { - errorRetrySpans++; - Assert.assertEquals(IllegalStateException.class.getName(), - span.getAttributes().get(ERROR_TYPE)); - } - } - Assert.assertEquals(1, executeSpans); - Assert.assertEquals(1, errorExecuteSpans); - Assert.assertEquals(1, retrySpans); - Assert.assertEquals(1, errorRetrySpans); - } - - @Test - public void retryableUnexpectedResultExceptionRetriesAndSetsErrorType() { - AtomicInteger attempt = new AtomicInteger(); - SessionRetryContext retryContext = SessionRetryContext.create(queryClient) - .maxRetries(5) - .backoffSlot(Duration.ofMillis(1)) - .fastBackoffSlot(Duration.ofMillis(1)) - .build(); - - Status status = retryContext.supplyStatus(session -> { - if (attempt.getAndIncrement() == 0) { - throw new UnexpectedResultException("retryable", Status.of(StatusCode.OVERLOADED)); - } - return session.createQuery("SELECT 1", TxMode.NONE).execute().thenApply(Result::getStatus); - }).join(); - status.expectSuccess(); - - assertSpanOK("ydb.ExecuteQuery", 1); - - List spans = exportedSpansWhenRunWithRetryPresent(); - int executeSpans = 0; - int okExecuteSpans = 0; - int retrySpans = 0; - int errorRetrySpans = 0; - int okRetrySpans = 0; - for (SpanData span : spans) { - if ("ydb.RunWithRetry".equals(span.getName())) { - executeSpans++; - if (io.opentelemetry.api.trace.StatusCode.OK.equals(span.getStatus().getStatusCode())) { - okExecuteSpans++; - } - } - if (!"ydb.Try".equals(span.getName())) { - continue; - } - retrySpans++; - if (io.opentelemetry.api.trace.StatusCode.ERROR.equals(span.getStatus().getStatusCode())) { - errorRetrySpans++; - Assert.assertEquals("ydb_error", span.getAttributes().get(ERROR_TYPE)); - Assert.assertEquals(StatusCode.OVERLOADED.toString(), span.getAttributes().get(STATUS_CODE)); - } else if (io.opentelemetry.api.trace.StatusCode.OK.equals(span.getStatus().getStatusCode())) { - okRetrySpans++; - } - } - Assert.assertEquals(1, executeSpans); - Assert.assertEquals(1, okExecuteSpans); - Assert.assertEquals(2, retrySpans); - Assert.assertEquals(1, errorRetrySpans); - Assert.assertEquals(1, okRetrySpans); - } - - @Test - public void tableProxySpansAreChildrenOfApplicationSpan() { - io.opentelemetry.api.trace.Span appSpan = appTracer.spanBuilder("app.parent.table").startSpan(); - try (Scope scope = appSpan.makeCurrent()) { - Assert.assertNotNull(scope); - try (TableClient tableClient = QueryClient.newTableClient(transport).build()) { - try (Session session = tableClient.createSession(Duration.ofSeconds(5)).join().getValue()) { - TableTransaction tx = session.createNewTransaction(TxMode.SERIALIZABLE_RW); - Result queryResult = tx.executeDataQuery("SELECT 1", Params.empty()).join(); - queryResult.getStatus().expectSuccess(); - Status commitStatus = tx.commit().join(); - commitStatus.expectSuccess(); - } - } - } finally { - appSpan.end(); - } - - List spans = exportedSpans(); - int matched = 0; - for (SpanData span : spans) { - if (!span.getName().startsWith("ydb.")) { - continue; - } - Assert.assertEquals(appSpan.getSpanContext().getTraceId(), span.getTraceId()); - Assert.assertEquals(appSpan.getSpanContext().getSpanId(), span.getParentSpanId()); - matched++; - } - Assert.assertEquals(3, matched); - } - - private void assertBaseAttributes(SpanData span) { - Assert.assertEquals(io.opentelemetry.api.trace.SpanKind.CLIENT, span.getKind()); - Assert.assertEquals("ydb", span.getAttributes().get(DB_SYSTEM_NAME)); - Assert.assertEquals(YDB.database(), span.getAttributes().get(DB_NAMESPACE)); - Assert.assertNotNull(span.getAttributes().get(SERVER_ADDRESS)); - Long port = span.getAttributes().get(SERVER_PORT); - Assert.assertNotNull(port); - Assert.assertTrue(port > 0L); - } - - private void assertSpanError(String spanName, int expectedCount, Status status) { - long deadlineMs = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(30); - int count = 0; - while (true) { - List spans = spanExporter.getFinishedSpanItems(); - count = 0; - for (SpanData span : spans) { - if (!spanName.equals(span.getName())) { - continue; - } - count++; - - Assert.assertEquals(status.getCode().toString(), span.getAttributes().get(STATUS_CODE)); - Assert.assertEquals("ydb_error", span.getAttributes().get(ERROR_TYPE)); - Assert.assertEquals(io.opentelemetry.api.trace.StatusCode.ERROR, span.getStatus().getStatusCode()); - - assertBaseAttributes(span); - } - if (count == expectedCount) { - return; - } - if (System.currentTimeMillis() >= deadlineMs) { - Assert.assertEquals("Unexpected count of span " + spanName, expectedCount, count); - return; - } - try { - Thread.sleep(5); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new AssertionError(e); - } - } - } - - private void assertSpanOK(String spanName, int expectedCount) { - long deadlineMs = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(30); - int count = 0; - while (true) { - List spans = spanExporter.getFinishedSpanItems(); - count = 0; - for (SpanData span : spans) { - if (!spanName.equals(span.getName())) { - continue; - } - count++; - Assert.assertEquals(io.opentelemetry.api.trace.StatusCode.OK, span.getStatus().getStatusCode()); - assertBaseAttributes(span); - } - if (count == expectedCount) { - return; - } - if (System.currentTimeMillis() >= deadlineMs) { - Assert.assertEquals("Unexpected count of span " + spanName, expectedCount, count); - return; - } - try { - Thread.sleep(5); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new AssertionError(e); - } - } - } -}