diff --git a/bson/src/main/org/bson/BinaryVector.java b/bson/src/main/org/bson/BinaryVector.java
index a1914601a9d..f5d57f5b241 100644
--- a/bson/src/main/org/bson/BinaryVector.java
+++ b/bson/src/main/org/bson/BinaryVector.java
@@ -32,6 +32,9 @@
* @since 5.3
*/
public abstract class BinaryVector {
+ /**
+ * The BinaryVector logger
+ */
protected static final Logger LOGGER = Loggers.getLogger("BinaryVector");
private final DataType dataType;
diff --git a/bson/src/main/org/bson/BsonBinary.java b/bson/src/main/org/bson/BsonBinary.java
index 833a1b5ad29..0ece148eb2d 100644
--- a/bson/src/main/org/bson/BsonBinary.java
+++ b/bson/src/main/org/bson/BsonBinary.java
@@ -127,9 +127,14 @@ public BsonBinary(final UUID uuid, final UuidRepresentation uuidRepresentation)
}
/**
- * Returns the binary as a UUID. The binary type must be 4.
+ * Returns the binary as a UUID.
+ *
+ *
Note:The BsonBinary subtype must be {@link BsonBinarySubType#UUID_STANDARD}.
*
* @return the uuid
+ * @throws BsonInvalidOperationException if BsonBinary subtype is not {@link BsonBinarySubType#UUID_STANDARD}
+ * @see #asUuid(UuidRepresentation)
+ * @see BsonBinarySubType
* @since 3.9
*/
public UUID asUuid() {
@@ -162,8 +167,15 @@ public BinaryVector asVector() {
/**
* Returns the binary as a UUID.
*
- * @param uuidRepresentation the UUID representation
+ * Note:The BsonBinary subtype must be either {@link BsonBinarySubType#UUID_STANDARD} or
+ * {@link BsonBinarySubType#UUID_LEGACY}.
+ *
+ * @param uuidRepresentation the UUID representation, must be {@link UuidRepresentation#STANDARD} or
+ * {@link UuidRepresentation#JAVA_LEGACY}
* @return the uuid
+ * @throws BsonInvalidOperationException if the BsonBinary subtype is incompatible with the given {@code uuidRepresentation}, or if
+ * the {@code uuidRepresentation} is not {@link UuidRepresentation#STANDARD} or
+ * {@link UuidRepresentation#JAVA_LEGACY}.
* @since 3.9
*/
public UUID asUuid(final UuidRepresentation uuidRepresentation) {
diff --git a/bson/src/main/org/bson/BsonBinarySubType.java b/bson/src/main/org/bson/BsonBinarySubType.java
index 08c29e2ef09..2a6eed1f5de 100644
--- a/bson/src/main/org/bson/BsonBinarySubType.java
+++ b/bson/src/main/org/bson/BsonBinarySubType.java
@@ -93,7 +93,7 @@ public enum BsonBinarySubType {
* Returns true if the given value is a UUID subtype.
*
* @param value the subtype value as a byte.
- * @return true if value is a UUID subtype.
+ * @return true if value has a {@link #UUID_STANDARD} or {@link #UUID_LEGACY} subtype.
* @since 3.4
*/
public static boolean isUuid(final byte value) {
diff --git a/driver-core/src/test/unit/com/mongodb/internal/TimeoutContextTest.java b/driver-core/src/test/unit/com/mongodb/internal/TimeoutContextTest.java
index be4526aada7..5f736f421c2 100644
--- a/driver-core/src/test/unit/com/mongodb/internal/TimeoutContextTest.java
+++ b/driver-core/src/test/unit/com/mongodb/internal/TimeoutContextTest.java
@@ -331,9 +331,10 @@ static Stream shouldChooseTimeoutMsWhenItIsLessThenConnectTimeoutMS()
);
}
- @ParameterizedTest
- @MethodSource
@DisplayName("should choose timeoutMS when timeoutMS is less than connectTimeoutMS")
+ @ParameterizedTest(name = "should choose timeoutMS when timeoutMS is less than connectTimeoutMS. "
+ + "Parameters: connectTimeoutMS: {0}, timeoutMS: {1}, expected: {2}")
+ @MethodSource
void shouldChooseTimeoutMsWhenItIsLessThenConnectTimeoutMS(final Long connectTimeoutMS,
final Long timeoutMS,
final long expected) {
@@ -345,7 +346,7 @@ void shouldChooseTimeoutMsWhenItIsLessThenConnectTimeoutMS(final Long connectTim
0));
long calculatedTimeoutMS = timeoutContext.getConnectTimeoutMs();
- assertTrue(expected - calculatedTimeoutMS <= 1);
+ assertTrue(expected - calculatedTimeoutMS <= 2);
}
private TimeoutContextTest() {
diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/TimeoutHelper.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/TimeoutHelper.java
index bc4da3026a9..cefdf7184d8 100644
--- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/TimeoutHelper.java
+++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/TimeoutHelper.java
@@ -55,8 +55,14 @@ public static MongoCollection collectionWithTimeout(final MongoCollection
public static Mono> collectionWithTimeoutMono(final MongoCollection collection,
@Nullable final Timeout timeout) {
+ return collectionWithTimeoutMono(collection, timeout, DEFAULT_TIMEOUT_MESSAGE);
+ }
+
+ public static Mono> collectionWithTimeoutMono(final MongoCollection collection,
+ @Nullable final Timeout timeout,
+ final String message) {
try {
- return Mono.just(collectionWithTimeout(collection, timeout));
+ return Mono.just(collectionWithTimeout(collection, timeout, message));
} catch (MongoOperationTimeoutException e) {
return Mono.error(e);
}
@@ -64,9 +70,14 @@ public static Mono> collectionWithTimeoutMono(final Mongo
public static Mono> collectionWithTimeoutDeferred(final MongoCollection collection,
@Nullable final Timeout timeout) {
- return Mono.defer(() -> collectionWithTimeoutMono(collection, timeout));
+ return collectionWithTimeoutDeferred(collection, timeout, DEFAULT_TIMEOUT_MESSAGE);
}
+ public static Mono> collectionWithTimeoutDeferred(final MongoCollection collection,
+ @Nullable final Timeout timeout,
+ final String message) {
+ return Mono.defer(() -> collectionWithTimeoutMono(collection, timeout, message));
+ }
public static MongoDatabase databaseWithTimeout(final MongoDatabase database,
@Nullable final Timeout timeout) {
diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/gridfs/GridFSUploadPublisherImpl.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/gridfs/GridFSUploadPublisherImpl.java
index 7d9a46cdf3f..50586e92102 100644
--- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/gridfs/GridFSUploadPublisherImpl.java
+++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/gridfs/GridFSUploadPublisherImpl.java
@@ -54,7 +54,8 @@
*/
public final class GridFSUploadPublisherImpl implements GridFSUploadPublisher {
- private static final String TIMEOUT_ERROR_MESSAGE = "Saving chunks exceeded the timeout limit.";
+ private static final String TIMEOUT_ERROR_MESSAGE_CHUNKS_SAVING = "Saving chunks exceeded the timeout limit.";
+ private static final String TIMEOUT_ERROR_MESSAGE_UPLOAD_CANCELLATION = "Upload cancellation exceeded the timeout limit.";
private static final Document PROJECTION = new Document("_id", 1);
private static final Document FILES_INDEX = new Document("filename", 1).append("uploadDate", 1);
private static final Document CHUNKS_INDEX = new Document("files_id", 1).append("n", 1);
@@ -226,8 +227,8 @@ private Mono createSaveChunksMono(final AtomicBoolean terminated, @Nullabl
.append("data", data);
Publisher insertOnePublisher = clientSession == null
- ? collectionWithTimeout(chunksCollection, timeout, TIMEOUT_ERROR_MESSAGE).insertOne(chunkDocument)
- : collectionWithTimeout(chunksCollection, timeout, TIMEOUT_ERROR_MESSAGE)
+ ? collectionWithTimeout(chunksCollection, timeout, TIMEOUT_ERROR_MESSAGE_CHUNKS_SAVING).insertOne(chunkDocument)
+ : collectionWithTimeout(chunksCollection, timeout, TIMEOUT_ERROR_MESSAGE_CHUNKS_SAVING)
.insertOne(clientSession, chunkDocument);
return Mono.from(insertOnePublisher).thenReturn(data.length());
@@ -270,7 +271,8 @@ private Mono createSaveFileDataMono(final AtomicBoolean termina
}
private Mono createCancellationMono(final AtomicBoolean terminated, @Nullable final Timeout timeout) {
- Mono> chunksCollectionMono = collectionWithTimeoutDeferred(chunksCollection, timeout);
+ Mono> chunksCollectionMono = collectionWithTimeoutDeferred(chunksCollection, timeout,
+ TIMEOUT_ERROR_MESSAGE_UPLOAD_CANCELLATION);
if (terminated.compareAndSet(false, true)) {
if (clientSession != null) {
return chunksCollectionMono.flatMap(collection -> Mono.from(collection
diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java
index b922ec20b71..90446953fc1 100644
--- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java
+++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java
@@ -16,7 +16,6 @@
package com.mongodb.reactivestreams.client;
-import com.mongodb.ClusterFixture;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCommandException;
import com.mongodb.MongoNamespace;
@@ -24,7 +23,6 @@
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
import com.mongodb.client.AbstractClientSideOperationsTimeoutProseTest;
-import com.mongodb.client.model.CreateCollectionOptions;
import com.mongodb.client.model.changestream.FullDocument;
import com.mongodb.event.CommandFailedEvent;
import com.mongodb.event.CommandStartedEvent;
@@ -43,6 +41,7 @@
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Hooks;
+import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.nio.ByteBuffer;
@@ -58,12 +57,16 @@
import static com.mongodb.ClusterFixture.TIMEOUT_DURATION;
import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet;
+import static com.mongodb.ClusterFixture.isStandalone;
import static com.mongodb.ClusterFixture.serverVersionAtLeast;
import static com.mongodb.ClusterFixture.sleep;
+import static com.mongodb.assertions.Assertions.assertTrue;
import static java.util.Collections.singletonList;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
@@ -104,7 +107,6 @@ protected boolean isAsync() {
@Override
public void testGridFSUploadViaOpenUploadStreamTimeout() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
//given
collectionHelper.runAdminCommand("{"
@@ -113,12 +115,12 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() {
+ " data: {"
+ " failCommands: [\"insert\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 405)
+ + " blockTimeMS: " + 600
+ " }"
+ "}");
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 400, TimeUnit.MILLISECONDS))) {
+ .timeout(600, TimeUnit.MILLISECONDS))) {
MongoDatabase database = client.getDatabase(gridFsFileNamespace.getDatabaseName());
GridFSBucket gridFsBucket = createReaciveGridFsBucket(database, GRID_FS_BUCKET_NAME);
@@ -158,7 +160,6 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() {
@Override
public void testAbortingGridFsUploadStreamTimeout() throws ExecutionException, InterruptedException, TimeoutException {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
//given
CompletableFuture droppedErrorFuture = new CompletableFuture<>();
@@ -170,12 +171,12 @@ public void testAbortingGridFsUploadStreamTimeout() throws ExecutionException, I
+ " data: {"
+ " failCommands: [\"delete\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 405)
+ + " blockTimeMS: " + 405
+ " }"
+ "}");
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 400, TimeUnit.MILLISECONDS))) {
+ .timeout(400, TimeUnit.MILLISECONDS))) {
MongoDatabase database = client.getDatabase(gridFsFileNamespace.getDatabaseName());
GridFSBucket gridFsBucket = createReaciveGridFsBucket(database, GRID_FS_BUCKET_NAME);
@@ -198,12 +199,25 @@ public void testAbortingGridFsUploadStreamTimeout() throws ExecutionException, I
//then
Throwable droppedError = droppedErrorFuture.get(TIMEOUT_DURATION.toMillis(), TimeUnit.MILLISECONDS);
Throwable commandError = droppedError.getCause();
- assertInstanceOf(MongoOperationTimeoutException.class, commandError);
CommandFailedEvent deleteFailedEvent = commandListener.getCommandFailedEvent("delete");
assertNotNull(deleteFailedEvent);
- assertEquals(commandError, commandListener.getCommandFailedEvent("delete").getThrowable());
+ CommandStartedEvent deleteStartedEvent = commandListener.getCommandStartedEvent("delete");
+ assertTrue(deleteStartedEvent.getCommand().containsKey("maxTimeMS"), "Expected delete command to have maxTimeMS");
+ long deleteMaxTimeMS = deleteStartedEvent
+ .getCommand()
+ .get("maxTimeMS")
+ .asNumber()
+ .longValue();
+
+ assertTrue(deleteMaxTimeMS <= 420
+ // some leeway for timing variations, when compression is used it is often less then 300.
+ // Without it, it is more than 300.
+ && deleteMaxTimeMS >= 150,
+ "Expected maxTimeMS for delete command to be between 150s and 420ms, " + "but was: " + deleteMaxTimeMS + "ms");
+ assertEquals(commandError, deleteFailedEvent.getThrowable());
+
// When subscription is cancelled, we should not receive any more events.
testSubscriber.assertNoTerminalEvent();
}
@@ -219,9 +233,8 @@ public void testTimeoutMSAppliesToFullResumeAttemptInNextCall() {
assumeTrue(isDiscoverableReplicaSet());
//given
- long rtt = ClusterFixture.getPrimaryRTT();
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 500, TimeUnit.MILLISECONDS))) {
+ .timeout(500, TimeUnit.MILLISECONDS))) {
MongoNamespace namespace = generateNamespace();
MongoCollection collection = client.getDatabase(namespace.getDatabaseName())
@@ -273,9 +286,8 @@ public void testTimeoutMSAppliedToInitialAggregate() {
assumeTrue(isDiscoverableReplicaSet());
//given
- long rtt = ClusterFixture.getPrimaryRTT();
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 200, TimeUnit.MILLISECONDS))) {
+ .timeout(200, TimeUnit.MILLISECONDS))) {
MongoNamespace namespace = generateNamespace();
MongoCollection collection = client.getDatabase(namespace.getDatabaseName())
@@ -290,7 +302,7 @@ public void testTimeoutMSAppliedToInitialAggregate() {
+ " data: {"
+ " failCommands: [\"aggregate\" ],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 201)
+ + " blockTimeMS: " + 201
+ " }"
+ "}");
@@ -321,13 +333,10 @@ public void testTimeoutMsRefreshedForGetMoreWhenMaxAwaitTimeMsNotSet() {
//given
BsonTimestamp startTime = new BsonTimestamp((int) Instant.now().getEpochSecond(), 0);
- collectionHelper.create(namespace.getCollectionName(), new CreateCollectionOptions());
sleep(2000);
-
- long rtt = ClusterFixture.getPrimaryRTT();
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 300, TimeUnit.MILLISECONDS))) {
+ .timeout(500, TimeUnit.MILLISECONDS))) {
MongoCollection collection = client.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName()).withReadPreference(ReadPreference.primary());
@@ -338,7 +347,7 @@ public void testTimeoutMsRefreshedForGetMoreWhenMaxAwaitTimeMsNotSet() {
+ " data: {"
+ " failCommands: [\"getMore\", \"aggregate\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 200)
+ + " blockTimeMS: " + 200
+ " }"
+ "}");
@@ -389,12 +398,10 @@ public void testTimeoutMsRefreshedForGetMoreWhenMaxAwaitTimeMsSet() {
//given
BsonTimestamp startTime = new BsonTimestamp((int) Instant.now().getEpochSecond(), 0);
- collectionHelper.create(namespace.getCollectionName(), new CreateCollectionOptions());
sleep(2000);
- long rtt = ClusterFixture.getPrimaryRTT();
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 300, TimeUnit.MILLISECONDS))) {
+ .timeout(500, TimeUnit.MILLISECONDS))) {
MongoCollection collection = client.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName())
@@ -406,7 +413,7 @@ public void testTimeoutMsRefreshedForGetMoreWhenMaxAwaitTimeMsSet() {
+ " data: {"
+ " failCommands: [\"aggregate\", \"getMore\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 200)
+ + " blockTimeMS: " + 200
+ " }"
+ "}");
@@ -449,9 +456,8 @@ public void testTimeoutMsISHonoredForNnextOperationWhenSeveralGetMoreExecutedInt
assumeTrue(isDiscoverableReplicaSet());
//given
- long rtt = ClusterFixture.getPrimaryRTT();
try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 2500, TimeUnit.MILLISECONDS))) {
+ .timeout(2500, TimeUnit.MILLISECONDS))) {
MongoCollection collection = client.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName()).withReadPreference(ReadPreference.primary());
@@ -468,7 +474,78 @@ public void testTimeoutMsISHonoredForNnextOperationWhenSeveralGetMoreExecutedInt
List commandStartedEvents = commandListener.getCommandStartedEvents();
assertCommandStartedEventsInOder(Arrays.asList("aggregate", "getMore", "getMore", "getMore", "killCursors"),
commandStartedEvents);
- assertOnlyOneCommandTimeoutFailure("getMore");
+
+ }
+ }
+
+ @DisplayName("9. End Session. The timeout specified via the MongoClient timeoutMS option")
+ @Test
+ @Override
+ public void test9EndSessionClientTimeout() {
+ assumeTrue(serverVersionAtLeast(4, 4));
+ assumeFalse(isStandalone());
+
+ collectionHelper.runAdminCommand("{"
+ + " configureFailPoint: \"failCommand\","
+ + " mode: { times: 1 },"
+ + " data: {"
+ + " failCommands: [\"abortTransaction\"],"
+ + " blockConnection: true,"
+ + " blockTimeMS: " + 400
+ + " }"
+ + "}");
+
+ try (MongoClient mongoClient = createReactiveClient(getMongoClientSettingsBuilder().retryWrites(false)
+ .timeout(300, TimeUnit.MILLISECONDS))) {
+ MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
+ .getCollection(namespace.getCollectionName());
+
+ try (ClientSession session = Mono.from(mongoClient.startSession()).block()) {
+ session.startTransaction();
+ Mono.from(collection.insertOne(session, new Document("x", 1))).block();
+ }
+
+ sleep(postSessionCloseSleep());
+ CommandFailedEvent abortTransactionEvent = assertDoesNotThrow(() -> commandListener.getCommandFailedEvent("abortTransaction"));
+ long elapsedTime = abortTransactionEvent.getElapsedTime(TimeUnit.MILLISECONDS);
+ assertInstanceOf(MongoOperationTimeoutException.class, abortTransactionEvent.getThrowable());
+ assertTrue(elapsedTime <= 400, "Took too long to time out, elapsedMS: " + elapsedTime);
+ }
+ }
+
+ @Test
+ @DisplayName("9. End Session. The timeout specified via the ClientSession defaultTimeoutMS option")
+ @Override
+ public void test9EndSessionSessionTimeout() {
+ assumeTrue(serverVersionAtLeast(4, 4));
+ assumeFalse(isStandalone());
+
+ collectionHelper.runAdminCommand("{"
+ + " configureFailPoint: \"failCommand\","
+ + " mode: { times: 1 },"
+ + " data: {"
+ + " failCommands: [\"abortTransaction\"],"
+ + " blockConnection: true,"
+ + " blockTimeMS: " + 400
+ + " }"
+ + "}");
+
+ try (MongoClient mongoClient = createReactiveClient(getMongoClientSettingsBuilder())) {
+ MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
+ .getCollection(namespace.getCollectionName());
+
+ try (ClientSession session = Mono.from(mongoClient.startSession(com.mongodb.ClientSessionOptions.builder()
+ .defaultTimeout(300, TimeUnit.MILLISECONDS).build())).block()) {
+
+ session.startTransaction();
+ Mono.from(collection.insertOne(session, new Document("x", 1))).block();
+ }
+
+ sleep(postSessionCloseSleep());
+ CommandFailedEvent abortTransactionEvent = assertDoesNotThrow(() -> commandListener.getCommandFailedEvent("abortTransaction"));
+ long elapsedTime = abortTransactionEvent.getElapsedTime(TimeUnit.MILLISECONDS);
+ assertInstanceOf(MongoOperationTimeoutException.class, abortTransactionEvent.getThrowable());
+ assertTrue(elapsedTime <= 400, "Took too long to time out, elapsedMS: " + elapsedTime);
}
}
@@ -512,6 +589,6 @@ public void tearDown() throws InterruptedException {
@Override
protected int postSessionCloseSleep() {
- return 256;
+ return 1000;
}
}
diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java
index 9ce58b1654f..fa39a6d3a06 100644
--- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java
+++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java
@@ -56,11 +56,8 @@
import com.mongodb.internal.connection.TestCommandListener;
import com.mongodb.internal.connection.TestConnectionPoolListener;
import com.mongodb.test.FlakyTest;
-import org.bson.BsonArray;
-import org.bson.BsonBoolean;
import org.bson.BsonDocument;
import org.bson.BsonInt32;
-import org.bson.BsonString;
import org.bson.BsonTimestamp;
import org.bson.Document;
import org.bson.codecs.BsonDocumentCodec;
@@ -256,7 +253,6 @@ public void testBlockingIterationMethodsChangeStream() {
assumeFalse(isAsync()); // Async change stream cursor is non-deterministic for cursor::next
BsonTimestamp startTime = new BsonTimestamp((int) Instant.now().getEpochSecond(), 0);
- collectionHelper.create(namespace.getCollectionName(), new CreateCollectionOptions());
sleep(2000);
collectionHelper.insertDocuments(singletonList(BsonDocument.parse("{x: 1}")), WriteConcern.MAJORITY);
@@ -298,7 +294,6 @@ public void testBlockingIterationMethodsChangeStream() {
@FlakyTest(maxAttempts = 3)
public void testGridFSUploadViaOpenUploadStreamTimeout() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
collectionHelper.runAdminCommand("{"
+ " configureFailPoint: \"failCommand\","
@@ -306,7 +301,7 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() {
+ " data: {"
+ " failCommands: [\"insert\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 205)
+ + " blockTimeMS: " + 205
+ " }"
+ "}");
@@ -314,7 +309,7 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() {
filesCollectionHelper.create();
try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 200, TimeUnit.MILLISECONDS))) {
+ .timeout(200, TimeUnit.MILLISECONDS))) {
MongoDatabase database = client.getDatabase(namespace.getDatabaseName());
GridFSBucket gridFsBucket = createGridFsBucket(database, GRID_FS_BUCKET_NAME);
@@ -329,7 +324,6 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() {
@Test
public void testAbortingGridFsUploadStreamTimeout() throws Throwable {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
collectionHelper.runAdminCommand("{"
+ " configureFailPoint: \"failCommand\","
@@ -337,7 +331,7 @@ public void testAbortingGridFsUploadStreamTimeout() throws Throwable {
+ " data: {"
+ " failCommands: [\"delete\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 305)
+ + " blockTimeMS: " + 320
+ " }"
+ "}");
@@ -345,7 +339,7 @@ public void testAbortingGridFsUploadStreamTimeout() throws Throwable {
filesCollectionHelper.create();
try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 300, TimeUnit.MILLISECONDS))) {
+ .timeout(300, TimeUnit.MILLISECONDS))) {
MongoDatabase database = client.getDatabase(namespace.getDatabaseName());
GridFSBucket gridFsBucket = createGridFsBucket(database, GRID_FS_BUCKET_NAME).withChunkSizeBytes(2);
@@ -360,7 +354,6 @@ public void testAbortingGridFsUploadStreamTimeout() throws Throwable {
@Test
public void testGridFsDownloadStreamTimeout() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
chunksCollectionHelper.create();
filesCollectionHelper.create();
@@ -382,18 +375,19 @@ public void testGridFsDownloadStreamTimeout() {
+ " metadata: {}"
+ "}"
)), WriteConcern.MAJORITY);
+
collectionHelper.runAdminCommand("{"
+ " configureFailPoint: \"failCommand\","
+ " mode: { skip: 1 },"
+ " data: {"
+ " failCommands: [\"find\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 95)
+ + " blockTimeMS: " + 500
+ " }"
+ "}");
try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder()
- .timeout(rtt + 100, TimeUnit.MILLISECONDS))) {
+ .timeout(300, TimeUnit.MILLISECONDS))) {
MongoDatabase database = client.getDatabase(namespace.getDatabaseName());
GridFSBucket gridFsBucket = createGridFsBucket(database, GRID_FS_BUCKET_NAME).withChunkSizeBytes(2);
@@ -401,7 +395,9 @@ public void testGridFsDownloadStreamTimeout() {
assertThrows(MongoOperationTimeoutException.class, downloadStream::read);
List events = commandListener.getCommandStartedEvents();
- List findCommands = events.stream().filter(e -> e.getCommandName().equals("find")).collect(Collectors.toList());
+ List findCommands = events.stream()
+ .filter(e -> e.getCommandName().equals("find"))
+ .collect(Collectors.toList());
assertEquals(2, findCommands.size());
assertEquals(gridFsFileNamespace.getCollectionName(), findCommands.get(0).getCommand().getString("find").getValue());
@@ -414,7 +410,7 @@ public void testGridFsDownloadStreamTimeout() {
@ParameterizedTest(name = "[{index}] {0}")
@MethodSource("test8ServerSelectionArguments")
public void test8ServerSelection(final String connectionString) {
- int timeoutBuffer = 100; // 5 in spec, Java is slower
+ int timeoutBuffer = 150; // 5 in spec, Java is slower
// 1. Create a MongoClient
try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder()
.applyConnectionString(new ConnectionString(connectionString)))
@@ -450,7 +446,7 @@ public void test8ServerSelectionHandshake(final String ignoredTestName, final in
+ " data: {"
+ " failCommands: [\"saslContinue\"],"
+ " blockConnection: true,"
- + " blockTimeMS: 350"
+ + " blockTimeMS: 600"
+ " }"
+ "}");
@@ -466,7 +462,7 @@ public void test8ServerSelectionHandshake(final String ignoredTestName, final in
.insertOne(new Document("x", 1));
});
long elapsed = msElapsedSince(start);
- assertTrue(elapsed <= 310, "Took too long to time out, elapsedMS: " + elapsed);
+ assertTrue(elapsed <= 350, "Took too long to time out, elapsedMS: " + elapsed);
}
}
@@ -483,23 +479,23 @@ public void test9EndSessionClientTimeout() {
+ " data: {"
+ " failCommands: [\"abortTransaction\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + 150
+ + " blockTimeMS: " + 500
+ " }"
+ "}");
try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder().retryWrites(false)
- .timeout(100, TimeUnit.MILLISECONDS))) {
- MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
+ .timeout(250, TimeUnit.MILLISECONDS))) {
+ MongoDatabase database = mongoClient.getDatabase(namespace.getDatabaseName());
+ MongoCollection collection = database
.getCollection(namespace.getCollectionName());
try (ClientSession session = mongoClient.startSession()) {
session.startTransaction();
collection.insertOne(session, new Document("x", 1));
-
long start = System.nanoTime();
session.close();
- long elapsed = msElapsedSince(start) - postSessionCloseSleep();
- assertTrue(elapsed <= 150, "Took too long to time out, elapsedMS: " + elapsed);
+ long elapsed = msElapsedSince(start);
+ assertTrue(elapsed <= 300, "Took too long to time out, elapsedMS: " + elapsed);
}
}
CommandFailedEvent abortTransactionEvent = assertDoesNotThrow(() ->
@@ -520,7 +516,7 @@ public void test9EndSessionSessionTimeout() {
+ " data: {"
+ " failCommands: [\"abortTransaction\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + 150
+ + " blockTimeMS: " + 400
+ " }"
+ "}");
@@ -529,14 +525,14 @@ public void test9EndSessionSessionTimeout() {
.getCollection(namespace.getCollectionName());
try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder()
- .defaultTimeout(100, TimeUnit.MILLISECONDS).build())) {
+ .defaultTimeout(300, TimeUnit.MILLISECONDS).build())) {
session.startTransaction();
collection.insertOne(session, new Document("x", 1));
long start = System.nanoTime();
session.close();
- long elapsed = msElapsedSince(start) - postSessionCloseSleep();
- assertTrue(elapsed <= 150, "Took too long to time out, elapsedMS: " + elapsed);
+ long elapsed = msElapsedSince(start);
+ assertTrue(elapsed <= 400, "Took too long to time out, elapsedMS: " + elapsed);
}
}
CommandFailedEvent abortTransactionEvent = assertDoesNotThrow(() ->
@@ -563,11 +559,12 @@ public void test9EndSessionCustomTesEachOperationHasItsOwnTimeoutWithCommit() {
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName());
+ int defaultTimeout = 300;
try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder()
- .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) {
+ .defaultTimeout(defaultTimeout, TimeUnit.MILLISECONDS).build())) {
session.startTransaction();
collection.insertOne(session, new Document("x", 1));
- sleep(200);
+ sleep(defaultTimeout);
assertDoesNotThrow(session::commitTransaction);
}
@@ -594,11 +591,12 @@ public void test9EndSessionCustomTesEachOperationHasItsOwnTimeoutWithAbort() {
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName());
+ int defaultTimeout = 300;
try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder()
- .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) {
+ .defaultTimeout(defaultTimeout, TimeUnit.MILLISECONDS).build())) {
session.startTransaction();
collection.insertOne(session, new Document("x", 1));
- sleep(200);
+ sleep(defaultTimeout);
assertDoesNotThrow(session::close);
}
@@ -618,12 +616,12 @@ public void test10ConvenientTransactions() {
+ " data: {"
+ " failCommands: [\"insert\", \"abortTransaction\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + 150
+ + " blockTimeMS: " + 200
+ " }"
+ "}");
try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder()
- .timeout(100, TimeUnit.MILLISECONDS))) {
+ .timeout(150, TimeUnit.MILLISECONDS))) {
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName());
@@ -661,12 +659,13 @@ public void test10CustomTestWithTransactionUsesASingleTimeout() {
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName());
+ int defaultTimeout = 200;
try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder()
- .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) {
+ .defaultTimeout(defaultTimeout, TimeUnit.MILLISECONDS).build())) {
assertThrows(MongoOperationTimeoutException.class,
() -> session.withTransaction(() -> {
collection.insertOne(session, new Document("x", 1));
- sleep(200);
+ sleep(defaultTimeout);
return true;
})
);
@@ -696,12 +695,13 @@ public void test10CustomTestWithTransactionUsesASingleTimeoutWithLock() {
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName());
+ int defaultTimeout = 200;
try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder()
- .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) {
+ .defaultTimeout(defaultTimeout, TimeUnit.MILLISECONDS).build())) {
assertThrows(MongoOperationTimeoutException.class,
() -> session.withTransaction(() -> {
collection.insertOne(session, new Document("x", 1));
- sleep(200);
+ sleep(defaultTimeout);
return true;
})
);
@@ -710,7 +710,7 @@ public void test10CustomTestWithTransactionUsesASingleTimeoutWithLock() {
}
@DisplayName("11. Multi-batch bulkWrites")
- @Test
+ @FlakyTest(maxAttempts = 3)
@SuppressWarnings("try")
protected void test11MultiBatchBulkWrites() throws InterruptedException {
assumeTrue(serverVersionAtLeast(8, 0));
@@ -718,12 +718,18 @@ protected void test11MultiBatchBulkWrites() throws InterruptedException {
// a workaround for https://jira.mongodb.org/browse/DRIVERS-2997, remove this block when the aforementioned bug is fixed
client.getDatabase(namespace.getDatabaseName()).drop();
}
- BsonDocument failPointDocument = new BsonDocument("configureFailPoint", new BsonString("failCommand"))
- .append("mode", new BsonDocument("times", new BsonInt32(2)))
- .append("data", new BsonDocument("failCommands", new BsonArray(singletonList(new BsonString("bulkWrite"))))
- .append("blockConnection", BsonBoolean.TRUE)
- .append("blockTimeMS", new BsonInt32(2020)));
- try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder().timeout(4000, TimeUnit.MILLISECONDS));
+ BsonDocument failPointDocument = BsonDocument.parse("{"
+ + " configureFailPoint: \"failCommand\","
+ + " mode: { times: 2},"
+ + " data: {"
+ + " failCommands: [\"bulkWrite\" ],"
+ + " blockConnection: true,"
+ + " blockTimeMS: " + 2020
+ + " }"
+ + "}");
+
+ long timeout = 4000;
+ try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder().timeout(timeout, TimeUnit.MILLISECONDS));
FailPoint ignored = FailPoint.enable(failPointDocument, getPrimary())) {
MongoDatabase db = client.getDatabase(namespace.getDatabaseName());
db.drop();
@@ -746,8 +752,8 @@ protected void test11MultiBatchBulkWrites() throws InterruptedException {
* Not a prose spec test. However, it is additional test case for better coverage.
*/
@Test
- @DisplayName("Should ignore wTimeoutMS of WriteConcern to initial and subsequent commitTransaction operations")
- public void shouldIgnoreWtimeoutMsOfWriteConcernToInitialAndSubsequentCommitTransactionOperations() {
+ @DisplayName("Should not include wTimeoutMS of WriteConcern to initial and subsequent commitTransaction operations")
+ public void shouldNotIncludeWtimeoutMsOfWriteConcernToInitialAndSubsequentCommitTransactionOperations() {
assumeTrue(serverVersionAtLeast(4, 4));
assumeFalse(isStandalone());
@@ -755,14 +761,15 @@ public void shouldIgnoreWtimeoutMsOfWriteConcernToInitialAndSubsequentCommitTran
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
.getCollection(namespace.getCollectionName());
+ int defaultTimeout = 200;
try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder()
- .defaultTimeout(200, TimeUnit.MILLISECONDS)
+ .defaultTimeout(defaultTimeout, TimeUnit.MILLISECONDS)
.build())) {
session.startTransaction(TransactionOptions.builder()
.writeConcern(WriteConcern.ACKNOWLEDGED.withWTimeout(100, TimeUnit.MILLISECONDS))
.build());
collection.insertOne(session, new Document("x", 1));
- sleep(200);
+ sleep(defaultTimeout);
assertDoesNotThrow(session::commitTransaction);
//repeat commit.
@@ -805,12 +812,12 @@ public void shouldIgnoreWaitQueueTimeoutMSWhenTimeoutMsIsSet() {
+ " data: {"
+ " failCommands: [\"find\" ],"
+ " blockConnection: true,"
- + " blockTimeMS: " + 300
+ + " blockTimeMS: " + 450
+ " }"
+ "}");
executor.submit(() -> collection.find().first());
- sleep(100);
+ sleep(150);
//when && then
assertDoesNotThrow(() -> collection.find().first());
@@ -863,7 +870,7 @@ public void shouldUseWaitQueueTimeoutMSWhenTimeoutIsNotSet() {
//given
try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder()
.applyToConnectionPoolSettings(builder -> builder
- .maxWaitTime(100, TimeUnit.MILLISECONDS)
+ .maxWaitTime(20, TimeUnit.MILLISECONDS)
.maxSize(1)
))) {
MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName())
@@ -875,12 +882,12 @@ public void shouldUseWaitQueueTimeoutMSWhenTimeoutIsNotSet() {
+ " data: {"
+ " failCommands: [\"find\" ],"
+ " blockConnection: true,"
- + " blockTimeMS: " + 300
+ + " blockTimeMS: " + 400
+ " }"
+ "}");
executor.submit(() -> collection.find().first());
- sleep(100);
+ sleep(200);
//when & then
assertThrows(MongoTimeoutException.class, () -> collection.find().first());
@@ -896,7 +903,6 @@ public void testKillCursorsIsNotExecutedAfterGetMoreNetworkErrorWhenTimeoutMsIsN
assumeTrue(serverVersionAtLeast(4, 4));
assumeTrue(isLoadBalanced());
- long rtt = ClusterFixture.getPrimaryRTT();
collectionHelper.create(namespace.getCollectionName(), new CreateCollectionOptions());
collectionHelper.insertDocuments(new Document(), new Document());
collectionHelper.runAdminCommand("{"
@@ -905,7 +911,7 @@ public void testKillCursorsIsNotExecutedAfterGetMoreNetworkErrorWhenTimeoutMsIsN
+ " data: {"
+ " failCommands: [\"getMore\" ],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 600)
+ + " blockTimeMS: " + 600
+ " }"
+ "}");
@@ -943,7 +949,6 @@ public void testKillCursorsIsNotExecutedAfterGetMoreNetworkError() {
assumeTrue(serverVersionAtLeast(4, 4));
assumeTrue(isLoadBalanced());
- long rtt = ClusterFixture.getPrimaryRTT();
collectionHelper.create(namespace.getCollectionName(), new CreateCollectionOptions());
collectionHelper.insertDocuments(new Document(), new Document());
collectionHelper.runAdminCommand("{"
@@ -952,7 +957,7 @@ public void testKillCursorsIsNotExecutedAfterGetMoreNetworkError() {
+ " data: {"
+ " failCommands: [\"getMore\" ],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 600)
+ + " blockTimeMS: " + 600
+ " }"
+ "}");
@@ -1040,11 +1045,16 @@ public void shouldUseConnectTimeoutMsWhenEstablishingConnectionInBackground() {
+ " data: {"
+ " failCommands: [\"hello\", \"isMaster\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + 500
+ + " blockTimeMS: " + 500 + ","
+ // The appName is unique to prevent this failpoint from affecting ClusterFixture's ServerMonitor.
+ // Without the appName, ClusterFixture's heartbeats would be blocked, polluting RTT measurements with 500ms values,
+ // which would cause flakiness in other prose tests that use ClusterFixture.getPrimaryRTT() for timeout adjustments.
+ + " appName: \"connectTimeoutBackgroundTest\""
+ " }"
+ "}");
try (MongoClient ignored = createMongoClient(getMongoClientSettingsBuilder()
+ .applicationName("connectTimeoutBackgroundTest")
.applyToConnectionPoolSettings(builder -> builder.minSize(1))
// Use a very short timeout to ensure that the connection establishment will fail on the first handshake command.
.timeout(10, TimeUnit.MILLISECONDS))) {
@@ -1075,9 +1085,10 @@ private static Stream test8ServerSelectionArguments() {
}
private static Stream test8ServerSelectionHandshakeArguments() {
+
return Stream.of(
- Arguments.of("timeoutMS honored for connection handshake commands if it's lower than serverSelectionTimeoutMS", 200, 300),
- Arguments.of("serverSelectionTimeoutMS honored for connection handshake commands if it's lower than timeoutMS", 300, 200)
+ Arguments.of("timeoutMS honored for connection handshake commands if it's lower than serverSelectionTimeoutMS", 200, 500),
+ Arguments.of("serverSelectionTimeoutMS honored for connection handshake commands if it's lower than timeoutMS", 500, 200)
);
}
@@ -1088,7 +1099,8 @@ protected MongoNamespace generateNamespace() {
protected MongoClientSettings.Builder getMongoClientSettingsBuilder() {
commandListener.reset();
- return Fixture.getMongoClientSettingsBuilder()
+ MongoClientSettings.Builder mongoClientSettingsBuilder = Fixture.getMongoClientSettingsBuilder();
+ return mongoClientSettingsBuilder
.readConcern(ReadConcern.MAJORITY)
.writeConcern(WriteConcern.MAJORITY)
.readPreference(ReadPreference.primary())
@@ -1103,6 +1115,9 @@ public void setUp() {
gridFsChunksNamespace = new MongoNamespace(getDefaultDatabaseName(), GRID_FS_BUCKET_NAME + ".chunks");
collectionHelper = new CollectionHelper<>(new BsonDocumentCodec(), namespace);
+ // in some test collection might not have been created yet, thus dropping it in afterEach will throw an error
+ collectionHelper.create();
+
filesCollectionHelper = new CollectionHelper<>(new BsonDocumentCodec(), gridFsFileNamespace);
chunksCollectionHelper = new CollectionHelper<>(new BsonDocumentCodec(), gridFsChunksNamespace);
commandListener = new TestCommandListener();
@@ -1112,10 +1127,13 @@ public void setUp() {
public void tearDown() throws InterruptedException {
ClusterFixture.disableFailPoint(FAIL_COMMAND_NAME);
if (collectionHelper != null) {
+ // Due to testing abortTransaction via failpoint, there may be open transactions
+ // after the test finishes, thus drop() command hangs for 60 seconds until transaction
+ // is automatically rolled back.
+ collectionHelper.runAdminCommand("{killAllSessions: []}");
collectionHelper.drop();
filesCollectionHelper.drop();
chunksCollectionHelper.drop();
- commandListener.reset();
try {
ServerHelper.checkPool(getPrimary());
} catch (InterruptedException e) {
@@ -1139,7 +1157,7 @@ private MongoClient createMongoClient(final MongoClientSettings.Builder builder)
return createMongoClient(builder.build());
}
- private long msElapsedSince(final long t1) {
+ protected long msElapsedSince(final long t1) {
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1);
}
diff --git a/driver-sync/src/test/functional/com/mongodb/client/csot/AbstractClientSideOperationsEncryptionTimeoutProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/csot/AbstractClientSideOperationsEncryptionTimeoutProseTest.java
index dd45bc8ae2c..04303833bf5 100644
--- a/driver-sync/src/test/functional/com/mongodb/client/csot/AbstractClientSideOperationsEncryptionTimeoutProseTest.java
+++ b/driver-sync/src/test/functional/com/mongodb/client/csot/AbstractClientSideOperationsEncryptionTimeoutProseTest.java
@@ -93,14 +93,13 @@ public abstract class AbstractClientSideOperationsEncryptionTimeoutProseTest {
@Test
void shouldThrowOperationTimeoutExceptionWhenCreateDataKey() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
Map> kmsProviders = new HashMap<>();
Map localProviderMap = new HashMap<>();
localProviderMap.put("key", Base64.getDecoder().decode(MASTER_KEY));
kmsProviders.put("local", localProviderMap);
- try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(rtt + 100))) {
+ try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(100))) {
keyVaultCollectionHelper.runAdminCommand("{"
+ " configureFailPoint: \"" + FAIL_COMMAND_NAME + "\","
@@ -108,7 +107,7 @@ void shouldThrowOperationTimeoutExceptionWhenCreateDataKey() {
+ " data: {"
+ " failCommands: [\"insert\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 100)
+ + " blockTimeMS: " + 100
+ " }"
+ "}");
@@ -126,9 +125,8 @@ void shouldThrowOperationTimeoutExceptionWhenCreateDataKey() {
@Test
void shouldThrowOperationTimeoutExceptionWhenEncryptData() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
- try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(rtt + 150))) {
+ try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(150))) {
clientEncryption.createDataKey("local");
@@ -138,7 +136,7 @@ void shouldThrowOperationTimeoutExceptionWhenEncryptData() {
+ " data: {"
+ " failCommands: [\"find\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 150)
+ + " blockTimeMS: " + 150
+ " }"
+ "}");
@@ -160,10 +158,9 @@ void shouldThrowOperationTimeoutExceptionWhenEncryptData() {
@Test
void shouldThrowOperationTimeoutExceptionWhenDecryptData() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
BsonBinary encrypted;
- try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(rtt + 400))) {
+ try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(400))) {
clientEncryption.createDataKey("local");
BsonBinary dataKey = clientEncryption.createDataKey("local");
EncryptOptions encryptOptions = new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic");
@@ -171,14 +168,14 @@ void shouldThrowOperationTimeoutExceptionWhenDecryptData() {
encrypted = clientEncryption.encrypt(new BsonString("hello"), encryptOptions);
}
- try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(rtt + 400))) {
+ try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder(400))) {
keyVaultCollectionHelper.runAdminCommand("{"
- + " configureFailPoint: \"" + FAIL_COMMAND_NAME + "\","
+ + " configureFailPoint: \"" + FAIL_COMMAND_NAME + "\","
+ " mode: { times: 1 },"
+ " data: {"
+ " failCommands: [\"find\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 500)
+ + " blockTimeMS: " + 500
+ " }"
+ "}");
commandListener.reset();
@@ -197,8 +194,7 @@ void shouldThrowOperationTimeoutExceptionWhenDecryptData() {
@Test
void shouldDecreaseOperationTimeoutForSubsequentOperations() {
assumeTrue(serverVersionAtLeast(4, 4));
- long rtt = ClusterFixture.getPrimaryRTT();
- long initialTimeoutMS = rtt + 2500;
+ long initialTimeoutMS = 2500;
keyVaultCollectionHelper.runAdminCommand("{"
+ " configureFailPoint: \"" + FAIL_COMMAND_NAME + "\","
@@ -206,7 +202,7 @@ void shouldDecreaseOperationTimeoutForSubsequentOperations() {
+ " data: {"
+ " failCommands: [\"insert\", \"find\", \"listCollections\"],"
+ " blockConnection: true,"
- + " blockTimeMS: " + (rtt + 10)
+ + " blockTimeMS: " + 10
+ " }"
+ "}");
@@ -272,8 +268,7 @@ void shouldDecreaseOperationTimeoutForSubsequentOperations() {
void shouldThrowTimeoutExceptionWhenCreateEncryptedCollection(final String commandToTimeout) {
assumeTrue(serverVersionAtLeast(7, 0));
//given
- long rtt = ClusterFixture.getPrimaryRTT();
- long initialTimeoutMS = rtt + 200;
+ long initialTimeoutMS = 200;
try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder()
.timeout(initialTimeoutMS, MILLISECONDS))) {
diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java
index 2225f837ec5..328c8298b6c 100644
--- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java
+++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java
@@ -63,6 +63,25 @@ public static void applyCustomizations(final TestDef def) {
.file("client-side-encryption/tests/unified", "client bulkWrite with queryable encryption");
// client-side-operation-timeout (CSOT)
+ def.retry("Unified CSOT tests do not account for RTT which varies in TLS vs non-TLS runs")
+ .whenFailureContains("timeout")
+ .test("client-side-operations-timeout",
+ "timeoutMS behaves correctly for non-tailable cursors",
+ "timeoutMS is refreshed for getMore if timeoutMode is iteration - success");
+
+ def.retry("Unified CSOT tests do not account for RTT which varies in TLS vs non-TLS runs")
+ .whenFailureContains("timeout")
+ .test("client-side-operations-timeout",
+ "timeoutMS behaves correctly for tailable non-awaitData cursors",
+ "timeoutMS is refreshed for getMore - success");
+
+ def.retry("Unified CSOT tests do not account for RTT which varies in TLS vs non-TLS runs")
+ .whenFailureContains("timeout")
+ .test("client-side-operations-timeout",
+ "timeoutMS behaves correctly for tailable non-awaitData cursors",
+ "timeoutMS is refreshed for getMore - success");
+
+ //TODO-invistigate
/*
As to the background connection pooling section:
timeoutMS set at the MongoClient level MUST be used as the timeout for all commands sent as part of the handshake.
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 8a08c34f213..b5e561c7f7e 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -18,10 +18,10 @@ aws-sdk-v2 = "2.30.31"
graal-sdk = "24.0.0"
jna = "5.11.0"
jnr-unixsocket = "0.38.17"
-netty-bom = "4.1.87.Final"
+netty-bom = "4.2.9.Final"
project-reactor-bom = "2022.0.0"
reactive-streams = "1.0.4"
-snappy = "1.1.10.3"
+snappy = "1.1.10.4"
zstd = "1.5.5-3"
jetbrains-annotations = "26.0.2"
micrometer-tracing = "1.6.0-M3" # This version has a fix for https://github.com/micrometer-metrics/tracing/issues/1092