Skip to content

Commit a527905

Browse files
authored
test(showcase): migrate Thread.sleep calls to Awaitility (#13728)
Migrate Thread.sleep and loop constructs in java-showcase to Awaitility.
1 parent faf8530 commit a527905

6 files changed

Lines changed: 56 additions & 45 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ jobs:
5151
workflows:
5252
- '.github/workflows/**'
5353
src:
54-
- '!(google-auth-library-java|grpc-gcp-java|java-bigquery|java-bigquery-jdbc|java-bigquerystorage|java-bigtable|java-cloud-bom|java-datastore|java-firestore|java-logging|java-logging-logback|java-pubsub|java-shared-config|java-spanner|java-storage)/**/*.java'
55-
- '!(google-auth-library-java|grpc-gcp-java|java-bigquery|java-bigquery-jdbc|java-bigquerystorage|java-bigtable|java-cloud-bom|java-datastore|java-firestore|java-logging|java-logging-logback|java-pubsub|java-shared-config|java-spanner|java-storage)/**/pom.xml'
54+
- '!(google-auth-library-java|grpc-gcp-java|java-bigquery|java-bigquery-jdbc|java-bigquerystorage|java-bigtable|java-cloud-bom|java-datastore|java-firestore|java-logging|java-logging-logback|java-pubsub|java-shared-config|java-showcase|java-spanner|java-storage)/**/*.java'
55+
- '!(google-auth-library-java|grpc-gcp-java|java-bigquery|java-bigquery-jdbc|java-bigquerystorage|java-bigtable|java-cloud-bom|java-datastore|java-firestore|java-logging|java-logging-logback|java-pubsub|java-shared-config|java-showcase|java-spanner|java-storage)/**/pom.xml'
5656
- 'pom.xml'
5757
ci:
5858
- '.github/workflows/ci.yaml'

java-showcase/gapic-showcase/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@
257257
<scope>test</scope>
258258
</dependency>
259259

260+
<dependency>
261+
<groupId>org.awaitility</groupId>
262+
<artifactId>awaitility</artifactId>
263+
<scope>test</scope>
264+
</dependency>
265+
260266
</dependencies>
261267
<profiles>
262268
<profile>

java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientShutdown.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.showcase.v1beta1.EchoClient;
2525
import com.google.showcase.v1beta1.EchoRequest;
2626
import com.google.showcase.v1beta1.it.util.TestClientInitializer;
27+
import org.awaitility.Awaitility;
2728
import org.junit.jupiter.api.Test;
2829
import org.junit.jupiter.api.Timeout;
2930
import org.threeten.bp.Duration;
@@ -143,12 +144,9 @@ private void assertClientTerminated(EchoClient echoClient) throws InterruptedExc
143144
// check that everything is properly terminated after close() is called.
144145
echoClient.close();
145146

146-
// Loop until the client has terminated successfully. For tests that use this,
147-
// try to ensure there is a timeout associated, otherwise this may run forever.
148-
// Future enhancement: Use awaitility instead of busy waiting
149-
while (!echoClient.isTerminated()) {
150-
Thread.sleep(500L);
151-
}
147+
Awaitility.await()
148+
.atMost(java.time.Duration.ofMillis(DEFAULT_CLIENT_TERMINATION_MS))
149+
.until(echoClient::isTerminated);
152150
// The busy-wait time won't be accurate, so account for a bit of buffer
153151
long end = System.currentTimeMillis();
154152

java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITCompositeTracer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
import io.opentelemetry.sdk.trace.SdkTracerProvider;
5050
import io.opentelemetry.sdk.trace.data.SpanData;
5151
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
52+
import java.time.Duration;
5253
import java.util.Arrays;
5354
import java.util.Collection;
5455
import java.util.List;
56+
import org.awaitility.Awaitility;
5557
import org.junit.jupiter.api.AfterEach;
5658
import org.junit.jupiter.api.BeforeEach;
5759
import org.junit.jupiter.api.Test;
@@ -124,13 +126,11 @@ void testCompositeTracer() throws Exception {
124126
.get(AttributeKey.stringKey(ObservabilityAttributes.SERVER_ADDRESS_ATTRIBUTE)))
125127
.isEqualTo(SHOWCASE_SERVER_ADDRESS);
126128

127-
Thread.sleep(100);
128129
// Verify metric name and one basic attribute server.address
130+
Awaitility.await()
131+
.atMost(Duration.ofSeconds(10))
132+
.until(() -> !metricReader.collectAllMetrics().isEmpty());
129133
Collection<MetricData> actualMetrics = metricReader.collectAllMetrics();
130-
for (int i = 0; i < 10 && actualMetrics.isEmpty(); i++) {
131-
Thread.sleep(1000L);
132-
actualMetrics = metricReader.collectAllMetrics();
133-
}
134134

135135
assertThat(actualMetrics).isNotEmpty();
136136
MetricData metricData =

java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelGoldenMetrics.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import java.io.InputStream;
6464
import java.time.Duration;
6565
import java.util.Collection;
66+
import org.awaitility.Awaitility;
6667
import org.junit.jupiter.api.AfterEach;
6768
import org.junit.jupiter.api.BeforeEach;
6869
import org.junit.jupiter.api.Test;
@@ -106,8 +107,7 @@ void testMetrics_successfulEcho_grpc() throws Exception {
106107
// This is implemented by adding a TraceFinisher to ApiFuture as a callback in
107108
// TracedUnaryCallable,
108109
// which could be executed in a different thread.
109-
Thread.sleep(100);
110-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
110+
Collection<MetricData> metrics = waitAndCollectMetrics();
111111
assertThat(metrics).isNotEmpty();
112112

113113
MetricData durationMetric =
@@ -192,8 +192,7 @@ public void sendMessage(ReqT message) {}
192192
UnavailableException.class,
193193
() -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build()));
194194

