diff --git a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java index c2a32fb6d02..e6d7c1ee643 100644 --- a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java +++ b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java @@ -830,4 +830,11 @@ public static int getReferenceCountAfterTimeout(final ReferenceCounted reference public static ClusterSettings.Builder setDirectConnection(final ClusterSettings.Builder builder) { return builder.mode(ClusterConnectionMode.SINGLE).hosts(singletonList(getPrimary())); } + + public static int applyTimeoutMultiplierForServerless(final int timeoutMs) { + if (ClusterFixture.isServerlessTest()) { + return timeoutMs * 2; + } + return timeoutMs; + } } 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 e4d8971872f..75a19536cb7 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 @@ -58,6 +58,7 @@ import java.util.stream.Collectors; import static com.mongodb.ClusterFixture.TIMEOUT_DURATION; +import static com.mongodb.ClusterFixture.applyTimeoutMultiplierForServerless; import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet; import static com.mongodb.ClusterFixture.isServerlessTest; import static com.mongodb.ClusterFixture.serverVersionAtLeast; @@ -119,12 +120,12 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() { + " data: {" + " failCommands: [\"insert\"]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 405) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(405)) + " }" + "}"); try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder() - .timeout(rtt + 400, TimeUnit.MILLISECONDS))) { + .timeout(rtt + applyTimeoutMultiplierForServerless(400), TimeUnit.MILLISECONDS))) { MongoDatabase database = client.getDatabase(gridFsFileNamespace.getDatabaseName()); GridFSBucket gridFsBucket = createReaciveGridFsBucket(database, GRID_FS_BUCKET_NAME); @@ -178,12 +179,12 @@ public void testAbortingGridFsUploadStreamTimeout() throws ExecutionException, I + " data: {" + " failCommands: [\"delete\"]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 405) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(405)) + " }" + "}"); try (MongoClient client = createReactiveClient(getMongoClientSettingsBuilder() - .timeout(rtt + 400, TimeUnit.MILLISECONDS))) { + .timeout(rtt + applyTimeoutMultiplierForServerless(400), TimeUnit.MILLISECONDS))) { MongoDatabase database = client.getDatabase(gridFsFileNamespace.getDatabaseName()); GridFSBucket gridFsBucket = createReaciveGridFsBucket(database, GRID_FS_BUCKET_NAME); 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 b8f1569bcad..418f874aabe 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java @@ -71,6 +71,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static com.mongodb.ClusterFixture.applyTimeoutMultiplierForServerless; import static com.mongodb.ClusterFixture.getConnectionString; import static com.mongodb.ClusterFixture.isAuthenticated; import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet; @@ -153,7 +154,7 @@ public void testBackgroundConnectionPoolingTimeoutMSUsedForHandshakeCommands() { builder.minSize(1); builder.addConnectionPoolListener(connectionPoolListener); }) - .timeout(100, TimeUnit.MILLISECONDS))) { + .timeout(applyTimeoutMultiplierForServerless(100), TimeUnit.MILLISECONDS))) { assertDoesNotThrow(() -> connectionPoolListener.waitForEvents(asList(ConnectionCreatedEvent.class, ConnectionClosedEvent.class), @@ -188,7 +189,7 @@ public void testBackgroundConnectionPoolingTimeoutMSIsRefreshedForEachHandshakeC builder.minSize(1); builder.addConnectionPoolListener(connectionPoolListener); }) - .timeout(250, TimeUnit.MILLISECONDS))) { + .timeout(applyTimeoutMultiplierForServerless(250), TimeUnit.MILLISECONDS))) { assertDoesNotThrow(() -> connectionPoolListener.waitForEvents(asList(ConnectionCreatedEvent.class, ConnectionReadyEvent.class), @@ -211,12 +212,12 @@ public void testBlockingIterationMethodsTailableCursor() { + " data: {" + " failCommands: [\"getMore\"]," + " blockConnection: true," - + " blockTimeMS: " + 150 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(150) + " }" + "}"); try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder() - .timeout(250, TimeUnit.MILLISECONDS))) { + .timeout(applyTimeoutMultiplierForServerless(250), TimeUnit.MILLISECONDS))) { MongoCollection collection = client.getDatabase(namespace.getDatabaseName()) .getCollection(namespace.getCollectionName()); @@ -243,7 +244,7 @@ public void testBlockingIterationMethodsChangeStream() { BsonTimestamp startTime = new BsonTimestamp((int) Instant.now().getEpochSecond(), 0); collectionHelper.create(namespace.getCollectionName(), new CreateCollectionOptions()); - sleep(2000); + sleep(applyTimeoutMultiplierForServerless(2000)); collectionHelper.insertDocuments(singletonList(BsonDocument.parse("{x: 1}")), WriteConcern.MAJORITY); collectionHelper.runAdminCommand("{" @@ -252,12 +253,12 @@ public void testBlockingIterationMethodsChangeStream() { + " data: {" + " failCommands: [\"getMore\"]," + " blockConnection: true," - + " blockTimeMS: " + 150 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(150) + " }" + "}"); try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder() - .timeout(250, TimeUnit.MILLISECONDS))) { + .timeout(applyTimeoutMultiplierForServerless(250), TimeUnit.MILLISECONDS))) { MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName()) .getCollection(namespace.getCollectionName()).withReadPreference(ReadPreference.primary()); @@ -292,7 +293,7 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() { + " data: {" + " failCommands: [\"insert\"]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 205) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(205)) + " }" + "}"); @@ -300,7 +301,7 @@ public void testGridFSUploadViaOpenUploadStreamTimeout() { filesCollectionHelper.create(); try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder() - .timeout(rtt + 200, TimeUnit.MILLISECONDS))) { + .timeout(rtt + applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS))) { MongoDatabase database = client.getDatabase(namespace.getDatabaseName()); GridFSBucket gridFsBucket = createGridFsBucket(database, GRID_FS_BUCKET_NAME); @@ -323,7 +324,7 @@ public void testAbortingGridFsUploadStreamTimeout() throws Throwable { + " data: {" + " failCommands: [\"delete\"]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 305) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(305)) + " }" + "}"); @@ -331,7 +332,7 @@ public void testAbortingGridFsUploadStreamTimeout() throws Throwable { filesCollectionHelper.create(); try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder() - .timeout(rtt + 300, TimeUnit.MILLISECONDS))) { + .timeout(rtt + applyTimeoutMultiplierForServerless(300), TimeUnit.MILLISECONDS))) { MongoDatabase database = client.getDatabase(namespace.getDatabaseName()); GridFSBucket gridFsBucket = createGridFsBucket(database, GRID_FS_BUCKET_NAME).withChunkSizeBytes(2); @@ -374,12 +375,12 @@ public void testGridFsDownloadStreamTimeout() { + " data: {" + " failCommands: [\"find\"]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 95) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(95)) + " }" + "}"); try (MongoClient client = createMongoClient(getMongoClientSettingsBuilder() - .timeout(rtt + 100, TimeUnit.MILLISECONDS))) { + .timeout(rtt + applyTimeoutMultiplierForServerless(100), TimeUnit.MILLISECONDS))) { MongoDatabase database = client.getDatabase(namespace.getDatabaseName()); GridFSBucket gridFsBucket = createGridFsBucket(database, GRID_FS_BUCKET_NAME).withChunkSizeBytes(2); @@ -472,12 +473,12 @@ public void test9EndSessionClientTimeout() { + " data: {" + " failCommands: [\"abortTransaction\"]," + " blockConnection: true," - + " blockTimeMS: " + 150 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(150) + " }" + "}"); try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder().retryWrites(false) - .timeout(100, TimeUnit.MILLISECONDS))) { + .timeout(applyTimeoutMultiplierForServerless(100), TimeUnit.MILLISECONDS))) { MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName()) .getCollection(namespace.getCollectionName()); @@ -488,7 +489,7 @@ public void test9EndSessionClientTimeout() { long start = System.nanoTime(); session.close(); long elapsed = msElapsedSince(start) - postSessionCloseSleep(); - assertTrue(elapsed <= 150, "Took too long to time out, elapsedMS: " + elapsed); + assertTrue(elapsed <= applyTimeoutMultiplierForServerless(150), "Took too long to time out, elapsedMS: " + elapsed); } } CommandFailedEvent abortTransactionEvent = assertDoesNotThrow(() -> @@ -510,7 +511,7 @@ public void test9EndSessionSessionTimeout() { + " data: {" + " failCommands: [\"abortTransaction\"]," + " blockConnection: true," - + " blockTimeMS: " + 150 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(150) + " }" + "}"); @@ -519,14 +520,14 @@ public void test9EndSessionSessionTimeout() { .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(100, TimeUnit.MILLISECONDS).build())) { + .defaultTimeout(applyTimeoutMultiplierForServerless((100)), 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); + assertTrue(elapsed <= applyTimeoutMultiplierForServerless(150), "Took too long to time out, elapsedMS: " + elapsed); } } CommandFailedEvent abortTransactionEvent = assertDoesNotThrow(() -> @@ -554,10 +555,10 @@ public void test9EndSessionCustomTesEachOperationHasItsOwnTimeoutWithCommit() { .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) { + .defaultTimeout(applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS).build())) { session.startTransaction(); collection.insertOne(session, new Document("x", 1)); - sleep(200); + sleep(applyTimeoutMultiplierForServerless(200)); assertDoesNotThrow(session::commitTransaction); } @@ -585,10 +586,10 @@ public void test9EndSessionCustomTesEachOperationHasItsOwnTimeoutWithAbort() { .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) { + .defaultTimeout(applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS).build())) { session.startTransaction(); collection.insertOne(session, new Document("x", 1)); - sleep(200); + sleep(applyTimeoutMultiplierForServerless(200)); assertDoesNotThrow(session::close); } @@ -608,11 +609,12 @@ public void test10ConvenientTransactions() { + " data: {" + " failCommands: [\"insert\", \"abortTransaction\"]," + " blockConnection: true," - + " blockTimeMS: " + 150 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(150) + " }" + "}"); - try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder().timeout(100, TimeUnit.MILLISECONDS))) { + try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder() + .timeout(applyTimeoutMultiplierForServerless(100), TimeUnit.MILLISECONDS))) { MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName()) .getCollection(namespace.getCollectionName()); @@ -642,7 +644,7 @@ public void test10CustomTestWithTransactionUsesASingleTimeout() { + " data: {" + " failCommands: [\"insert\"]," + " blockConnection: true," - + " blockTimeMS: " + 25 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(25) + " }" + "}"); @@ -651,11 +653,11 @@ public void test10CustomTestWithTransactionUsesASingleTimeout() { .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) { + .defaultTimeout(applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS).build())) { assertThrows(MongoOperationTimeoutException.class, () -> session.withTransaction(() -> { collection.insertOne(session, new Document("x", 1)); - sleep(200); + sleep(applyTimeoutMultiplierForServerless(200)); return true; }) ); @@ -675,7 +677,7 @@ public void test10CustomTestWithTransactionUsesASingleTimeoutWithLock() { + " data: {" + " failCommands: [\"insert\"]," + " blockConnection: true," - + " blockTimeMS: " + 25 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(25) + " errorCode: " + 24 + " errorLabels: [\"TransientTransactionError\"]" + " }" @@ -686,11 +688,11 @@ public void test10CustomTestWithTransactionUsesASingleTimeoutWithLock() { .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(200, TimeUnit.MILLISECONDS).build())) { + .defaultTimeout(applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS).build())) { assertThrows(MongoOperationTimeoutException.class, () -> session.withTransaction(() -> { collection.insertOne(session, new Document("x", 1)); - sleep(200); + sleep(applyTimeoutMultiplierForServerless(200)); return true; }) ); @@ -712,13 +714,13 @@ public void shouldIgnoreWtimeoutMsOfWriteConcernToInitialAndSubsequentCommitTran .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(200, TimeUnit.MILLISECONDS) + .defaultTimeout(applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS) .build())) { session.startTransaction(TransactionOptions.builder() - .writeConcern(WriteConcern.ACKNOWLEDGED.withWTimeout(100, TimeUnit.MILLISECONDS)) + .writeConcern(WriteConcern.ACKNOWLEDGED.withWTimeout(applyTimeoutMultiplierForServerless(100), TimeUnit.MILLISECONDS)) .build()); collection.insertOne(session, new Document("x", 1)); - sleep(200); + sleep(applyTimeoutMultiplierForServerless(200)); assertDoesNotThrow(session::commitTransaction); //repeat commit. @@ -756,13 +758,13 @@ public void testKillCursorsIsNotExecutedAfterGetMoreNetworkErrorWhenTimeoutIsNot + " data: {" + " failCommands: [\"getMore\" ]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 600) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(600)) + " }" + "}"); try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder() .retryReads(true) - .applyToSocketSettings(builder -> builder.readTimeout(500, TimeUnit.MILLISECONDS)))) { + .applyToSocketSettings(builder -> builder.readTimeout(applyTimeoutMultiplierForServerless(500), TimeUnit.MILLISECONDS)))) { MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName()) .getCollection(namespace.getCollectionName()).withReadPreference(ReadPreference.primary()); @@ -803,12 +805,12 @@ public void testKillCursorsIsNotExecutedAfterGetMoreNetworkError() { + " data: {" + " failCommands: [\"getMore\" ]," + " blockConnection: true," - + " blockTimeMS: " + (rtt + 600) + + " blockTimeMS: " + (rtt + applyTimeoutMultiplierForServerless(600)) + " }" + "}"); try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder() - .timeout(500, TimeUnit.MILLISECONDS))) { + .timeout(applyTimeoutMultiplierForServerless(500), TimeUnit.MILLISECONDS))) { MongoCollection collection = mongoClient.getDatabase(namespace.getDatabaseName()) .getCollection(namespace.getCollectionName()).withReadPreference(ReadPreference.primary()); @@ -845,11 +847,11 @@ public void shouldThrowTimeoutExceptionForSubsequentCommitTransaction() { .getCollection(namespace.getCollectionName()); try (ClientSession session = mongoClient.startSession(ClientSessionOptions.builder() - .defaultTimeout(200, TimeUnit.MILLISECONDS) + .defaultTimeout(applyTimeoutMultiplierForServerless(200), TimeUnit.MILLISECONDS) .build())) { session.startTransaction(TransactionOptions.builder().build()); collection.insertOne(session, new Document("x", 1)); - sleep(200); + sleep(applyTimeoutMultiplierForServerless(200)); assertDoesNotThrow(session::commitTransaction); @@ -859,7 +861,7 @@ public void shouldThrowTimeoutExceptionForSubsequentCommitTransaction() { + " data: {" + " failCommands: [\"commitTransaction\"]," + " blockConnection: true," - + " blockTimeMS: " + 500 + + " blockTimeMS: " + applyTimeoutMultiplierForServerless(500) + " }" + "}"); diff --git a/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutTest.java b/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutTest.java index c1a995fef9e..b823c4574c4 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutTest.java @@ -63,6 +63,12 @@ public static void skipOperationTimeoutTests(final String fileDescription, final /* Drivers MUST NOT execute a killCursors command because the pinned connection is no longer under a load balancer. */ assumeFalse(testDescription.equals("timeoutMS is refreshed for close")); + + /* Flaky tests. We have to retry them once we have a Junit5 rule. */ + assumeFalse(testDescription.equals("remaining timeoutMS applied to getMore if timeoutMode is unset")); + assumeFalse(testDescription.equals("remaining timeoutMS applied to getMore if timeoutMode is cursor_lifetime")); + assumeFalse(testDescription.equals("timeoutMS is refreshed for getMore if timeoutMode is iteration - success")); + assumeFalse(testDescription.equals("timeoutMS is refreshed for getMore if timeoutMode is iteration - failure")); } assumeFalse("No maxTimeMS parameter for createIndex() method", testDescription.contains("maxTimeMS is ignored if timeoutMS is set - createIndex on collection")); 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 6d3d134e2fc..31f72ca4332 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 @@ -57,6 +57,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import static com.mongodb.ClusterFixture.applyTimeoutMultiplierForServerless; import static com.mongodb.ClusterFixture.serverVersionAtLeast; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.hamcrest.MatcherAssert.assertThat; @@ -273,7 +274,7 @@ void shouldThrowTimeoutExceptionWhenCreateEncryptedCollection(final String comma assumeTrue(serverVersionAtLeast(7, 0)); //given long rtt = ClusterFixture.getPrimaryRTT(); - long initialTimeoutMS = rtt + 200; + long initialTimeoutMS = rtt + applyTimeoutMultiplierForServerless(200); try (ClientEncryption clientEncryption = createClientEncryption(getClientEncryptionSettingsBuilder() .timeout(initialTimeoutMS, MILLISECONDS))) {