Skip to content

Commit beee46f

Browse files
authored
test(gax): use FakeApiClock in DirectRetryingExecutorTest to avoid Thread.sleep (#14705)
Use FakeApiClock and RecordingScheduler in ScheduledRetryingExecutorTest so non-concurrent retry tests execute deterministically without sleeping. Isolate asynchronous polling and cancellation tests to use per-iteration local ScheduledExecutorService instances and NanoClock. Make RecordingScheduler stubbings lenient to avoid UnnecessaryStubbingException when recorded metrics are not queried. Fixes [#13535](#14625)
1 parent bc0126a commit beee46f

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

‎sdk-platform-java/gax-java/gax/src/test/java/com/google/api/gax/retrying/AbstractRetryingExecutorTest.java‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import static org.mockito.Mockito.verify;
4646
import static org.mockito.Mockito.verifyNoMoreInteractions;
4747

48+
import com.google.api.core.ApiClock;
4849
import com.google.api.core.ApiFuture;
4950
import com.google.api.core.NanoClock;
5051
import com.google.api.gax.retrying.FailingCallable.CustomException;
@@ -102,6 +103,10 @@ protected abstract RetryingExecutorWithContext<String> getExecutor(
102103
protected abstract RetryAlgorithm<String> getAlgorithm(
103104
RetrySettings retrySettings, int apocalypseCountDown, RuntimeException apocalypseException);
104105

106+
protected ApiClock getClock() {
107+
return NanoClock.getDefaultClock();
108+
}
109+
105110
protected <T> void busyWaitForInitialResult(RetryingFuture<T> future, java.time.Duration timeout)
106111
throws TimeoutException {
107112
Stopwatch watch = Stopwatch.createStarted();
@@ -356,7 +361,7 @@ void testPollExceptionByPollAlgorithm(boolean withCustomRetrySettings) throws Ex
356361
useContextRetrySettings
357362
? withCustomRetrySettings ? FAILING_RETRY_SETTINGS : FAST_RETRY_SETTINGS
358363
: retrySettings,
359-
NanoClock.getDefaultClock()));
364+
getClock()));
360365

361366
RetryingExecutorWithContext<String> executor = getExecutor(retryAlgorithm);
362367
FailingCallable callable = new FailingCallable(6, "request", "FAILURE", tracer);

‎sdk-platform-java/gax-java/gax/src/test/java/com/google/api/gax/retrying/DirectRetryingExecutorTest.java‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,41 @@
2929
*/
3030
package com.google.api.gax.retrying;
3131

32-
import com.google.api.core.CurrentMillisClock;
32+
import com.google.api.core.ApiClock;
33+
import com.google.api.gax.core.FakeApiClock;
34+
import java.time.Duration;
3335

3436
class DirectRetryingExecutorTest extends AbstractRetryingExecutorTest {
3537

38+
// ExponentialRetryAlgorithm and ExponentialPollAlgorithm only compute relative elapsed time
39+
// deltas against firstAttemptStartTimeNanos (clock.nanoTime() - firstAttemptStartTimeNanos)
40+
// and never treat 0L as a special sentinel value.
41+
private final FakeApiClock clock = new FakeApiClock(0L);
42+
43+
@Override
44+
protected ApiClock getClock() {
45+
return clock;
46+
}
47+
3648
@Override
3749
protected RetryingExecutorWithContext<String> getExecutor(RetryAlgorithm<String> retryAlgorithm) {
38-
return new DirectRetryingExecutor<>(retryAlgorithm);
50+
return new DirectRetryingExecutor<String>(retryAlgorithm) {
51+
// Advance the fake clock instead of sleeping the current thread so that retry delays
52+
// are simulated deterministically without wall-clock pauses on slow CI VMs.
53+
@Override
54+
protected void sleep(Duration delay) {
55+
if (!delay.isZero() && !delay.isNegative()) {
56+
clock.incrementNanoTime(delay.toNanos());
57+
}
58+
}
59+
};
3960
}
4061

4162
@Override
4263
protected RetryAlgorithm<String> getAlgorithm(
4364
RetrySettings retrySettings, int apocalypseCountDown, RuntimeException apocalypseException) {
4465
return new RetryAlgorithm<>(
4566
new TestResultRetryAlgorithm<String>(apocalypseCountDown, apocalypseException),
46-
new ExponentialRetryAlgorithm(retrySettings, CurrentMillisClock.getDefaultClock()));
67+
new ExponentialRetryAlgorithm(retrySettings, clock));
4768
}
4869
}

0 commit comments

Comments
 (0)