195-
Thread.sleep(100);
196-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
195+
Collection<MetricData> metrics = waitAndCollectMetrics();
197196
assertThat(metrics).isNotEmpty();
198197

199198
MetricData durationMetric =
@@ -224,8 +223,7 @@ void testMetrics_successfulEcho_httpjson() throws Exception {
224223

225224
client.echo(EchoRequest.newBuilder().setContent("metrics-test").build());
226225

227-
Thread.sleep(100);
228-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
226+
Collection<MetricData> metrics = waitAndCollectMetrics();
229227
assertThat(metrics).isNotEmpty();
230228

231229
MetricData durationMetric =
@@ -366,8 +364,7 @@ public String getHeaderValue(int index) {
366364
UnavailableException.class,
367365
() -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build()));
368366

369-
Thread.sleep(100);
370-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
367+
Collection<MetricData> metrics = waitAndCollectMetrics();
371368
assertThat(metrics).isNotEmpty();
372369

373370
MetricData durationMetric =
@@ -415,8 +412,7 @@ void testMetrics_clientTimeout_grpc() throws Exception {
415412
Exception.class,
416413
() -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build()));
417414

418-
Thread.sleep(100);
419-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
415+
Collection<MetricData> metrics = waitAndCollectMetrics();
420416
assertThat(metrics).isNotEmpty();
421417

422418
MetricData durationMetric =
@@ -458,8 +454,7 @@ void testMetrics_clientTimeout_httpjson() throws Exception {
458454
Exception.class,
459455
() -> client.echo(EchoRequest.newBuilder().setContent("metrics-test").build()));
460456

461-
Thread.sleep(100);
462-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
457+
Collection<MetricData> metrics = waitAndCollectMetrics();
463458
assertThat(metrics).isNotEmpty();
464459

465460
MetricData durationMetric =
@@ -538,8 +533,7 @@ public void sendMessage(ReqT message) {}
538533

539534
assertThat(attemptCount.get()).isEqualTo(3);
540535

541-
Thread.sleep(100);
542-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
536+
Collection<MetricData> metrics = waitAndCollectMetrics();
543537
assertThat(metrics).hasSize(1);
544538

545539
MetricData durationMetric =
@@ -709,8 +703,7 @@ public String getHeaderValue(int index) {
709703

710704
assertThat(requestCount.get()).isEqualTo(3);
711705

712-
Thread.sleep(100);
713-
Collection<MetricData> metrics = metricReader.collectAllMetrics();
706+
Collection<MetricData> metrics = waitAndCollectMetrics();
714707
assertThat(metrics).hasSize(1);
715708

716709
MetricData durationMetric =
@@ -730,4 +723,11 @@ public String getHeaderValue(int index) {
730723
.isEqualTo("OK");
731724
}
732725
}
726+
727+
private Collection<MetricData> waitAndCollectMetrics() {
728+
Awaitility.await()
729+
.atMost(Duration.ofSeconds(5))
730+
.until(() -> !metricReader.collectAllMetrics().isEmpty());
731+
return metricReader.collectAllMetrics();
732+
}
733733
}

