Skip to content

JAVA-6055 Implement prose backpressure retryable writes tests#1929

Open
stIncMale wants to merge 2 commits intomongodb:backpressurefrom
stIncMale:backpressure_JAVA-6055_proseTests
Open

JAVA-6055 Implement prose backpressure retryable writes tests#1929
stIncMale wants to merge 2 commits intomongodb:backpressurefrom
stIncMale:backpressure_JAVA-6055_proseTests

Conversation

@stIncMale
Copy link
Copy Markdown
Member

@stIncMale stIncMale commented Mar 27, 2026

The relevant spec changes:

I recommend reviewing the first two commits one by one to simplify reviewing: the first commit does the refactoring, including the necessary refactoring (the introduction of ConfigureFailPointCommandListener), the second commit adds the new tests.

I used the TODO-BACKPRESSURE Valentin comments as described in #1918.

JAVA-6055

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds/updates prose tests to cover the retryable writes “backpressure retryable writes” scenarios from the spec updates, including refactoring test infrastructure to configure fail points in reaction to command events.

Changes:

  • Introduce ConfigureFailPointCommandListener to enable a failpoint once upon matching a CommandEvent, and automatically disable it via try-with-resources.
  • Refactor existing retryable reads/writes prose tests to use the new helper and updated spec link references.
  • Add new “error propagation after encountering multiple errors” retryable writes prose test cases (with Case 1 temporarily disabled behind TODO-BACKPRESSURE).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
driver-sync/src/test/functional/com/mongodb/internal/event/ConfigureFailPointCommandListener.java New test utility to configure/cleanup failpoints triggered by command events.
driver-sync/src/test/functional/com/mongodb/client/RetryableWritesProseTest.java Refactor existing prose tests; add new multi-error propagation cases.
driver-sync/src/test/functional/com/mongodb/client/RetryableReadsProseTest.java Update prose-test references and align helper usage/signatures.
driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/RetryableWritesProseTest.java Mirror sync prose test updates via sync-adapter delegation; add new cases.
driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/RetryableReadsProseTest.java Update prose-test references and align helper usage/signatures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stIncMale stIncMale force-pushed the backpressure_JAVA-6055_proseTests branch 3 times, most recently from 53e526f to 44c8119 Compare March 27, 2026 18:31
@vbabanin vbabanin requested a review from Copilot March 27, 2026 18:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stIncMale stIncMale force-pushed the backpressure_JAVA-6055_proseTests branch from 44c8119 to 973ee55 Compare March 27, 2026 18:45
@vbabanin vbabanin requested a review from Copilot March 27, 2026 18:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stIncMale stIncMale force-pushed the backpressure_JAVA-6055_proseTests branch from 973ee55 to 758b89e Compare March 27, 2026 21:02
@vbabanin vbabanin requested a review from Copilot March 27, 2026 21:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stIncMale stIncMale force-pushed the backpressure_JAVA-6055_proseTests branch from 758b89e to d270460 Compare March 27, 2026 21:36
@vbabanin vbabanin requested a review from Copilot March 27, 2026 21:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stIncMale stIncMale force-pushed the backpressure_JAVA-6055_proseTests branch from d270460 to 72d70e4 Compare March 27, 2026 22:14
@stIncMale stIncMale marked this pull request as ready for review March 27, 2026 22:15
@stIncMale stIncMale requested a review from a team as a code owner March 27, 2026 22:15
@stIncMale stIncMale changed the title Implement prose backpressure retryable writes tests JAVA-6055 Implement prose backpressure retryable writes tests Mar 28, 2026
@stIncMale stIncMale changed the title JAVA-6055 Implement prose backpressure retryable writes tests JAVA-6055: Implement prose backpressure retryable writes tests Mar 28, 2026
@stIncMale stIncMale changed the title JAVA-6055: Implement prose backpressure retryable writes tests JAVA-6055 Implement prose backpressure retryable writes tests Mar 28, 2026
Copy link
Copy Markdown
Collaborator

@nhachicha nhachicha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea extracting ConfigureFailPointCommandListener as a reusable utility 👍
some minor comments from me & Claude review

fail("The listener was closed before (in the happens-before order) it attempted to configure the fail point");
} else {
assertTrue(failPointFuture.isDone());
assertNotNull(failPointFuture.get()).close();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]
If failPointFuture is completed exceptionally (via completeExceptionally), then failPointFuture.get() in close() will throw, so the normal FailPoint.close() is skipped and the fail point may remain enabled.

This is, however, low-risk since there may be nothing to clean up if FailPoint.enable() fails ...

@Override
public void close() throws InterruptedException, ExecutionException {
synchronized (lock) {
if (failPointFuture.cancel(true)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[TIL]
mayInterruptIfRunning is no-op

mayInterruptIfRunning - this value has no effect in this implementation because interrupts are not used to control processing.

+ " data: {\n"
+ " failCommands: [\"" + operationName + "\"],\n"
+ " failCommands: [\"" + expectedCommandName + "\"],\n"
+ " errorCode: 6,\n"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[claude-review]
Trailing comma in generated JSON when write=false.

The old code avoided this by placing errorCode last

The same pattern appears in retriesOnSameMongosWhenAnotherNotAvailable

Predicate<CommandEvent> configureFailPointEventMatcher = event -> {
if (event instanceof CommandFailedEvent) {
CommandFailedEvent commandFailedEvent = (CommandFailedEvent) event;
MongoException cause = assertInstanceOf(MongoException.class, commandFailedEvent.getThrowable());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[claude-review]
The predicates use assertInstanceOf(MongoException.class, ...) which throws AssertionFailedError if the type doesn't match. A Predicate.test() should return false, not throw. The exception is caught by onEvent() and routed to completeExceptionally, so it works, but the semantics are surprising. Consider using a plain instanceof check instead.

Predicate<CommandEvent> configureFailPointEventMatcher = event -> {
if (event instanceof CommandFailedEvent) {
CommandFailedEvent commandFailedEvent = (CommandFailedEvent) event;
MongoException cause = assertInstanceOf(MongoException.class, commandFailedEvent.getThrowable());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import static com.mongodb.assertions.Assertions.assertTrue;
import static com.mongodb.assertions.Assertions.fail;

public final class ConfigureFailPointCommandListener implements CommandListener, AutoCloseable {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth annotating with @ThreadSafe ?

+ " failCommands: ['" + commandName + "'],\n"
+ " errorCode: 91,\n"
+ " blockConnection: true,\n"
+ " blockTimeMS: 1000,\n"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing comma issue when write == false. I wonder if we should keep the append approach of building the BsonDocument

similar to https://github.com/mongodb/mongo-java-driver/pull/1929/changes#r3005045523

+ " data: {\n"
+ " failCommands: [\"" + operationName + "\"],\n"
+ " failCommands: [\"" + expectedCommandName + "\"],\n"
+ " errorCode: 6,\n"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+ "', '" + NO_WRITES_PERFORMED_ERROR_LABEL + "']\n"
+ " }\n"
+ "}\n");
Predicate<CommandEvent> configureFailPointEventMatcher = event -> event instanceof CommandFailedEvent;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]
Both the initial and the listener fail points use error code 91, for consistency and defensiveness, checking code == 91 wouldn't hurt — if something unexpected fails first (e.g., a different command), the test would configure the second fail point at the wrong time and produce a confusing failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants