Skip to content

GridFS download test reenablement#1991

Open
rozza wants to merge 3 commits into
mongodb:mainfrom
rozza:JAVA-5839
Open

GridFS download test reenablement#1991
rozza wants to merge 3 commits into
mongodb:mainfrom
rozza:JAVA-5839

Conversation

@rozza
Copy link
Copy Markdown
Member

@rozza rozza commented Jun 2, 2026

This PR comes in 3 parts:

  • Removing the skip test
  • Clarifying the naming in UnitedTestModifications
  • Adding transform mechanism for Specification tests

JAVA-5839

vbabanin and others added 2 commits June 2, 2026 10:27
- Remove JAVA-5839 skip entry for "timeoutMS applied to entire download, not individual parts" test so it runs in CI

JAVA-5839
Rename dir/file/test to directory/fileDescription/testDescription
to clarify that 'file' refers to the spec file's description field,
not the filename, and 'test' refers to the individual test description.

JAVA-5839
@rozza rozza requested a review from Copilot June 2, 2026 11:18
@rozza rozza marked this pull request as ready for review June 2, 2026 11:18
@rozza rozza requested a review from a team as a code owner June 2, 2026 11:18
@rozza rozza requested a review from nhachicha June 2, 2026 11:18
@rozza rozza marked this pull request as draft June 2, 2026 11:19
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

Re-enables the unified spec test covering CSOT behavior for GridFS downloads (JAVA-5839) by replacing a hard skip with a targeted test-data transformation, and clarifies naming in the unified test modification helpers.

Changes:

  • Removed the JAVA-5839 skip for the GridFS download CSOT spec test and replaced it with a transformation that relaxes timeouts to reduce CI flakiness.
  • Renamed dir/file/test identifiers in UnifiedTestModifications to directory/fileDescription/testDescription for clarity and consistency with spec terminology.
  • Added a transformation mechanism (TestTransformer) and integrated it into the unified test runner setup.

Reviewed changes

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

File Description
driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java Adds test-data transformation support, renames identifiers for clarity, and applies a transformation for the GridFS CSOT test.
driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java Applies registered transformations during test setup before entity initialization.

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

Comment thread driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java Outdated
…ation

Add TestTransformer functional interface and transform() method to TestDef,
allowing spec test data (entities and definition) to be mutated before
execution. Transformations are logged with a mandatory reason string.

Apply transform for JAVA-5839: bump timeoutMS from 75 to 250 and
blockTimeMS from 50 to 200 for the GridFS download timeout test to
avoid CI latency failures. The 150ms margin (6x the original 25ms)
should be reliable across CI environments.

JAVA-5839
@rozza rozza marked this pull request as ready for review June 2, 2026 12:47
@nhachicha nhachicha requested a review from Copilot June 4, 2026 12:42
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 2 out of 2 changed files in this pull request and generated no new comments.

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.

Isn't introducing a TestTransformer risk deviating from the spec tests? in this case if the timeout is too short shouldn't we modify the upstream spec test instead?

AI review (Opus 4.8 1M)

🟡 [important] L271-273: definition is mutated in place while entitiesArray is defensively cloned.
The guard clones entitiesArray before transforming it, but passes the raw definition to applyTransformations, which mutates definition.getArray("operations")...blockTimeMS in place. definition is
later re-read at execution time in shouldPassAllOutcomes() — so the in-place mutation is required there — but the same definition object is reused across retry attempts. This is safe today only because
findAndSetInt is idempotent (it sets a fixed value). It becomes a latent corruption bug the moment any future transformer increments or otherwise depends on the prior value. Either clone definition too
and read the clone downstream, or add a comment documenting that transformers must be idempotent because definition is intentionally shared.

driver-sync/.../unified/UnifiedTestModifications.java

  • 🟡 [important] findAndSetInt: Silent no-op when the path matches nothing.
    If zero elements match (a typo in the path, or a future spec YAML renaming/retyping the field), the method completes silently with no substitution and no log line — the LOGGER.info only fires on a
    successful replacement. Since the whole point is to suppress CI flakiness, a silent miss would quietly reintroduce the original flaky failures with no diagnostic signal. Track a substitution count and log a
    warning (or fail) when it stays zero.

  • 🟢 [nit] isInt32() guard: A value parsed as BsonInt64/BsonDouble is silently skipped. Current spec values are int32, so this works, but a one-line comment on why only int32 is accepted (or relaxing
    to isNumber() + asNumber().intValue()) would prevent a future silent miss.

  • 🟢 [nit] findAndSetInt searches only top-level array elements, not recursively. Correct for the flat operations list today, but the generic name/signature implies otherwise. Consider noting in the
    Javadoc that it does not recurse into nested operations (e.g. loop operations).

  • 💡 [suggestion] onMatch (transformer path): When a transformer matches, onMatch also runs this.testDef.matchesThrowable = this.matchesThrowable, which is null for the transformer constructor. If
    a test ever registers both a transform(...) and a retry(...)/when... with a matchesThrowable, registration order could null it out. Not triggered by current usage, but worth guarding (assign only when
    non-null) if transforms and retries are later combined on one test.
    </details?

* @param path dot-separated path to an int field
* @param newValue the replacement value
*/
static void findAndSetInt(final BsonArray array, final String path, final int newValue) {
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.

is there a value in asserting the expected original value? this will make sure if the upstream test changes to a more favourable value maybe the transformation is no longer needed ?

* @param path dot-separated path to an int field
* @param newValue the replacement value
*/
static void findAndSetInt(final BsonArray array, final String path, final int newValue) {
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.

can we generalise this method for all numbers? and use isNumber below?

}
}
String leafKey = segments[segments.length - 1];
if (found && current.containsKey(leafKey) && current.get(leafKey).isInt32()) {
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.

The transformation is skipped if the value is BsonInt64 ? (maybe related to https://github.com/mongodb/mongo-java-driver/pull/1991/changes#r3356666027)

* @param path dot-separated path to an int field
* @param newValue the replacement value
*/
static void findAndSetInt(final BsonArray array, final String path, final int newValue) {
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.

Can we refactor this to include the reason ? this will make the log statement below (LOGGER.info) more highly informative

Ex:

 String reason = "JAVA-5839: Bump blocking/timeout to avoid CI latency failures";
def.transform(reason,
         (entitiesArray, definition) -> {
             findAndSetInt(reason, entitiesArray, "client.uriOptions.timeoutMS", 250);
             findAndSetInt(reason, definition.getArray("operations"), "arguments.failPoint.data.blockTimeMS", 200);
         })

Or infer it from TestApplicator

// TestDef ...
public void applyTransformations(final BsonArray entitiesArray, final BsonDocument definition) {
         for (Transformation t : transformations) {
             t.transformer.transform(t.reason, entitiesArray, definition);
         }
     }

//  lambda

def.transform("JAVA-5839: Bump blocking/timeout to avoid CI latency failures",
         (reason, entitiesArray, definition) -> {
             findAndSetInt(reason, entitiesArray, "client.uriOptions.timeoutMS", 250);
             findAndSetInt(reason, definition.getArray("operations"), "arguments.failPoint.data.blockTimeMS", 200);
         })

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.

4 participants