Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ public void testIsPlanRefreshError() {
}

@Test
public void planRefreshDelayIsFactoredIntoExecuteTimeout() throws InterruptedException {
public void planRefreshDelayIsFactoredIntoExecuteTimeout()
throws InterruptedException, ExecutionException {
MockServerStreamingCallable<ExecuteQueryRequest, ExecuteQueryResponse> innerCallable =
new MockServerStreamingCallable<>();
RequestContext requestContext = RequestContext.create("project", "instance", "profile");
Expand All @@ -258,30 +259,39 @@ public void planRefreshDelayIsFactoredIntoExecuteTimeout() throws InterruptedExc
ExecuteQueryCallContext callContext =
ExecuteQueryCallContext.create(preparedStatement.bind().build(), metadataFuture);

Duration originalAttemptTimeout = Duration.ofMillis(100);
// Simulate delay for prepare response
int prepareDelayMs = 50;
SettableApiFuture<Instant> prepareResolvedAt = SettableApiFuture.create();
scheduler.schedule(
() -> {
prepareResolvedAt.set(Instant.now());
prepareFuture.set(
PrepareResponse.fromProto(
prepareResponse(
ByteString.copyFromUtf8("initialPlan"),
metadata(columnMetadata("strCol", stringType())))));
},
50,
prepareDelayMs,
TimeUnit.MILLISECONDS);

Duration originalAttemptTimeout = Duration.ofMillis(5000);
ApiCallContext context =
GrpcCallContext.createDefault().withTimeoutDuration(originalAttemptTimeout);
// prepare takes 50 ms to resolve. Despite that the execute timeout should be around 100ms from
// now (w padding)
Deadline paddedDeadlineAtStartOfCall =
Deadline.after(originalAttemptTimeout.toMillis() + 5, TimeUnit.MILLISECONDS);
callable.call(callContext, outerObserver, context);
Instant startOfCall = Instant.now();
scheduler.shutdown();
scheduler.awaitTermination(30, TimeUnit.SECONDS);
GrpcCallContext grpcCallContext =
(GrpcCallContext) innerCallable.popLastCall().getApiCallContext();

// Deadline should be at most (original deadline - prepare delay). Add 1ms to avoid flakiness.
Duration prepareLatency = Duration.between(startOfCall, prepareResolvedAt.get());
Deadline deadlineUpperBound =
Deadline.after(
originalAttemptTimeout.toMillis() - prepareLatency.toMillis() + 1,
TimeUnit.MILLISECONDS);
Deadline executeDeadline = grpcCallContext.getCallOptions().getDeadline();
assertThat(executeDeadline.isBefore(paddedDeadlineAtStartOfCall)).isTrue();
assertThat(executeDeadline.isBefore(deadlineUpperBound)).isTrue();
}

@Test
Expand Down
Loading