This document describes the tests that drivers MUST run to validate the behavior of the timeoutMS option. These tests are broken up into automated YAML/JSON tests and additional prose tests.
This directory contains a set of YAML and JSON spec tests. Drivers MUST run these as described in the "Unified Test
Runner" specification. Because the tests introduced in this specification are timing-based, there is a risk that some of
them may intermittently fail without any bugs being present in the driver. As a mitigation, drivers MAY execute these
tests in two new Evergreen tasks that use single-node replica sets: one with only authentication enabled and another
with both authentication and TLS enabled. Drivers that choose to do so SHOULD use the single-node-auth.json and
single-node-auth-ssl.json files in the drivers-evergreen-tools repository to create these clusters.
There are some tests that cannot be expressed in the unified YAML/JSON format. For each of these tests, drivers MUST
create a MongoClient without the timeoutMS option set (referred to as internalClient). Any fail points set during a
test MUST be unset using internalClient after the test has been executed. All MongoClient instances created for tests
MUST be configured with read/write concern majority, read preference primary, and command monitoring enabled to
listen for command_started events.
This test MUST only run against standalones on server versions 4.4 and higher. The insertMany call takes an
exceedingly long time on replicasets and sharded clusters. Drivers MAY adjust the timeouts used in this test to allow
for differing bulk encoding performance.
-
Using
internalClient, drop thedb.collcollection. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 2 }, data: { failCommands: ["insert"], blockConnection: true, blockTimeMS: 1010 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=2000. -
Using
client, insert 50 1-megabyte documents in a singleinsertManycall.- Expect this to fail with a timeout error.
-
Verify that two
insertcommands were executed againstdb.collas part of theinsertManycall.
This test MUST only be run against enterprise server versions 4.2 and higher.
- Launch a mongocryptd process on 23000.
- Create a MongoClient (referred to as
client) using the URImongodb://localhost:23000/?timeoutMS=1000. - Using
client, execute the{ ping: 1 }command against theadmindatabase. - Verify via command monitoring that the
pingcommand sent did not contain amaxTimeMSfield.
Each test under this category MUST only be run against server versions 4.4 and higher. In these tests, LOCAL_MASTERKEY
refers to the following base64:
Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk
For each test, perform the following setup:
-
Using
internalClient, drop and create thekeyvault.datakeyscollection. -
Create a MongoClient (referred to as
keyVaultClient) withtimeoutMS=10. -
Create a
ClientEncryptionobject that wrapskeyVaultClient(referred to asclientEncryption). Configure this object withkeyVaultNamespaceset tokeyvault.datakeysand the following KMS providers map:{ "local": { "key": <base64 decoding of LOCAL_MASTERKEY> } }
-
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["insert"], blockConnection: true, blockTimeMS: 15 } }
-
Call
clientEncryption.createDataKey()with thelocalKMS provider.- Expect this to fail with a timeout error.
-
Verify that an
insertcommand was executed against tokeyvault.datakeysas part of thecreateDataKeycall.
-
Call
client_encryption.createDataKey()with thelocalKMS provider.- Expect a BSON binary with subtype 4 to be returned, referred to as
datakeyId.
- Expect a BSON binary with subtype 4 to be returned, referred to as
-
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["find"], blockConnection: true, blockTimeMS: 15 } }
-
Call
clientEncryption.encrypt()with the valuehello, the algorithmAEAD_AES_256_CBC_HMAC_SHA_512-Deterministic, and the keyIddatakeyId.- Expect this to fail with a timeout error.
-
Verify that a
findcommand was executed against thekeyvault.datakeyscollection as part of theencryptcall.
-
Call
clientEncryption.createDataKey()with thelocalKMS provider.- Expect this to return a BSON binary with subtype 4, referred to as
dataKeyId.
- Expect this to return a BSON binary with subtype 4, referred to as
-
Call
clientEncryption.encrypt()with the valuehello, the algorithmAEAD_AES_256_CBC_HMAC_SHA_512-Deterministic, and the keyIddataKeyId.- Expect this to return a BSON binary with subtype 6, referred to as
encrypted.
- Expect this to return a BSON binary with subtype 6, referred to as
-
Close and re-create the
keyVaultClientandclientEncryptionobjects. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["find"], blockConnection: true, blockTimeMS: 15 } }
-
Call
clientEncryption.decrypt()with the valueencrypted.- Expect this to fail with a timeout error.
-
Verify that a
findcommand was executed against thekeyvault.datakeyscollection as part of thedecryptcall.
The tests in this section MUST only be run if the server version is 4.4 or higher and the URI has authentication fields (i.e. a username and password). Each test in this section requires drivers to create a MongoClient and then wait for some CMAP events to be published. Drivers MUST wait for up to 10 seconds and fail the test if the specified events are not published within that time.
-
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["saslContinue"], blockConnection: true, blockTimeMS: 15, appName: "timeoutBackgroundPoolTest" } }
-
Create a MongoClient (referred to as
client) configured with the following:minPoolSizeof 1timeoutMSof 10appNameoftimeoutBackgroundPoolTest- CMAP monitor configured to listen for
ConnectionCreatedEventandConnectionClosedEventevents.
-
Wait for a
ConnectionCreatedEventand aConnectionClosedEventto be published.
-
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: "alwaysOn", data: { failCommands: ["hello", "isMaster", "saslContinue"], blockConnection: true, blockTimeMS: 15, appName: "refreshTimeoutBackgroundPoolTest" } }
-
Create a MongoClient (referred to as
client) configured with the following:minPoolSizeof 1timeoutMSof 20appNameofrefreshTimeoutBackgroundPoolTest- CMAP monitor configured to listen for
ConnectionCreatedEventandConnectionReadyevents.
-
Wait for a
ConnectionCreatedEventand aConnectionReadyto be published.
Tests in this section MUST only be run against server versions 4.4 and higher and only apply to drivers that have a
blocking method for cursor iteration that executes getMore commands in a loop until a document is available or an
error occurs.
-
Using
internalClient, drop thedb.collcollection. -
Using
internalClient, insert the document{ x: 1 }intodb.coll. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: "alwaysOn", data: { failCommands: ["getMore"], blockConnection: true, blockTimeMS: 15 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=20. -
Using
client, create a tailable cursor ondb.collwithcursorType=tailable.- Expect this to succeed and return a cursor with a non-zero ID.
-
Call either a blocking or non-blocking iteration method on the cursor.
- Expect this to succeed and return the document
{ x: 1 }without sending agetMorecommand.
- Expect this to succeed and return the document
-
Call the blocking iteration method on the resulting cursor.
- Expect this to fail with a timeout error.
-
Verify that a
findcommand and twogetMorecommands were executed against thedb.collcollection during the test.
-
Using
internalClient, drop thedb.collcollection. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: "alwaysOn", data: { failCommands: ["getMore"], blockConnection: true, blockTimeMS: 15 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=20. -
Using
client, use thewatchhelper to create a change stream againstdb.coll.- Expect this to succeed and return a change stream with a non-zero ID.
-
Call the blocking iteration method on the resulting change stream.
- Expect this to fail with a timeout error.
-
Verify that an
aggregatecommand and twogetMorecommands were executed against thedb.collcollection during the test.
Tests in this section MUST only be run against server versions 4.4 and higher. Drivers SHOULD apply useMultipleMongoses=false as described in the unified test format when testing on sharded clusters to ensure failpoint are hit by only using one mongos.
-
Using
internalClient, drop and re-create thedb.fs.filesanddb.fs.chunkscollections. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["insert"], blockConnection: true, blockTimeMS: 200 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=150. -
Using
client, create a GridFS bucket (referred to asbucket) that wraps thedbdatabase. -
Call
bucket.open_upload_stream()with the filenamefilenameto create an upload stream (referred to asuploadStream).- Expect this to succeed and return a non-null stream.
-
Using
uploadStream, upload a single0x12byte. -
Call
uploadStream.close()to flush the stream and insert chunks.- Expect this to fail with a timeout error.
This test only applies to drivers that provide an API to abort a GridFS upload stream.
-
Using
internalClient, drop and re-create thedb.fs.filesanddb.fs.chunkscollections. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["delete"], blockConnection: true, blockTimeMS: 200 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=150. -
Using
client, create a GridFS bucket (referred to asbucket) that wraps thedbdatabase withchunkSizeBytes=2. -
Call
bucket.open_upload_stream()with the filenamefilenameto create an upload stream (referred to asuploadStream).- Expect this to succeed and return a non-null stream.
-
Using
uploadStream, upload the bytes[0x01, 0x02, 0x03, 0x04]. -
Call
uploadStream.abort().- Expect this to fail with a timeout error.
This test MUST only be run against server versions 4.4 and higher. Drivers SHOULD apply useMultipleMongoses=false as described in the unified test format when testing on sharded clusters to ensure failpoint are hit by only using one mongos.
-
Using
internalClient, drop and re-create thedb.fs.filesanddb.fs.chunkscollections. -
Using
internalClient, insert the following document into thedb.fs.filescollection:{ "_id": { "$oid": "000000000000000000000005" }, "length": 10, "chunkSize": 4, "uploadDate": { "$date": "1970-01-01T00:00:00.000Z" }, "md5": "57d83cd477bfb1ccd975ab33d827a92b", "filename": "length-10", "contentType": "application/octet-stream", "aliases": [], "metadata": {} }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=150. -
Using
client, create a GridFS bucket (referred to asbucket) that wraps thedbdatabase. -
Call
bucket.open_download_streamwith the id{ "$oid": "000000000000000000000005" }to create a download stream (referred to asdownloadStream).- Expect this to succeed and return a non-null stream.
-
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 1 }, data: { failCommands: ["find"], blockConnection: true, blockTimeMS: 200 } }
-
Read from the
downloadStream.- Expect this to fail with a timeout error.
-
Verify that two
findcommands were executed during the read: one againstdb.fs.filesand another againstdb.fs.chunks.
- Create a MongoClient (referred to as
client) with URImongodb://invalid/?serverSelectionTimeoutMS=10. - Using
client, execute the command{ ping: 1 }against theadmindatabase.- Expect this to fail with a server selection timeout error after no more than 15ms.
- Create a MongoClient (referred to as
client) with URImongodb://invalid/?timeoutMS=10&serverSelectionTimeoutMS=20. - Using
client, run the command{ ping: 1 }against theadmindatabase.- Expect this to fail with a server selection timeout error after no more than 15ms.
- Create a MongoClient (referred to as
client) with URImongodb://invalid/?timeoutMS=20&serverSelectionTimeoutMS=10. - Using
client, run the command{ ping: 1 }against theadmindatabase.- Expect this to fail with a server selection timeout error after no more than 15ms.
- Create a MongoClient (referred to as
client) with URImongodb://invalid/?timeoutMS=0&serverSelectionTimeoutMS=10. - Using
client, run the command{ ping: 1 }against theadmindatabase.- Expect this to fail with a server selection timeout error after no more than 15ms.
This test MUST only be run if the server version is 4.4 or higher and the URI has authentication fields (i.e. a username and password).
-
Using
internalClient, set the following fail point:{ configureFailPoint: failCommand, mode: { times: 1 }, data: { failCommands: ["saslContinue"], blockConnection: true, blockTimeMS: 15 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=10andserverSelectionTimeoutMS=20. -
Using
client, insert the document{ x: 1 }into collectiondb.coll.- Expect this to fail with a timeout error after no more than 15ms.
This test MUST only be run if the server version is 4.4 or higher and the URI has authentication fields (i.e. a username and password).
-
Using
internalClient, set the following fail point:{ configureFailPoint: failCommand, mode: { times: 1 }, data: { failCommands: ["saslContinue"], blockConnection: true, blockTimeMS: 15 } }
-
Create a new MongoClient (referred to as
client) withtimeoutMS=20andserverSelectionTimeoutMS=10. -
Using
client, insert the document{ x: 1 }into collectiondb.coll.- Expect this to fail with a timeout error after no more than 15ms.
This test MUST only be run against replica sets and sharded clusters with server version 4.4 or higher. It MUST be run
three times: once with the timeout specified via the MongoClient timeoutMS option, once with the timeout specified via
the ClientSession defaultTimeoutMS option, and once more with the timeout specified via the timeoutMS option for the
endSession operation. In all cases, the timeout MUST be set to 150 milliseconds.
-
Using
internalClient, drop thedb.collcollection. -
Using
internalClient, set the following fail point:{ configureFailPoint: failCommand, mode: { times: 1 }, data: { failCommands: ["abortTransaction"], blockConnection: true, blockTimeMS: 200 } }
-
Create a new MongoClient (referred to as
client) and an explicit ClientSession derived from that MongoClient (referred to assession). -
Execute the following code:
coll = client.database("db").collection("coll") session.start_transaction() coll.insert_one({x: 1}, session=session)
-
Using
session, executesession.end_session- Expect this to fail with a timeout error after no more than 150ms.
Tests in this section MUST only run against replica sets and sharded clusters with server versions 4.4 or higher.
-
Using
internalClient, drop thedb.collcollection. -
Using
internalClient, set the following fail point:{ configureFailPoint: failCommand, mode: { times: 2 }, data: { failCommands: ["insert", "abortTransaction"], blockConnection: true, blockTimeMS: 200 } }
-
Create a new MongoClient (referred to as
client) configured withtimeoutMS=150and an explicit ClientSession derived from that MongoClient (referred to assession). -
Using
session, execute awithTransactionoperation with the following callback:def callback() { coll = client.database("db").collection("coll") coll.insert_one({ _id: 1 }, session=session) }
-
Expect the previous
withTransactioncall to fail with a timeout error. -
Verify that the following events were published during the
withTransactioncall:command_startedandcommand_failedevents for aninsertcommand.command_startedandcommand_failedevents for anabortTransactioncommand.
This test MUST only run against server versions 8.0+. This test must be skipped on Atlas Serverless.
This test MUST only run against standalones. The bulkWrite call takes an exceedingly long time on replicasets and sharded clusters. Drivers MAY adjust the timeouts used in this test to allow for differing bulk encoding performance.
-
Using
internalClient, drop thedb.collcollection. -
Using
internalClient, set the following fail point:{ configureFailPoint: "failCommand", mode: { times: 2 }, data: { failCommands: ["bulkWrite"], blockConnection: true, blockTimeMS: 1010 } }
-
Using
internalClient, perform ahellocommand and record themaxBsonObjectSizeandmaxMessageSizeBytesvalues in the response. -
Create a new MongoClient (referred to as
client) withtimeoutMS=2000. -
Create a list of write models (referred to as
models) with the following write model repeated (maxMessageSizeBytes / maxBsonObjectSize + 1) times:InsertOne { "namespace": "db.coll", "document": { "a": "b".repeat(maxBsonObjectSize - 500) } }
-
Call
bulkWriteonclientwithmodels.- Expect this to fail with a timeout error.
-
Verify that two
bulkWritecommands were executed as part of theMongoClient.bulkWritecall.
The tests enumerated in this section could not be expressed in either spec or prose format. Drivers SHOULD implement these if it is possible to do so using the driver's existing test infrastructure.
- Operations should ignore
waitQueueTimeoutMSiftimeoutMSis also set. - If
timeoutMSis set for an operation, the remainingtimeoutMSvalue should apply to connection checkout after a server has been selected. - If
timeoutMSis not set for an operation,waitQueueTimeoutMSshould apply to connection checkout after a server has been selected. - If a new connection is required to execute an operation,
min(remaining computedServerSelectionTimeout, connectTimeoutMS)should apply to socket establishment. - For drivers that have control over OCSP behavior,
min(remaining computedServerSelectionTimeout, 5 seconds)should apply to HTTP requests against OCSP responders. - The remaining
timeoutMSvalue should apply to HTTP requests against KMS servers for CSFLE. - The remaining
timeoutMSvalue should apply to commands sent to mongocryptd as part of automatic encryption. - When doing
minPoolSizemaintenance,connectTimeoutMSis used as the timeout for socket establishment.