java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelMetrics.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383
import java.util.concurrent.TimeUnit;
8484
import java.util.function.Predicate;
8585
import java.util.stream.Collectors;
86+
import org.awaitility.Awaitility;
87+
import org.awaitility.core.ConditionTimeoutException;
8688
import org.junit.jupiter.api.AfterEach;
8789
import org.junit.jupiter.api.Assertions;
8890
import org.junit.jupiter.api.BeforeEach;
@@ -290,24 +292,29 @@ private List<MetricData> getMetricDataList() throws InterruptedException {
290292
}
291293

292294
/**
293-
* Attempts to retrieve the metrics from a custom InMemoryMetricsReader. Sleep every second for at
294-
* most 10s to try and retrieve all the metrics available. If it is unable to retrieve all the
295-
* metrics, fail the test.
295+
* Attempts to retrieve the metrics from a custom InMemoryMetricsReader. Polls for at most 10s to
296+
* try and retrieve all the metrics available. If it is unable to retrieve all the metrics, fail
297+
* the test.
296298
*/
297299
private List<MetricData> getMetricDataList(InMemoryMetricReader metricReader)
298300
throws InterruptedException {
299-
for (int i = 0; i < NUM_DEFAULT_FLUSH_ATTEMPTS; i++) {
300-
Thread.sleep(1000L);
301-
List<MetricData> metricData = new ArrayList<>(metricReader.collectAllMetrics());
302-
// Depending on the OpenTelemetry instance (i.e. OpenTelemetry, GrpcOpenTelemetry, etc.)
303-
// there may be additional metrics recorded. Only check to ensure the Gax Metrics
304-
// are recorded properly. Any additional metrics are fine to be passed.
305-
if (metricData.size() >= NUM_GAX_OTEL_METRICS && areAllGaxMetricsRecorded(metricData)) {
306-
return metricData;
307-
}
301+
try {
302+
Awaitility.await()
303+
.atMost(java.time.Duration.ofSeconds(NUM_DEFAULT_FLUSH_ATTEMPTS))
304+
.until(
305+
() -> {
306+
List<MetricData> metricData = new ArrayList<>(metricReader.collectAllMetrics());
307+
// Depending on the OpenTelemetry instance (i.e. OpenTelemetry, GrpcOpenTelemetry,
308+
// etc.)
309+
// there may be additional metrics recorded. Only check to ensure the Gax Metrics
310+
// are recorded properly. Any additional metrics are fine to be passed.
311+
return metricData.size() >= NUM_GAX_OTEL_METRICS
312+
&& areAllGaxMetricsRecorded(metricData);
313+
});
314+
} catch (ConditionTimeoutException e) {
315+
Assertions.fail("Unable to collect all the GAX metrics required for the test");
308316
}
309-
Assertions.fail("Unable to collect all the GAX metrics required for the test");
310-
return new ArrayList<>();
317+
return new ArrayList<>(metricReader.collectAllMetrics());
311318
}
312319

313320
private boolean areAllGaxMetricsRecorded(List<MetricData> metricData) {
@@ -370,7 +377,7 @@ void testGrpc_operationCancelled_recordsMetrics() throws Exception {
370377
UnaryCallable<BlockRequest, BlockResponse> blockCallable = grpcClient.blockCallable();
371378
ApiFuture<BlockResponse> blockResponseApiFuture = blockCallable.futureCall(blockRequest);
372379
// Sleep 1s before cancelling to let the request go through
373-
Thread.sleep(1000);
380+
Awaitility.await().pollDelay(java.time.Duration.ofSeconds(1)).until(() -> true);
374381
blockResponseApiFuture.cancel(true);
375382

376383
List<MetricData> actualMetricDataList = getMetricDataList();
@@ -397,7 +404,7 @@ void testHttpJson_operationCancelled_recordsMetrics() throws Exception {
397404
UnaryCallable<BlockRequest, BlockResponse> blockCallable = httpClient.blockCallable();
398405
ApiFuture<BlockResponse> blockResponseApiFuture = blockCallable.futureCall(blockRequest);
399406
// Sleep 1s before cancelling to let the request go through
400-
Thread.sleep(1000);
407+
Awaitility.await().pollDelay(java.time.Duration.ofSeconds(1)).until(() -> true);
401408
blockResponseApiFuture.cancel(true);
402409

403410
List<MetricData> actualMetricDataList = getMetricDataList();

0 commit comments

Comments
 (0)