From b972782b34a2b05100db1114f98f71eb4ec5a472 Mon Sep 17 00:00:00 2001 From: blakeli Date: Thu, 18 Jun 2026 14:52:43 -0400 Subject: [PATCH] refactor(showcase): migrate Thread.sleep to Awaitility in integration tests --- java-showcase/gapic-showcase/pom.xml | 6 +++ .../showcase/v1beta1/it/ITClientShutdown.java | 11 +++-- .../v1beta1/it/ITCompositeTracer.java | 11 ++--- .../v1beta1/it/ITOtelGoldenMetrics.java | 41 +++++++++++++++---- .../showcase/v1beta1/it/ITOtelMetrics.java | 30 ++++++++------ 5 files changed, 67 insertions(+), 32 deletions(-) diff --git a/java-showcase/gapic-showcase/pom.xml b/java-showcase/gapic-showcase/pom.xml index d4cfcfa4de22..289e41615788 100644 --- a/java-showcase/gapic-showcase/pom.xml +++ b/java-showcase/gapic-showcase/pom.xml @@ -256,6 +256,12 @@ ${slf4j2-logback.version} test + + org.awaitility + awaitility + 4.3.0 + test + diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientShutdown.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientShutdown.java index e55ee8d1ed5a..00d8e7218b57 100644 --- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientShutdown.java +++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientShutdown.java @@ -24,6 +24,7 @@ import com.google.showcase.v1beta1.EchoClient; import com.google.showcase.v1beta1.EchoRequest; import com.google.showcase.v1beta1.it.util.TestClientInitializer; +import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.threeten.bp.Duration; @@ -143,12 +144,10 @@ private void assertClientTerminated(EchoClient echoClient) throws InterruptedExc // check that everything is properly terminated after close() is called. echoClient.close(); - // Loop until the client has terminated successfully. For tests that use this, - // try to ensure there is a timeout associated, otherwise this may run forever. - // Future enhancement: Use awaitility instead of busy waiting - while (!echoClient.isTerminated()) { - Thread.sleep(500L); - } + Awaitility.await() + .atMost(java.time.Duration.ofMillis(DEFAULT_CLIENT_TERMINATION_MS)) + .pollInterval(java.time.Duration.ofMillis(500)) + .until(echoClient::isTerminated); // The busy-wait time won't be accurate, so account for a bit of buffer long end = System.currentTimeMillis(); diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITCompositeTracer.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITCompositeTracer.java index b1a66f206c6b..5111366c8330 100644 --- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITCompositeTracer.java +++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITCompositeTracer.java @@ -49,9 +49,11 @@ import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import java.time.Duration; import java.util.Arrays; import java.util.Collection; import java.util.List; +import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -124,13 +126,12 @@ void testCompositeTracer() throws Exception { .get(AttributeKey.stringKey(ObservabilityAttributes.SERVER_ADDRESS_ATTRIBUTE))) .isEqualTo(SHOWCASE_SERVER_ADDRESS); - Thread.sleep(100); // Verify metric name and one basic attribute server.address + Awaitility.await() + .atMost(Duration.ofSeconds(10)) + .pollInterval(Duration.ofMillis(100)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection actualMetrics = metricReader.collectAllMetrics(); - for (int i = 0; i < 10 && actualMetrics.isEmpty(); i++) { - Thread.sleep(1000L); - actualMetrics = metricReader.collectAllMetrics(); - } assertThat(actualMetrics).isNotEmpty(); MetricData metricData = diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelGoldenMetrics.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelGoldenMetrics.java index 5385ecc67774..609b2399802d 100644 --- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelGoldenMetrics.java +++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelGoldenMetrics.java @@ -63,6 +63,7 @@ import java.io.InputStream; import java.time.Duration; import java.util.Collection; +import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -106,7 +107,10 @@ void testMetrics_successfulEcho_grpc() throws Exception { // This is implemented by adding a TraceFinisher to ApiFuture as a callback in // TracedUnaryCallable, // which could be executed in a different thread. - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).isNotEmpty(); @@ -192,7 +196,10 @@ public void sendMessage(ReqT message) {} UnavailableException.class, () -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build())); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).isNotEmpty(); @@ -224,7 +231,10 @@ void testMetrics_successfulEcho_httpjson() throws Exception { client.echo(EchoRequest.newBuilder().setContent("metrics-test").build()); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).isNotEmpty(); @@ -366,7 +376,10 @@ public String getHeaderValue(int index) { UnavailableException.class, () -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build())); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).isNotEmpty(); @@ -415,7 +428,10 @@ void testMetrics_clientTimeout_grpc() throws Exception { Exception.class, () -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build())); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).isNotEmpty(); @@ -458,7 +474,10 @@ void testMetrics_clientTimeout_httpjson() throws Exception { Exception.class, () -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build())); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).isNotEmpty(); @@ -538,7 +557,10 @@ public void sendMessage(ReqT message) {} assertThat(attemptCount.get()).isEqualTo(3); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).hasSize(1); @@ -709,7 +731,10 @@ public String getHeaderValue(int index) { assertThat(requestCount.get()).isEqualTo(3); - Thread.sleep(100); + Awaitility.await() + .atMost(Duration.ofSeconds(5)) + .pollInterval(Duration.ofMillis(10)) + .until(() -> !metricReader.collectAllMetrics().isEmpty()); Collection metrics = metricReader.collectAllMetrics(); assertThat(metrics).hasSize(1); diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelMetrics.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelMetrics.java index ad973e4137b2..5833a61cbea0 100644 --- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelMetrics.java +++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelMetrics.java @@ -83,6 +83,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.stream.Collectors; +import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -296,18 +297,21 @@ private List getMetricDataList() throws InterruptedException { */ private List getMetricDataList(InMemoryMetricReader metricReader) throws InterruptedException { - for (int i = 0; i < NUM_DEFAULT_FLUSH_ATTEMPTS; i++) { - Thread.sleep(1000L); - List metricData = new ArrayList<>(metricReader.collectAllMetrics()); - // Depending on the OpenTelemetry instance (i.e. OpenTelemetry, GrpcOpenTelemetry, etc.) - // there may be additional metrics recorded. Only check to ensure the Gax Metrics - // are recorded properly. Any additional metrics are fine to be passed. - if (metricData.size() >= NUM_GAX_OTEL_METRICS && areAllGaxMetricsRecorded(metricData)) { - return metricData; - } + try { + Awaitility.await() + .atMost(java.time.Duration.ofSeconds(NUM_DEFAULT_FLUSH_ATTEMPTS)) + .pollInterval(java.time.Duration.ofSeconds(1)) + .until( + () -> { + List metricData = new ArrayList<>(metricReader.collectAllMetrics()); + return metricData.size() >= NUM_GAX_OTEL_METRICS + && areAllGaxMetricsRecorded(metricData); + }); + return new ArrayList<>(metricReader.collectAllMetrics()); + } catch (org.awaitility.core.ConditionTimeoutException e) { + Assertions.fail("Unable to collect all the GAX metrics required for the test", e); + return new ArrayList<>(); } - Assertions.fail("Unable to collect all the GAX metrics required for the test"); - return new ArrayList<>(); } private boolean areAllGaxMetricsRecorded(List metricData) { @@ -370,7 +374,7 @@ void testGrpc_operationCancelled_recordsMetrics() throws Exception { UnaryCallable blockCallable = grpcClient.blockCallable(); ApiFuture blockResponseApiFuture = blockCallable.futureCall(blockRequest); // Sleep 1s before cancelling to let the request go through - Thread.sleep(1000); + Awaitility.await().pollDelay(java.time.Duration.ofSeconds(1)).until(() -> true); blockResponseApiFuture.cancel(true); List actualMetricDataList = getMetricDataList(); @@ -397,7 +401,7 @@ void testHttpJson_operationCancelled_recordsMetrics() throws Exception { UnaryCallable blockCallable = httpClient.blockCallable(); ApiFuture blockResponseApiFuture = blockCallable.futureCall(blockRequest); // Sleep 1s before cancelling to let the request go through - Thread.sleep(1000); + Awaitility.await().pollDelay(java.time.Duration.ofSeconds(1)).until(() -> true); blockResponseApiFuture.cancel(true); List actualMetricDataList = getMetricDataList();