diff --git a/test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.js b/test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.js deleted file mode 100644 index 3feb4e5183..0000000000 --- a/test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict'; -const { TestRunnerContext, generateTopologyTests } = require('../../tools/spec-runner'); -const { loadSpecTests } = require('../../spec'); - -class SDAMRunnerContext extends TestRunnerContext { - constructor() { - super(); - - this.currentPrimary = null; - } - - configureFailPoint(args) { - return this.enableFailPoint(args.failPoint); - } - - recordPrimary(client) { - const servers = client.topology.description.servers; - const primary = Array.from(servers.values()).filter(sd => sd.type === 'RSPrimary')[0]; - this.currentPrimary = primary.address; - } - - waitForPrimaryChange(client) { - const currentPrimary = this.currentPrimary; - - return new Promise(resolve => { - function eventHandler(event) { - if ( - event.newDescription.type === 'RSPrimary' && - event.newDescription.address !== currentPrimary - ) { - resolve(); - client.removeListener('serverDescriptionChanged', eventHandler); - } - } - - client.on('serverDescriptionChanged', eventHandler); - }); - } -} - -// 'TODO: NODE-3891 - fix tests broken when AUTH enabled' -// Some tests are failing when setting a failCommand when auth is enabled. -const isAuthEnabled = process.env.AUTH === 'auth'; -const failpointTests = [ - 'Reset server and pool after AuthenticationFailure error', - 'Reset server and pool after misc command error', - 'Reset server and pool after network error during authentication', - 'Reset server and pool after network timeout error during authentication', - 'Reset server and pool after shutdown error during authentication' -]; -const skippedTests = [...(isAuthEnabled ? failpointTests : []), 'Network error on Monitor check']; - -function sdamDisabledTestFilter(test) { - const { description } = test; - return !skippedTests.includes(description); -} - -describe('SDAM', function () { - describe('integration spec tests', function () { - const testContext = new SDAMRunnerContext(); - const testSuites = loadSpecTests('server-discovery-and-monitoring/integration'); - - beforeEach(async function () { - if (this.configuration.isLoadBalanced) { - this.currentTest.skipReason = 'Cannot run in a loadBalanced environment'; - this.skip(); - } - }); - - beforeEach(async function () { - await testContext.setup(this.configuration); - }); - - afterEach(async () => { - await testContext.teardown(); - }); - - generateTopologyTests(testSuites, testContext, sdamDisabledTestFilter); - }); -}); diff --git a/test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.ts b/test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.ts new file mode 100644 index 0000000000..84e3289e62 --- /dev/null +++ b/test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { Socket } from 'net'; +import * as path from 'path'; + +import { loadSpecTests } from '../../spec'; +import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner'; +import { TestFilter } from '../../tools/unified-spec-runner/schema'; +import { sleep } from '../../tools/utils'; + +const filter: TestFilter = ({ description }) => { + const isAuthEnabled = process.env.AUTH === 'auth'; + switch (description) { + case 'Reset server and pool after AuthenticationFailure error': + case 'Reset server and pool after misc command error': + case 'Reset server and pool after network error during authentication': + case 'Reset server and pool after network timeout error during authentication': + case 'Reset server and pool after shutdown error during authentication': + // These tests time out waiting for the PoolCleared event + return isAuthEnabled ? 'TODO(NODE-3891): fix tests broken when AUTH enabled' : false; + case 'Network error on minPoolSize background creation': + return 'TODO(NODE-4385): implement pool pausing and pool ready event'; + default: + return false; + } +}; + +describe('SDAM Unified Tests', function () { + afterEach(async function () { + // TODO(NODE-4573): fix socket leaks + const LEAKY_TESTS = [ + 'Command error on Monitor handshake', + 'Network error on Monitor check', + 'Network timeout on Monitor check', + 'Network error on Monitor handshake', + 'Network timeout on Monitor handshake' + ]; + + await sleep(250); + const sockArray = (process as any)._getActiveHandles().filter(handle => { + // Stdio are instanceof Socket so look for fd to be null + return handle.fd == null && handle instanceof Socket && handle.destroyed !== true; + }); + if (!sockArray.length) { + return; + } + for (const sock of sockArray) { + sock.destroy(); + } + if (!LEAKY_TESTS.some(test => test === this.currentTest!.title)) { + this.test!.error(new Error(`Test failed to clean up ${sockArray.length} socket(s)`)); + } + }); + runUnifiedSuite(loadSpecTests(path.join('server-discovery-and-monitoring', 'unified')), filter); +}); diff --git a/test/spec/server-discovery-and-monitoring/README.rst b/test/spec/server-discovery-and-monitoring/README.rst index 7dcaaa8fa5..caadb9b4b6 100644 --- a/test/spec/server-discovery-and-monitoring/README.rst +++ b/test/spec/server-discovery-and-monitoring/README.rst @@ -188,196 +188,9 @@ Continue until all phases have been executed. Integration Tests ----------------- -Integration tests are provided in the "integration" directory. - -Test Format -~~~~~~~~~~~ - -The same as the `Transactions Spec Test format -`_ with the following -additions: - -- The ``runOn`` requirement gains a new field: - - - ``authEnabled`` (optional): If True, skip this test if auth is not enabled. - If False, skip this test if auth is enabled. If this field is omitted, - this test can be run on clusters with or without auth. - -Special Test Operations -~~~~~~~~~~~~~~~~~~~~~~~ - -Certain operations that appear in the "operations" array do not correspond to -API methods but instead represent special test operations. Such operations are -defined on the "testRunner" object and are documented in the -`Transactions Spec Test -`_. - -Additional, SDAM test specific operations are documented here: - -configureFailPoint -'''''''''''''''''' - -The "configureFailPoint" operation instructs the test runner to configure -the given server failpoint on the "admin" database. The runner MUST disable -this failpoint at the end of the test. For example:: - - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["insert"] - closeConnection: true - -Tests that use the "configureFailPoint" operation do not include -``configureFailPoint`` commands in their command expectations. Drivers MUST -ensure that ``configureFailPoint`` commands do not appear in the list of logged -commands, either by manually filtering it from the list of observed commands or -by using a different MongoClient to execute ``configureFailPoint``. - -Note, similar to the ``tests.failPoint`` field described in the `Transactions -Spec Test format `_ tests -with ``useMultipleMongoses: true`` will not contain a ``configureFailPoint`` -operation. - -wait -'''' - -The "wait" operation instructs the test runner to sleep for "ms" -milliseconds. For example:: - - - name: wait - object: testRunner - arguments: - ms: 1000 - -waitForEvent -'''''''''''' - -The "waitForEvent" operation instructs the test runner to wait until the test's -MongoClient has published a specific event a given number of times. For -example, the following instructs the test runner to wait for at least one -PoolClearedEvent to be published:: - - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - -Note that "count" includes events that were published while running previous -operations. - -If the "waitForEvent" operation is not satisfied after 10 seconds, the -operation is considered an error. - -ServerMarkedUnknownEvent -```````````````````````` - -The ServerMarkedUnknownEvent may appear as an event in `waitForEvent`_ and -`assertEventCount`_. This event is defined as ServerDescriptionChangedEvent -where newDescription.type is ``Unknown``. - -assertEventCount -'''''''''''''''' - -The "assertEventCount" operation instructs the test runner to assert the test's -MongoClient has published a specific event a given number of times. For -example, the following instructs the test runner to assert that a single -PoolClearedEvent was published:: - - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - -recordPrimary -''''''''''''' - -The "recordPrimary" operation instructs the test runner to record the current -primary of the test's MongoClient. For example:: - - - name: recordPrimary - object: testRunner - -runAdminCommand -''''''''''''''' - -The "runAdminCommand" operation instructs the test runner to run the given -command on the admin database. Drivers MUST run this command on a different -MongoClient from the one used for test operations. For example:: - - - name: runAdminCommand - object: testRunner - command_name: replSetFreeze - arguments: - command: - replSetFreeze: 0 - readPreference: - mode: Secondary - -waitForPrimaryChange -'''''''''''''''''''' - -The "waitForPrimaryChange" operation instructs the test runner to wait up to -"timeoutMS" milliseconds for the MongoClient to discover a new primary server. -The new primary should be different from the one recorded by "recordPrimary". -For example:: - - - name: waitForPrimaryChange - object: testRunner - arguments: - timeoutMS: 15000 - -To implement, Drivers can subscribe to ServerDescriptionChangedEvents and wait -for an event where newDescription.type is ``RSPrimary`` and the address is -different from the one previously recorded by "recordPrimary". - -startThread -''''''''''' - -The "startThread" operation instructs the test runner to start a new thread -with the provided "name". The `runOnThread`_ and `waitForThread`_ operations -reference a thread by its "name". For example:: - - - name: startThread - object: testRunner - arguments: - name: thread1 - -runOnThread -''''''''''' - -The "runOnThread" operation instructs the test runner to schedule an operation -to be run on the given thread. runOnThread MUST NOT wait for the scheduled -operation to complete. For example:: - - - name: runOnThread - object: testRunner - arguments: - name: thread1 - operation: - name: insertOne - object: collection - arguments: - document: - _id: 2 - error: true - -waitForThread -''''''''''''' - -The "waitForThread" operation instructs the test runner to stop the given -thread, wait for it to complete, and assert that the thread exited without -any errors. For example:: - - - name: waitForThread - object: testRunner - arguments: - name: thread1 +Integration tests are provided in the "unified" directory and are +written in the `Unified Test Format +<../unified-test-format/unified-test-format.rst>`_. Prose Tests ----------- diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-error.json b/test/spec/server-discovery-and-monitoring/integration/auth-error.json deleted file mode 100644 index 064d660e32..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-error.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4", - "authEnabled": true - } - ], - "database_name": "sdam-tests", - "collection_name": "auth-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after AuthenticationFailure error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "saslContinue" - ], - "appName": "authErrorTest", - "errorCode": 18 - } - }, - "clientOptions": { - "retryWrites": false, - "appname": "authErrorTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "auth-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-error.yml b/test/spec/server-discovery-and-monitoring/integration/auth-error.yml deleted file mode 100644 index 9c646543e0..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-error.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - authEnabled: true - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "auth-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after AuthenticationFailure error - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["saslContinue"] - appName: authErrorTest - errorCode: 18 # AuthenticationFailure - clientOptions: - retryWrites: false - appname: authErrorTest - operations: - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - # Note: The first insert command is never attempted because connection - # checkout fails. - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-misc-command-error.json b/test/spec/server-discovery-and-monitoring/integration/auth-misc-command-error.json deleted file mode 100644 index 70dd59251d..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-misc-command-error.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4", - "authEnabled": true - } - ], - "database_name": "sdam-tests", - "collection_name": "auth-misc-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after misc command error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "saslContinue" - ], - "appName": "authMiscErrorTest", - "errorCode": 1 - } - }, - "clientOptions": { - "retryWrites": false, - "appname": "authMiscErrorTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "auth-misc-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-misc-command-error.yml b/test/spec/server-discovery-and-monitoring/integration/auth-misc-command-error.yml deleted file mode 100644 index 20eae4533e..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-misc-command-error.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - authEnabled: true - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "auth-misc-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after misc command error - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["saslContinue"] - appName: authMiscErrorTest - errorCode: 1 # InternalError - clientOptions: - retryWrites: false - appname: authMiscErrorTest - operations: - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - # Note: The first insert command is never attempted because connection - # checkout fails. - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-network-error.json b/test/spec/server-discovery-and-monitoring/integration/auth-network-error.json deleted file mode 100644 index a75a398c5e..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-network-error.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4", - "authEnabled": true - } - ], - "database_name": "sdam-tests", - "collection_name": "auth-network-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after network error during authentication", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "saslContinue" - ], - "closeConnection": true, - "appName": "authNetworkErrorTest" - } - }, - "clientOptions": { - "retryWrites": false, - "appname": "authNetworkErrorTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "auth-network-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-network-error.yml b/test/spec/server-discovery-and-monitoring/integration/auth-network-error.yml deleted file mode 100644 index abb2b1471e..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-network-error.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - authEnabled: true - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "auth-network-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after network error during authentication - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["saslContinue"] - closeConnection: true - appName: authNetworkErrorTest - clientOptions: - retryWrites: false - appname: authNetworkErrorTest - operations: - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - # Note: The first insert command is never attempted because connection - # checkout fails. - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-network-timeout-error.json b/test/spec/server-discovery-and-monitoring/integration/auth-network-timeout-error.json deleted file mode 100644 index a4ee7d9eff..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-network-timeout-error.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4", - "authEnabled": true - } - ], - "database_name": "sdam-tests", - "collection_name": "auth-network-timeout-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after network timeout error during authentication", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "saslContinue" - ], - "blockConnection": true, - "blockTimeMS": 500, - "appName": "authNetworkTimeoutErrorTest" - } - }, - "clientOptions": { - "retryWrites": false, - "appname": "authNetworkTimeoutErrorTest", - "connectTimeoutMS": 250, - "socketTimeoutMS": 250 - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "auth-network-timeout-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-network-timeout-error.yml b/test/spec/server-discovery-and-monitoring/integration/auth-network-timeout-error.yml deleted file mode 100644 index e065ec5abf..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-network-timeout-error.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - authEnabled: true - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "auth-network-timeout-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after network timeout error during authentication - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["saslContinue"] - blockConnection: true - blockTimeMS: 500 - appName: authNetworkTimeoutErrorTest - clientOptions: - retryWrites: false - appname: authNetworkTimeoutErrorTest - # Set a short connect/socket timeout to ensure the fail point causes the - # connection establishment to timeout. - connectTimeoutMS: 250 - socketTimeoutMS: 250 - operations: - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - # Note: The first insert command is never attempted because connection - # checkout fails. - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-shutdown-error.json b/test/spec/server-discovery-and-monitoring/integration/auth-shutdown-error.json deleted file mode 100644 index 2dab90e1c5..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-shutdown-error.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4", - "authEnabled": true - } - ], - "database_name": "sdam-tests", - "collection_name": "auth-shutdown-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after shutdown error during authentication", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "saslContinue" - ], - "appName": "authShutdownErrorTest", - "errorCode": 91 - } - }, - "clientOptions": { - "retryWrites": false, - "appname": "authShutdownErrorTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "auth-shutdown-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/auth-shutdown-error.yml b/test/spec/server-discovery-and-monitoring/integration/auth-shutdown-error.yml deleted file mode 100644 index 4efe25f3be..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/auth-shutdown-error.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - authEnabled: true - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "auth-shutdown-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after shutdown error during authentication - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["saslContinue"] - appName: authShutdownErrorTest - errorCode: 91 - clientOptions: - retryWrites: false - appname: authShutdownErrorTest - operations: - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - # Note: The first insert command is never attempted because connection - # checkout fails. - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/cancel-server-check.json b/test/spec/server-discovery-and-monitoring/integration/cancel-server-check.json deleted file mode 100644 index 9586350959..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/cancel-server-check.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.2", - "topology": [ - "sharded" - ] - } - ], - "database_name": "sdam-tests", - "collection_name": "cancel-server-check", - "data": [], - "tests": [ - { - "description": "Cancel server check", - "clientOptions": { - "retryWrites": true, - "heartbeatFrequencyMS": 10000, - "serverSelectionTimeoutMS": 5000, - "appname": "cancelServerCheckTest" - }, - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 1 - } - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - } - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/cancel-server-check.yml b/test/spec/server-discovery-and-monitoring/integration/cancel-server-check.yml deleted file mode 100644 index 2a759a8452..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/cancel-server-check.yml +++ /dev/null @@ -1,96 +0,0 @@ -# Test SDAM error handling. -runOn: - # General failCommand requirements (this file does not use appName - # with failCommand). - - minServerVersion: "4.0" - topology: ["replicaset"] - - minServerVersion: "4.2" - topology: ["sharded"] - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "cancel-server-check" - -data: [] - -tests: - - description: Cancel server check - clientOptions: - retryWrites: true - heartbeatFrequencyMS: 10000 - # Server selection timeout MUST be less than heartbeatFrequencyMS for - # this test. This setting ensures that the retried insert will fail - # after 5 seconds if the driver does not properly cancel the in progress - # check. - serverSelectionTimeoutMS: 5000 - appname: cancelServerCheckTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertOne - object: collection - arguments: - document: - _id: 1 - # Configure the next inserts to fail with a non-timeout network error. - # This should: - # 1) Mark the server Unknown - # 2) Clear the connection pool - # 3) Cancel the in progress hello or legacy hello check and close the Monitor - # connection - # 4) The write will be then we retried, server selection will request an - # immediate check, and block for ~500ms until the next Monitor check - # proceeds. - # 5) The write will succeed on the second attempt. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["insert"] - closeConnection: True - - name: insertOne - object: collection - arguments: - document: - _id: 2 - result: - insertedId: 2 - # The first error should mark the server Unknown and then clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node still selectable. - - name: insertOne - object: collection - arguments: - document: - _id: 3 - result: - insertedId: 3 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - # Order of operations is non-deterministic so we cannot check events. - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} diff --git a/test/spec/server-discovery-and-monitoring/integration/connectTimeoutMS.json b/test/spec/server-discovery-and-monitoring/integration/connectTimeoutMS.json deleted file mode 100644 index 36a6dc4507..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/connectTimeoutMS.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "connectTimeoutMS", - "data": [], - "tests": [ - { - "description": "connectTimeoutMS=0", - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 0, - "heartbeatFrequencyMS": 500, - "appname": "connectTimeoutMS=0" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "connectTimeoutMS=0", - "blockConnection": true, - "blockTimeMS": 550 - } - } - } - }, - { - "name": "wait", - "object": "testRunner", - "arguments": { - "ms": 750 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 0 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "connectTimeoutMS", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "connectTimeoutMS", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/connectTimeoutMS.yml b/test/spec/server-discovery-and-monitoring/integration/connectTimeoutMS.yml deleted file mode 100644 index 3ee4d32926..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/connectTimeoutMS.yml +++ /dev/null @@ -1,88 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "connectTimeoutMS" - -data: [] - -tests: - - description: connectTimeoutMS=0 - clientOptions: - retryWrites: false - connectTimeoutMS: 0 - heartbeatFrequencyMS: 500 - appname: connectTimeoutMS=0 - operations: - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # Block the next streaming hello check for longer than - # heartbeatFrequencyMS to ensure that the connection timeout remains - # unlimited. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: connectTimeoutMS=0 - blockConnection: true - blockTimeMS: 550 - - name: wait - object: testRunner - arguments: - ms: 750 - # Perform an operation to ensure the node is still selectable. - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - # Assert that the server was never marked Unknown and the pool was never - # cleared. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 0 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 0 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} diff --git a/test/spec/server-discovery-and-monitoring/integration/find-network-error.json b/test/spec/server-discovery-and-monitoring/integration/find-network-error.json deleted file mode 100644 index 4db2634cd6..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/find-network-error.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "find-network-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after network error on find", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "closeConnection": true, - "appName": "findNetworkErrorTest" - } - }, - "clientOptions": { - "retryWrites": false, - "retryReads": false, - "appname": "findNetworkErrorTest" - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "find-network-error" - }, - "command_name": "find", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "find-network-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/find-network-error.yml b/test/spec/server-discovery-and-monitoring/integration/find-network-error.yml deleted file mode 100644 index 1f505428dd..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/find-network-error.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "find-network-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after network error on find - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["find"] - closeConnection: true - appName: findNetworkErrorTest - clientOptions: - retryWrites: false - retryReads: false - appname: findNetworkErrorTest - operations: - - name: find - object: collection - arguments: - filter: - _id: 1 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - - command_started_event: - command: - find: *collection_name - command_name: find - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/find-network-timeout-error.json b/test/spec/server-discovery-and-monitoring/integration/find-network-timeout-error.json deleted file mode 100644 index c4e10b3a76..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/find-network-timeout-error.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "find-network-timeout-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Ignore network timeout error on find", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "find" - ], - "blockConnection": true, - "blockTimeMS": 500, - "appName": "findNetworkTimeoutErrorTest" - } - }, - "clientOptions": { - "retryWrites": false, - "retryReads": false, - "appname": "findNetworkTimeoutErrorTest", - "socketTimeoutMS": 250 - }, - "operations": [ - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 3 - } - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 0 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "find": "find-network-timeout-error" - }, - "command_name": "find", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "find-network-timeout-error", - "documents": [ - { - "_id": 3 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/find-network-timeout-error.yml b/test/spec/server-discovery-and-monitoring/integration/find-network-timeout-error.yml deleted file mode 100644 index d4ce8e39a7..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/find-network-timeout-error.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "find-network-timeout-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Ignore network timeout error on find - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["find"] - blockConnection: true - blockTimeMS: 500 - appName: findNetworkTimeoutErrorTest - clientOptions: - retryWrites: false - retryReads: false - appname: findNetworkTimeoutErrorTest - # Set a short socket timeout to ensure the find command times out. - socketTimeoutMS: 250 - operations: - - name: find - object: collection - arguments: - filter: - _id: 1 - error: true - # Perform another operation to ensure the node is still usable. - - name: insertOne - object: collection - arguments: - document: - _id: 3 - # Assert the server was not marked Unknown and the pool was not cleared. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 0 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 0 - - expectations: - - command_started_event: - command: - find: *collection_name - command_name: find - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} diff --git a/test/spec/server-discovery-and-monitoring/integration/find-shutdown-error.json b/test/spec/server-discovery-and-monitoring/integration/find-shutdown-error.json deleted file mode 100644 index 65de8398b1..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/find-shutdown-error.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "find-shutdown-error", - "data": [], - "tests": [ - { - "description": "Concurrent shutdown error on find", - "clientOptions": { - "retryWrites": false, - "retryReads": false, - "heartbeatFrequencyMS": 500, - "appname": "shutdownErrorFindTest" - }, - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 1 - } - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "find" - ], - "appName": "shutdownErrorFindTest", - "errorCode": 91, - "blockConnection": true, - "blockTimeMS": 500 - } - } - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread1" - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread2" - } - }, - { - "name": "runOnThread", - "object": "testRunner", - "arguments": { - "name": "thread1", - "operation": { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - } - } - }, - { - "name": "runOnThread", - "object": "testRunner", - "arguments": { - "name": "thread2", - "operation": { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "_id": 1 - } - }, - "error": true - } - } - }, - { - "name": "waitForThread", - "object": "testRunner", - "arguments": { - "name": "thread1" - } - }, - { - "name": "waitForThread", - "object": "testRunner", - "arguments": { - "name": "thread2" - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 4 - } - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/find-shutdown-error.yml b/test/spec/server-discovery-and-monitoring/integration/find-shutdown-error.yml deleted file mode 100644 index bf52313738..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/find-shutdown-error.yml +++ /dev/null @@ -1,116 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "find-shutdown-error" - -data: [] - -tests: - - description: Concurrent shutdown error on find - clientOptions: - retryWrites: false - retryReads: false - heartbeatFrequencyMS: 500 - appname: shutdownErrorFindTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertOne - object: collection - arguments: - document: - _id: 1 - # Configure the next two finds to fail with a non-timeout shutdown - # errors. Block the connection for 500ms to ensure both operations check - # out connections from the same pool generation. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["find"] - appName: shutdownErrorFindTest - errorCode: 91 - blockConnection: true - blockTimeMS: 500 - # Start threads. - - name: startThread - object: testRunner - arguments: - name: thread1 - - name: startThread - object: testRunner - arguments: - name: thread2 - # Perform concurrent find operations. Both fail with shutdown errors. - - name: runOnThread - object: testRunner - arguments: - name: thread1 - operation: - name: find - object: collection - arguments: - filter: - _id: 1 - error: true - - name: runOnThread - object: testRunner - arguments: - name: thread2 - operation: - name: find - object: collection - arguments: - filter: - _id: 1 - error: true - # Stop threads. - - name: waitForThread - object: testRunner - arguments: - name: thread1 - - name: waitForThread - object: testRunner - arguments: - name: thread2 - # The first shutdown error should mark the server Unknown and then clear - # the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform an operation to ensure the node is rediscovered. - - name: insertOne - object: collection - arguments: - document: - _id: 4 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - # Order of operations is non-deterministic so we cannot check events. - outcome: - collection: - data: - - {_id: 1} - - {_id: 4} diff --git a/test/spec/server-discovery-and-monitoring/integration/hello-command-error.json b/test/spec/server-discovery-and-monitoring/integration/hello-command-error.json deleted file mode 100644 index 05a93e751c..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/hello-command-error.json +++ /dev/null @@ -1,239 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.9" - } - ], - "database_name": "sdam-tests", - "collection_name": "hello-command-error", - "data": [], - "tests": [ - { - "description": "Command error on Monitor handshake", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "commandErrorHandshakeTest", - "closeConnection": false, - "errorCode": 91 - } - }, - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 250, - "heartbeatFrequencyMS": 500, - "appname": "commandErrorHandshakeTest" - }, - "operations": [ - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-command-error", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "Command error on Monitor check", - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 1000, - "heartbeatFrequencyMS": 500, - "appname": "commandErrorCheckTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "commandErrorCheckTest", - "closeConnection": false, - "blockConnection": true, - "blockTimeMS": 750, - "errorCode": 91 - } - } - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-command-error", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "hello-command-error", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/hello-command-error.yml b/test/spec/server-discovery-and-monitoring/integration/hello-command-error.yml deleted file mode 100644 index ae25e4946c..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/hello-command-error.yml +++ /dev/null @@ -1,158 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.9" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "hello-command-error" - -data: [] - -tests: - - description: Command error on Monitor handshake - # Configure the initial handshake to fail with a command error. - # Use times: 2 so that the RTT hello fails as well. - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: commandErrorHandshakeTest - closeConnection: false - errorCode: 91 # ShutdownInProgress - clientOptions: - retryWrites: false - connectTimeoutMS: 250 - heartbeatFrequencyMS: 500 - appname: commandErrorHandshakeTest - operations: - # The command error on the initial handshake should mark the server - # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # We cannot assert the server was marked Unknown and pool was cleared an - # exact number of times because the RTT hello may or may not have - # triggered this failpoint as well. - # - name: assertEventCount - # object: testRunner - # arguments: - # event: ServerMarkedUnknownEvent - # count: 1 - # - name: assertEventCount - # object: testRunner - # arguments: - # event: PoolClearedEvent - # count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - - description: Command error on Monitor check - clientOptions: - retryWrites: false - connectTimeoutMS: 1000 - heartbeatFrequencyMS: 500 - appname: commandErrorCheckTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # Configure the next streaming hello check to fail with a command - # error. - # Use times: 2 so that the RTT hello is blocked as well. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: commandErrorCheckTest - closeConnection: false - blockConnection: true - blockTimeMS: 750 - errorCode: 91 # ShutdownInProgress - # The command error on the next check should mark the server Unknown and - # clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform an operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} diff --git a/test/spec/server-discovery-and-monitoring/integration/hello-network-error.json b/test/spec/server-discovery-and-monitoring/integration/hello-network-error.json deleted file mode 100644 index b699363923..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/hello-network-error.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.9" - } - ], - "database_name": "sdam-tests", - "collection_name": "hello-network-error", - "data": [], - "tests": [ - { - "description": "Network error on Monitor handshake", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "networkErrorHandshakeTest", - "closeConnection": true - } - }, - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 250, - "heartbeatFrequencyMS": 500, - "appname": "networkErrorHandshakeTest" - }, - "operations": [ - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-network-error", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "Network error on Monitor check", - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 250, - "heartbeatFrequencyMS": 500, - "appname": "networkErrorCheckTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "networkErrorCheckTest", - "closeConnection": true - } - } - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-network-error", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "hello-network-error", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/hello-network-error.yml b/test/spec/server-discovery-and-monitoring/integration/hello-network-error.yml deleted file mode 100644 index 54c6a3bac3..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/hello-network-error.yml +++ /dev/null @@ -1,156 +0,0 @@ -#hello Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.9" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "hello-network-error" - -data: [] - -tests: - - description: Network error on Monitor handshake - # Configure the initial handshake to fail with a network error. - # Use times: 2 so that the RTT hello fails as well. - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: networkErrorHandshakeTest - closeConnection: true - clientOptions: - retryWrites: false - connectTimeoutMS: 250 - heartbeatFrequencyMS: 500 - appname: networkErrorHandshakeTest - operations: - # The network error on the initial handshake should mark the server - # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # We cannot assert the server was marked Unknown and pool was cleared an - # exact number of times because the RTT hello may or may not have - # triggered this failpoint as well. - # - name: assertEventCount - # object: testRunner - # arguments: - # event: ServerMarkedUnknownEvent - # count: 1 - # - name: assertEventCount - # object: testRunner - # arguments: - # event: PoolClearedEvent - # count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - - description: Network error on Monitor check - clientOptions: - retryWrites: false - connectTimeoutMS: 250 - heartbeatFrequencyMS: 500 - appname: networkErrorCheckTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # Configure the next streaming hello check to fail with a non-timeout - # network error. Use times: 2 to ensure that the the Monitor check fails - # since the RTT hello may trigger this failpoint as well. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: networkErrorCheckTest - closeConnection: true - # The network error on the next check should mark the server Unknown and - # clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform an operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - # We cannot assert the server was marked Unknown and pool was cleared an - # exact number of times because the RTT hello may or may not have - # triggered this failpoint as well. - # - name: assertEventCount - # object: testRunner - # arguments: - # event: ServerMarkedUnknownEvent - # count: 1 - # - name: assertEventCount - # object: testRunner - # arguments: - # event: PoolClearedEvent - # count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} diff --git a/test/spec/server-discovery-and-monitoring/integration/hello-timeout.json b/test/spec/server-discovery-and-monitoring/integration/hello-timeout.json deleted file mode 100644 index 7bdc61a912..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/hello-timeout.json +++ /dev/null @@ -1,353 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "hello-timeout", - "data": [], - "tests": [ - { - "description": "Network timeout on Monitor handshake", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "timeoutMonitorHandshakeTest", - "blockConnection": true, - "blockTimeMS": 1000 - } - }, - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 250, - "heartbeatFrequencyMS": 500, - "appname": "timeoutMonitorHandshakeTest" - }, - "operations": [ - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-timeout", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "Network timeout on Monitor check", - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 750, - "heartbeatFrequencyMS": 500, - "appname": "timeoutMonitorCheckTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "timeoutMonitorCheckTest", - "blockConnection": true, - "blockTimeMS": 1000 - } - } - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-timeout", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "hello-timeout", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - }, - { - "description": "Driver extends timeout while streaming", - "clientOptions": { - "retryWrites": false, - "connectTimeoutMS": 250, - "heartbeatFrequencyMS": 500, - "appname": "extendsTimeoutTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - }, - { - "name": "wait", - "object": "testRunner", - "arguments": { - "ms": 2000 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 0 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "hello-timeout", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "hello-timeout", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/hello-timeout.yml b/test/spec/server-discovery-and-monitoring/integration/hello-timeout.yml deleted file mode 100644 index 6c91ca9a72..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/hello-timeout.yml +++ /dev/null @@ -1,223 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "hello-timeout" - -data: [] - -tests: - - description: Network timeout on Monitor handshake - # Configure the initial handshake to fail with a timeout. - # Use times: 2 so that the RTT hello is blocked as well. - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: timeoutMonitorHandshakeTest - blockConnection: true - blockTimeMS: 1000 - clientOptions: - retryWrites: false - connectTimeoutMS: 250 - heartbeatFrequencyMS: 500 - appname: timeoutMonitorHandshakeTest - operations: - # The network error on the initial handshake should mark the server - # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # We cannot assert the server was marked Unknown and pool was cleared an - # exact number of times because the RTT hello may or may not have - # triggered this failpoint as well. - # - name: assertEventCount - # object: testRunner - # arguments: - # event: ServerMarkedUnknownEvent - # count: 1 - # - name: assertEventCount - # object: testRunner - # arguments: - # event: PoolClearedEvent - # count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - - description: Network timeout on Monitor check - clientOptions: - retryWrites: false - connectTimeoutMS: 750 - heartbeatFrequencyMS: 500 - appname: timeoutMonitorCheckTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # Configure the next streaming hello check to fail with a timeout - # Use times: 2 so that the RTT hello is blocked as well. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["hello", "isMaster"] - appName: timeoutMonitorCheckTest - blockConnection: true - # blockTimeMS is evaluated after the waiting for heartbeatFrequencyMS server-side, so this value only - # needs to be greater than connectTimeoutMS. The driver will wait for (500+750)ms and the server will - # respond after (500+1000)ms. - blockTimeMS: 1000 - # The network error on the next check should mark the server Unknown and - # clear the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform an operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} - - - description: Driver extends timeout while streaming - clientOptions: - retryWrites: false - connectTimeoutMS: 250 - heartbeatFrequencyMS: 500 - appname: extendsTimeoutTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 1 - - _id: 2 - # Wait for multiple monitor checks to complete. - - name: wait - object: testRunner - arguments: - ms: 2000 - # Perform an operation to ensure the node is still selectable. - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - # Assert that the server was never marked Unknown and the pool was never - # cleared. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 0 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 0 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 1 - - _id: 2 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} diff --git a/test/spec/server-discovery-and-monitoring/integration/insert-network-error.json b/test/spec/server-discovery-and-monitoring/integration/insert-network-error.json deleted file mode 100644 index fa8bb253e1..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/insert-network-error.json +++ /dev/null @@ -1,156 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "insert-network-error", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Reset server and pool after network error on insert", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true, - "appName": "insertNetworkErrorTest" - } - }, - "clientOptions": { - "retryWrites": false, - "appname": "insertNetworkErrorTest" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "error": true - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "insert-network-error", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "insert-network-error", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/insert-network-error.yml b/test/spec/server-discovery-and-monitoring/integration/insert-network-error.yml deleted file mode 100644 index ddd9f356b4..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/insert-network-error.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "insert-network-error" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Reset server and pool after network error on insert - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["insert"] - closeConnection: true - appName: insertNetworkErrorTest - clientOptions: - retryWrites: false - appname: insertNetworkErrorTest - operations: - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - error: true - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform another operation to ensure the node is rediscovered. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/integration/insert-shutdown-error.json b/test/spec/server-discovery-and-monitoring/integration/insert-shutdown-error.json deleted file mode 100644 index edde149a91..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/insert-shutdown-error.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4" - } - ], - "database_name": "sdam-tests", - "collection_name": "insert-shutdown-error", - "data": [], - "tests": [ - { - "description": "Concurrent shutdown error on insert", - "clientOptions": { - "retryWrites": false, - "heartbeatFrequencyMS": 500, - "appname": "shutdownErrorInsertTest" - }, - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 1 - } - } - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "insert" - ], - "appName": "shutdownErrorInsertTest", - "errorCode": 91, - "blockConnection": true, - "blockTimeMS": 500 - } - } - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread1" - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread2" - } - }, - { - "name": "runOnThread", - "object": "testRunner", - "arguments": { - "name": "thread1", - "operation": { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 2 - } - }, - "error": true - } - } - }, - { - "name": "runOnThread", - "object": "testRunner", - "arguments": { - "name": "thread2", - "operation": { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 3 - } - }, - "error": true - } - } - }, - { - "name": "waitForThread", - "object": "testRunner", - "arguments": { - "name": "thread1" - } - }, - { - "name": "waitForThread", - "object": "testRunner", - "arguments": { - "name": "thread2" - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "_id": 4 - } - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 4 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/insert-shutdown-error.yml b/test/spec/server-discovery-and-monitoring/integration/insert-shutdown-error.yml deleted file mode 100644 index 503607a6bd..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/insert-shutdown-error.yml +++ /dev/null @@ -1,115 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.4" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "insert-shutdown-error" - -data: [] - -tests: - - description: Concurrent shutdown error on insert - clientOptions: - retryWrites: false - heartbeatFrequencyMS: 500 - appname: shutdownErrorInsertTest - operations: - # Perform an operation to ensure the node is discovered. - - name: insertOne - object: collection - arguments: - document: - _id: 1 - # Configure the next two inserts to fail with a non-timeout shutdown - # errors. Block the connection for 500ms to ensure both operations check - # out connections from the same pool generation. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["insert"] - appName: shutdownErrorInsertTest - errorCode: 91 - blockConnection: true - blockTimeMS: 500 - # Start threads. - - name: startThread - object: testRunner - arguments: - name: thread1 - - name: startThread - object: testRunner - arguments: - name: thread2 - # Perform concurrent insert operations. Both fail with shutdown errors. - - name: runOnThread - object: testRunner - arguments: - name: thread1 - operation: - name: insertOne - object: collection - arguments: - document: - _id: 2 - error: true - - name: runOnThread - object: testRunner - arguments: - name: thread2 - operation: - name: insertOne - object: collection - arguments: - document: - _id: 3 - error: true - # Stop threads. - - name: waitForThread - object: testRunner - arguments: - name: thread1 - - name: waitForThread - object: testRunner - arguments: - name: thread2 - # The first shutdown error should mark the server Unknown and then clear - # the pool. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # Perform an operation to ensure the node is rediscovered. - - name: insertOne - object: collection - arguments: - document: - _id: 4 - # Assert the server was marked Unknown and pool was cleared exactly once. - - name: assertEventCount - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - - # Order of operations is non-deterministic so we cannot check events. - outcome: - collection: - data: - - {_id: 1} - - {_id: 4} diff --git a/test/spec/server-discovery-and-monitoring/integration/minPoolSize-error.json b/test/spec/server-discovery-and-monitoring/integration/minPoolSize-error.json deleted file mode 100644 index 9f8e4f6f8b..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/minPoolSize-error.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.9" - } - ], - "database_name": "sdam-tests", - "collection_name": "sdam-minPoolSize-error", - "data": [], - "tests": [ - { - "description": "Network error on minPoolSize background creation", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "skip": 3 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "SDAMminPoolSizeError", - "closeConnection": true - } - }, - "clientOptions": { - "heartbeatFrequencyMS": 10000, - "appname": "SDAMminPoolSizeError", - "minPoolSize": 10, - "serverSelectionTimeoutMS": 1000, - "directConnection": true - }, - "operations": [ - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolReadyEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "event": "ServerMarkedUnknownEvent", - "count": 1 - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "ping", - "arguments": { - "command": { - "ping": {} - } - }, - "error": true - }, - { - "name": "configureFailPoint", - "object": "testRunner", - "arguments": { - "failPoint": { - "configureFailPoint": "failCommand", - "mode": "off" - } - } - }, - { - "name": "runCommand", - "object": "database", - "command_name": "ping", - "arguments": { - "command": { - "ping": 1 - } - }, - "error": false - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolReadyEvent", - "count": 2 - } - } - ] - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/minPoolSize-error.yml b/test/spec/server-discovery-and-monitoring/integration/minPoolSize-error.yml deleted file mode 100644 index 3272728893..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/minPoolSize-error.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Test SDAM error handling. -runOn: - # failCommand appName requirements - - minServerVersion: "4.9" - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "sdam-minPoolSize-error" - -data: [] - -tests: - - description: Network error on minPoolSize background creation - # Configure the initial monitor handshake to succeed but the - # first or second background minPoolSize establishments to fail. - failPoint: - configureFailPoint: failCommand - mode: { skip: 3 } - data: - failCommands: ["hello", "isMaster"] - appName: SDAMminPoolSizeError - closeConnection: true - clientOptions: - heartbeatFrequencyMS: 10000 - appname: SDAMminPoolSizeError - minPoolSize: 10 - serverSelectionTimeoutMS: 1000 - directConnection: true - operations: - # Wait for monitor to succeed handshake and mark the pool as ready. - - name: waitForEvent - object: testRunner - arguments: - event: PoolReadyEvent - count: 1 - # Background connection establishment ensuring minPoolSize should fail, - # causing the pool to be cleared. - - name: waitForEvent - object: testRunner - arguments: - event: PoolClearedEvent - count: 1 - # The server should be marked as Unknown as part of this. - - name: waitForEvent - object: testRunner - arguments: - event: ServerMarkedUnknownEvent - count: 1 - # Executing a command should fail server selection due to not being able - # to find the primary. - - name: runCommand - object: database - command_name: ping - arguments: - command: - ping: {} - error: true - # Disable the failpoint, allowing the monitor to discover the primary again. - - name: configureFailPoint - object: testRunner - arguments: - failPoint: - configureFailPoint: failCommand - mode: off - # Perform an operation to ensure the node is discovered. - - name: runCommand - object: database - command_name: ping - arguments: - command: - ping: 1 - error: false - # Assert that the monitor discovered the primary and mark the pool as ready again. - - name: assertEventCount - object: testRunner - arguments: - event: PoolReadyEvent - count: 2 diff --git a/test/spec/server-discovery-and-monitoring/integration/rediscover-quickly-after-step-down.json b/test/spec/server-discovery-and-monitoring/integration/rediscover-quickly-after-step-down.json deleted file mode 100644 index 41fbdc695c..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/rediscover-quickly-after-step-down.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.4", - "topology": [ - "replicaset" - ] - } - ], - "database_name": "sdam-tests", - "collection_name": "test-replSetStepDown", - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ], - "tests": [ - { - "description": "Rediscover quickly after replSetStepDown", - "clientOptions": { - "appname": "replSetStepDownTest", - "heartbeatFrequencyMS": 60000, - "serverSelectionTimeoutMS": 5000, - "w": "majority" - }, - "operations": [ - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - } - }, - { - "name": "recordPrimary", - "object": "testRunner" - }, - { - "name": "runAdminCommand", - "object": "testRunner", - "command_name": "replSetFreeze", - "arguments": { - "command": { - "replSetFreeze": 0 - }, - "readPreference": { - "mode": "Secondary" - } - } - }, - { - "name": "runAdminCommand", - "object": "testRunner", - "command_name": "replSetStepDown", - "arguments": { - "command": { - "replSetStepDown": 30, - "secondaryCatchUpPeriodSecs": 30, - "force": false - } - } - }, - { - "name": "waitForPrimaryChange", - "object": "testRunner", - "arguments": { - "timeoutMS": 15000 - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - }, - { - "name": "assertEventCount", - "object": "testRunner", - "arguments": { - "event": "PoolClearedEvent", - "count": 0 - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test-replSetStepDown", - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test-replSetStepDown", - "documents": [ - { - "_id": 5 - }, - { - "_id": 6 - } - ] - }, - "command_name": "insert", - "database_name": "sdam-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - }, - { - "_id": 4 - }, - { - "_id": 5 - }, - { - "_id": 6 - } - ] - } - } - } - ] -} diff --git a/test/spec/server-discovery-and-monitoring/integration/rediscover-quickly-after-step-down.yml b/test/spec/server-discovery-and-monitoring/integration/rediscover-quickly-after-step-down.yml deleted file mode 100644 index fd8b430703..0000000000 --- a/test/spec/server-discovery-and-monitoring/integration/rediscover-quickly-after-step-down.yml +++ /dev/null @@ -1,98 +0,0 @@ -runOn: - # 4.4 is required for streaming. - # A replica set is required for replSetStepDown. - - minServerVersion: "4.4" - topology: ["replicaset"] - -database_name: &database_name "sdam-tests" -collection_name: &collection_name "test-replSetStepDown" - -data: &data - - {_id: 1} - - {_id: 2} - -tests: - - description: Rediscover quickly after replSetStepDown - clientOptions: - appname: replSetStepDownTest - # Configure a large heartbeatFrequencyMS - heartbeatFrequencyMS: 60000 - # Configure a much smaller server selection timeout so that the test - # will error when it cannot discover the new primary soon. - serverSelectionTimeoutMS: 5000 - w: majority - operations: - # Discover the primary. - - name: insertMany - object: collection - arguments: - documents: - - _id: 3 - - _id: 4 - - name: recordPrimary - object: testRunner - # Unfreeze a secondary with replSetFreeze:0 to ensure a speedy election. - - name: runAdminCommand - object: testRunner - command_name: replSetFreeze - arguments: - command: - replSetFreeze: 0 - readPreference: - mode: Secondary - # Run replSetStepDown on the meta client. - - name: runAdminCommand - object: testRunner - command_name: replSetStepDown - arguments: - command: - replSetStepDown: 30 - secondaryCatchUpPeriodSecs: 30 - force: false - - name: waitForPrimaryChange - object: testRunner - arguments: - # We use a relatively large timeout here to workaround slow - # elections on Windows, possibly caused by SERVER-48154. - timeoutMS: 15000 - # Rediscover the new primary. - - name: insertMany - object: collection - arguments: - documents: - - _id: 5 - - _id: 6 - # Assert that no pools were cleared. - - name: assertEventCount - object: testRunner - arguments: - event: PoolClearedEvent - count: 0 - - expectations: - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 3 - - _id: 4 - command_name: insert - database_name: *database_name - - command_started_event: - command: - insert: *collection_name - documents: - - _id: 5 - - _id: 6 - command_name: insert - database_name: *database_name - - outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} - - {_id: 5} - - {_id: 6} diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-error.json b/test/spec/server-discovery-and-monitoring/unified/auth-error.json new file mode 100644 index 0000000000..5c78ecfe50 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-error.json @@ -0,0 +1,230 @@ +{ + "description": "auth-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "auth": true, + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "auth-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after AuthenticationFailure error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "saslContinue" + ], + "appName": "authErrorTest", + "errorCode": 18 + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "appname": "authErrorTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "auth-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "auth-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "auth-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-error.yml b/test/spec/server-discovery-and-monitoring/unified/auth-error.yml new file mode 100644 index 0000000000..b2dfc4eccc --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-error.yml @@ -0,0 +1,130 @@ +description: auth-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + auth: true + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName auth-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 +tests: + - description: Reset server and pool after AuthenticationFailure error + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - saslContinue + appName: authErrorTest + errorCode: 18 + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + appname: authErrorTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + # Note: The first insert command is never attempted because connection + # checkout fails. + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: auth-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-misc-command-error.json b/test/spec/server-discovery-and-monitoring/unified/auth-misc-command-error.json new file mode 100644 index 0000000000..6e1b645461 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-misc-command-error.json @@ -0,0 +1,230 @@ +{ + "description": "auth-misc-command-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "auth": true, + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "auth-misc-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after misc command error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "saslContinue" + ], + "appName": "authMiscErrorTest", + "errorCode": 1 + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "appname": "authMiscErrorTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "auth-misc-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "auth-misc-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "auth-misc-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-misc-command-error.yml b/test/spec/server-discovery-and-monitoring/unified/auth-misc-command-error.yml new file mode 100644 index 0000000000..94d41d6616 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-misc-command-error.yml @@ -0,0 +1,132 @@ +--- +description: auth-misc-command-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + auth: true + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName auth-misc-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Reset server and pool after misc command error + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - saslContinue + appName: authMiscErrorTest + errorCode: 1 # InternalError + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + appname: authMiscErrorTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + # Note: The first insert command is never attempted because connection + # checkout fails. + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: auth-misc-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-network-error.json b/test/spec/server-discovery-and-monitoring/unified/auth-network-error.json new file mode 100644 index 0000000000..7606d2db7a --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-network-error.json @@ -0,0 +1,230 @@ +{ + "description": "auth-network-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "auth": true, + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "auth-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after network error during authentication", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "saslContinue" + ], + "closeConnection": true, + "appName": "authNetworkErrorTest" + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "appname": "authNetworkErrorTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "auth-network-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "auth-network-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "auth-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-network-error.yml b/test/spec/server-discovery-and-monitoring/unified/auth-network-error.yml new file mode 100644 index 0000000000..9073a927ce --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-network-error.yml @@ -0,0 +1,132 @@ +--- +description: auth-network-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + auth: true + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName auth-network-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Reset server and pool after network error during authentication + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - saslContinue + closeConnection: true + appName: authNetworkErrorTest + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + appname: authNetworkErrorTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + # Note: The first insert command is never attempted because connection + # checkout fails. + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: auth-network-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-network-timeout-error.json b/test/spec/server-discovery-and-monitoring/unified/auth-network-timeout-error.json new file mode 100644 index 0000000000..22066e8bae --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-network-timeout-error.json @@ -0,0 +1,233 @@ +{ + "description": "auth-network-timeout-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "auth": true, + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "auth-network-timeout-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after network timeout error during authentication", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "saslContinue" + ], + "blockConnection": true, + "blockTimeMS": 500, + "appName": "authNetworkTimeoutErrorTest" + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "appname": "authNetworkTimeoutErrorTest", + "connectTimeoutMS": 250, + "socketTimeoutMS": 250 + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "auth-network-timeout-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "auth-network-timeout-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "auth-network-timeout-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-network-timeout-error.yml b/test/spec/server-discovery-and-monitoring/unified/auth-network-timeout-error.yml new file mode 100644 index 0000000000..8b29a1e670 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-network-timeout-error.yml @@ -0,0 +1,138 @@ +--- +description: auth-network-timeout-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + auth: true + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName auth-network-timeout-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Reset server and pool after network timeout error during authentication + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - saslContinue + blockConnection: true + blockTimeMS: 500 + appName: authNetworkTimeoutErrorTest + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + appname: authNetworkTimeoutErrorTest + # Set a short connect/socket timeout to ensure the fail point causes the + # connection establishment to timeout. + connectTimeoutMS: 250 + socketTimeoutMS: 250 + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + # Note: The first insert command is never attempted because connection + # checkout fails. + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: auth-network-timeout-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-shutdown-error.json b/test/spec/server-discovery-and-monitoring/unified/auth-shutdown-error.json new file mode 100644 index 0000000000..5dd7b5bb6f --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-shutdown-error.json @@ -0,0 +1,230 @@ +{ + "description": "auth-shutdown-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "auth": true, + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "auth-shutdown-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after shutdown error during authentication", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "saslContinue" + ], + "appName": "authShutdownErrorTest", + "errorCode": 91 + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "appname": "authShutdownErrorTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "auth-shutdown-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "auth-shutdown-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "auth-shutdown-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/auth-shutdown-error.yml b/test/spec/server-discovery-and-monitoring/unified/auth-shutdown-error.yml new file mode 100644 index 0000000000..87a937d381 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/auth-shutdown-error.yml @@ -0,0 +1,133 @@ +--- +description: auth-shutdown-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + auth: true + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName auth-shutdown-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Reset server and pool after shutdown error during authentication + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - saslContinue + appName: authShutdownErrorTest + errorCode: 91 + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + appname: authShutdownErrorTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + # Note: The first insert command is never attempted because connection + # checkout fails. + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: auth-shutdown-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/cancel-server-check.json b/test/spec/server-discovery-and-monitoring/unified/cancel-server-check.json new file mode 100644 index 0000000000..896cc8d087 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/cancel-server-check.json @@ -0,0 +1,201 @@ +{ + "description": "cancel-server-check", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ], + "serverless": "forbid" + }, + { + "minServerVersion": "4.2", + "topologies": [ + "sharded" + ], + "serverless": "forbid" + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "cancel-server-check", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Cancel server check", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": true, + "heartbeatFrequencyMS": 10000, + "serverSelectionTimeoutMS": 5000, + "appname": "cancelServerCheckTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "cancel-server-check" + } + } + ] + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 1 + } + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "insert" + ], + "closeConnection": true + } + }, + "client": "setupClient" + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 2 + } + }, + "expectResult": { + "insertedId": 2 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 3 + } + }, + "expectResult": { + "insertedId": 3 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "outcome": [ + { + "collectionName": "cancel-server-check", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/cancel-server-check.yml b/test/spec/server-discovery-and-monitoring/unified/cancel-server-check.yml new file mode 100644 index 0000000000..67d96706e1 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/cancel-server-check.yml @@ -0,0 +1,143 @@ +--- +description: cancel-server-check + +schemaVersion: "1.10" + +runOnRequirements: + # General failCommand requirements (this file does not use appName + # with failCommand). + - minServerVersion: "4.0" + topologies: + - replicaset + serverless: forbid + - minServerVersion: "4.2" + topologies: + - sharded + serverless: forbid + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName cancel-server-check + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Cancel server check + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: true + heartbeatFrequencyMS: 10000 + # Server selection timeout MUST be less than heartbeatFrequencyMS for + # this test. This setting ensures that the retried insert will fail + # after 5 seconds if the driver does not properly cancel the in progress + # check. + serverSelectionTimeoutMS: 5000 + appname: cancelServerCheckTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertOne + object: *collection + arguments: + document: + _id: 1 + # Configure the next inserts to fail with a non-timeout network error. + # This should: + # 1) Mark the server Unknown + # 2) Clear the connection pool + # 3) Cancel the in progress hello or legacy hello check and close the Monitor + # connection + # 4) The write will be then we retried, server selection will request an + # immediate check, and block for ~500ms until the next Monitor check + # proceeds. + # 5) The write will succeed on the second attempt. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - insert + closeConnection: true + client: *setupClient + - name: insertOne + object: *collection + arguments: + document: + _id: 2 + expectResult: + insertedId: 2 + # The first error should mark the server Unknown and then clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node still selectable. + - name: insertOne + object: *collection + arguments: + document: + _id: 3 + expectResult: + insertedId: 3 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + + # Order of operations is non-deterministic so we cannot check events. + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 diff --git a/test/spec/server-discovery-and-monitoring/unified/connectTimeoutMS.json b/test/spec/server-discovery-and-monitoring/unified/connectTimeoutMS.json new file mode 100644 index 0000000000..67a4d9da1d --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/connectTimeoutMS.json @@ -0,0 +1,221 @@ +{ + "description": "connectTimeoutMS", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "connectTimeoutMS", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "connectTimeoutMS=0", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 0, + "heartbeatFrequencyMS": 500, + "appname": "connectTimeoutMS=0" + }, + "useMultipleMongoses": false + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "connectTimeoutMS" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "connectTimeoutMS=0", + "blockConnection": true, + "blockTimeMS": 550 + } + }, + "client": "setupClient" + } + }, + { + "name": "wait", + "object": "testRunner", + "arguments": { + "ms": 750 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 0 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 0 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "connectTimeoutMS", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "connectTimeoutMS", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "connectTimeoutMS", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/connectTimeoutMS.yml b/test/spec/server-discovery-and-monitoring/unified/connectTimeoutMS.yml new file mode 100644 index 0000000000..ef6d1150a7 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/connectTimeoutMS.yml @@ -0,0 +1,130 @@ +--- +description: connectTimeoutMS + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName connectTimeoutMS + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: connectTimeoutMS=0 + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 0 + heartbeatFrequencyMS: 500 + appname: connectTimeoutMS=0 + useMultipleMongoses: false + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # Block the next streaming hello check for longer than + # heartbeatFrequencyMS to ensure that the connection timeout remains + # unlimited. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 2 + data: + failCommands: + - hello + - isMaster + appName: connectTimeoutMS=0 + blockConnection: true + blockTimeMS: 550 + client: *setupClient + - name: wait + object: testRunner + arguments: + ms: 750 + # Perform an operation to ensure the node is still selectable. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + # Assert that the server was never marked Unknown and the pool was never + # cleared. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 0 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 0 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: connectTimeoutMS + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: connectTimeoutMS + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 diff --git a/test/spec/server-discovery-and-monitoring/unified/find-network-error.json b/test/spec/server-discovery-and-monitoring/unified/find-network-error.json new file mode 100644 index 0000000000..651466bfa6 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/find-network-error.json @@ -0,0 +1,234 @@ +{ + "description": "find-network-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "find-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after network error on find", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "find" + ], + "closeConnection": true, + "appName": "findNetworkErrorTest" + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "retryReads": false, + "appname": "findNetworkErrorTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "find-network-error" + } + } + ] + } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": { + "_id": 1 + } + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "find": "find-network-error" + }, + "commandName": "find", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "find-network-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "find-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/find-network-error.yml b/test/spec/server-discovery-and-monitoring/unified/find-network-error.yml new file mode 100644 index 0000000000..deae09a19f --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/find-network-error.yml @@ -0,0 +1,135 @@ +--- +description: find-network-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName find-network-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Reset server and pool after network error on find + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - find + closeConnection: true + appName: findNetworkErrorTest + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + retryReads: false + appname: findNetworkErrorTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: find + object: *collection + arguments: + filter: + _id: 1 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + find: find-network-error + commandName: find + databaseName: *databaseName + - commandStartedEvent: + command: + insert: find-network-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/find-network-timeout-error.json b/test/spec/server-discovery-and-monitoring/unified/find-network-timeout-error.json new file mode 100644 index 0000000000..2bde6daa5d --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/find-network-timeout-error.json @@ -0,0 +1,199 @@ +{ + "description": "find-network-timeout-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "find-network-timeout-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Ignore network timeout error on find", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "find" + ], + "blockConnection": true, + "blockTimeMS": 500, + "appName": "findNetworkTimeoutErrorTest" + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "retryReads": false, + "appname": "findNetworkTimeoutErrorTest", + "socketTimeoutMS": 250 + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "find-network-timeout-error" + } + } + ] + } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": { + "_id": 1 + } + }, + "expectError": { + "isError": true + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 3 + } + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 0 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 0 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "find": "find-network-timeout-error" + }, + "commandName": "find", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "find-network-timeout-error", + "documents": [ + { + "_id": 3 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "find-network-timeout-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/find-network-timeout-error.yml b/test/spec/server-discovery-and-monitoring/unified/find-network-timeout-error.yml new file mode 100644 index 0000000000..30c4809ccf --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/find-network-timeout-error.yml @@ -0,0 +1,119 @@ +--- +description: find-network-timeout-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName find-network-timeout-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Ignore network timeout error on find + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - find + blockConnection: true + blockTimeMS: 500 + appName: findNetworkTimeoutErrorTest + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + retryReads: false + appname: findNetworkTimeoutErrorTest + # Set a short socket timeout to ensure the find command times out. + socketTimeoutMS: 250 + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: find + object: *collection + arguments: + filter: + _id: 1 + expectError: + isError: true + # Perform another operation to ensure the node is still usable. + - name: insertOne + object: *collection + arguments: + document: + _id: 3 + # Assert the server was not marked Unknown and the pool was not cleared. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 0 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 0 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + find: find-network-timeout-error + commandName: find + databaseName: *databaseName + - commandStartedEvent: + command: + insert: find-network-timeout-error + documents: + - _id: 3 + commandName: insert + databaseName: *databaseName + + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 diff --git a/test/spec/server-discovery-and-monitoring/unified/find-shutdown-error.json b/test/spec/server-discovery-and-monitoring/unified/find-shutdown-error.json new file mode 100644 index 0000000000..624ad352fc --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/find-shutdown-error.json @@ -0,0 +1,251 @@ +{ + "description": "find-shutdown-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "find-shutdown-error", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Concurrent shutdown error on find", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "uriOptions": { + "retryWrites": false, + "retryReads": false, + "heartbeatFrequencyMS": 500, + "appname": "shutdownErrorFindTest" + }, + "observeEvents": [ + "serverDescriptionChangedEvent", + "poolClearedEvent" + ] + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "find-shutdown-error" + } + } + ] + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 1 + } + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "find" + ], + "appName": "shutdownErrorFindTest", + "errorCode": 91, + "blockConnection": true, + "blockTimeMS": 500 + } + }, + "client": "setupClient" + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "thread": { + "id": "thread0" + } + }, + { + "thread": { + "id": "thread1" + } + } + ] + } + }, + { + "name": "runOnThread", + "object": "testRunner", + "arguments": { + "thread": "thread0", + "operation": { + "name": "find", + "object": "collection", + "arguments": { + "filter": { + "_id": 1 + } + }, + "expectError": { + "isError": true + } + } + } + }, + { + "name": "runOnThread", + "object": "testRunner", + "arguments": { + "thread": "thread1", + "operation": { + "name": "find", + "object": "collection", + "arguments": { + "filter": { + "_id": 1 + } + }, + "expectError": { + "isError": true + } + } + } + }, + { + "name": "waitForThread", + "object": "testRunner", + "arguments": { + "thread": "thread0" + } + }, + { + "name": "waitForThread", + "object": "testRunner", + "arguments": { + "thread": "thread1" + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 4 + } + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "outcome": [ + { + "collectionName": "find-shutdown-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 4 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/find-shutdown-error.yml b/test/spec/server-discovery-and-monitoring/unified/find-shutdown-error.yml new file mode 100644 index 0000000000..f2da705d9e --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/find-shutdown-error.yml @@ -0,0 +1,163 @@ +--- +description: find-shutdown-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName find-shutdown-error + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Concurrent shutdown error on find + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + uriOptions: + retryWrites: false + retryReads: false + heartbeatFrequencyMS: 500 + appname: shutdownErrorFindTest + observeEvents: + - serverDescriptionChangedEvent + - poolClearedEvent + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertOne + object: *collection + arguments: + document: + _id: 1 + # Configure the next two finds to fail with a non-timeout shutdown + # errors. Block the connection for 500ms to ensure both operations check + # out connections from the same pool generation. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 2 + data: + failCommands: + - find + appName: shutdownErrorFindTest + errorCode: 91 + blockConnection: true + blockTimeMS: 500 + client: *setupClient + # Start threads. + - name: createEntities + object: testRunner + arguments: + entities: + - thread: + id: &thread0 thread0 + - thread: + id: &thread1 thread1 + # Perform concurrent find operations. Both fail with shutdown errors. + - name: runOnThread + object: testRunner + arguments: + thread: *thread0 + operation: + name: find + object: *collection + arguments: + filter: + _id: 1 + expectError: + isError: true + - name: runOnThread + object: testRunner + arguments: + thread: *thread1 + operation: + name: find + object: *collection + arguments: + filter: + _id: 1 + expectError: + isError: true + # Stop threads. + - name: waitForThread + object: testRunner + arguments: + thread: *thread0 + - name: waitForThread + object: testRunner + arguments: + thread: *thread1 + # The first shutdown error should mark the server Unknown and then clear + # the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform an operation to ensure the node is rediscovered. + - name: insertOne + object: *collection + arguments: + document: + _id: 4 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + + # Order of operations is non-deterministic so we cannot check events. + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 4 diff --git a/test/spec/server-discovery-and-monitoring/unified/hello-command-error.json b/test/spec/server-discovery-and-monitoring/unified/hello-command-error.json new file mode 100644 index 0000000000..7d6046b76f --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/hello-command-error.json @@ -0,0 +1,376 @@ +{ + "description": "hello-command-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.9", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "hello-command-error", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Command error on Monitor handshake", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 4 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "commandErrorHandshakeTest", + "closeConnection": false, + "errorCode": 91 + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "serverDescriptionChangedEvent", + "poolClearedEvent", + "commandStartedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 250, + "heartbeatFrequencyMS": 500, + "appname": "commandErrorHandshakeTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-command-error" + } + } + ] + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-command-error", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-command-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ] + }, + { + "description": "Command error on Monitor check", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 1000, + "heartbeatFrequencyMS": 500, + "appname": "commandErrorCheckTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-command-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "commandErrorCheckTest", + "closeConnection": false, + "blockConnection": true, + "blockTimeMS": 750, + "errorCode": 91 + } + }, + "client": "setupClient" + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-command-error", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "hello-command-error", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-command-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/hello-command-error.yml b/test/spec/server-discovery-and-monitoring/unified/hello-command-error.yml new file mode 100644 index 0000000000..2dc8be2f3b --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/hello-command-error.yml @@ -0,0 +1,233 @@ +--- +description: hello-command-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.9" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName hello-command-error + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Command error on Monitor handshake + operations: + # Configure the next streaming hello check to fail with a command error. + # Use "times: 4" to increase the probability that the Monitor check fails + # since the RTT hello may trigger this failpoint one or many times as + # well. + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 4 + data: + failCommands: + - hello + - isMaster + appName: commandErrorHandshakeTest + closeConnection: false + errorCode: 91 + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - serverDescriptionChangedEvent + - poolClearedEvent + - commandStartedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 250 + heartbeatFrequencyMS: 500 + appname: commandErrorHandshakeTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # The command error on the initial handshake should mark the server + # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # We cannot assert the server was marked Unknown and pool was cleared an + # exact number of times because the RTT hello may or may not have + # triggered this failpoint as well. + + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-command-error + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + + - description: Command error on Monitor check + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 1000 + heartbeatFrequencyMS: 500 + appname: commandErrorCheckTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # Configure the next streaming hello check to fail with a command + # error. + # Use times: 2 so that the RTT hello is blocked as well. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 2 + data: + failCommands: + - hello + - isMaster + appName: commandErrorCheckTest + closeConnection: false + blockConnection: true + blockTimeMS: 750 + errorCode: 91 + client: *setupClient + # The command error on the next check should mark the server Unknown and + # clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform an operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-command-error + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: hello-command-error + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 diff --git a/test/spec/server-discovery-and-monitoring/unified/hello-network-error.json b/test/spec/server-discovery-and-monitoring/unified/hello-network-error.json new file mode 100644 index 0000000000..f44b26a9f9 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/hello-network-error.json @@ -0,0 +1,346 @@ +{ + "description": "hello-network-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.9", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "hello-network-error", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Network error on Monitor handshake", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "networkErrorHandshakeTest", + "closeConnection": true + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 250, + "heartbeatFrequencyMS": 500, + "appname": "networkErrorHandshakeTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-network-error" + } + } + ] + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-network-error", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ] + }, + { + "description": "Network error on Monitor check", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 250, + "heartbeatFrequencyMS": 500, + "appname": "networkErrorCheckTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-network-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 4 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "networkErrorCheckTest", + "closeConnection": true + } + }, + "client": "setupClient" + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-network-error", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "hello-network-error", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/hello-network-error.yml b/test/spec/server-discovery-and-monitoring/unified/hello-network-error.yml new file mode 100644 index 0000000000..20932b39c6 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/hello-network-error.yml @@ -0,0 +1,227 @@ +--- +description: hello-network-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.9" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName hello-network-error + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Network error on Monitor handshake + # Configure the initial handshake to fail with a network error. + # Use times: 2 so that the RTT hello fails as well. + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 2 + data: + failCommands: + - hello + - isMaster + appName: networkErrorHandshakeTest + closeConnection: true + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 250 + heartbeatFrequencyMS: 500 + appname: networkErrorHandshakeTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # The network error on the initial handshake should mark the server + # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # We cannot assert the server was marked Unknown and pool was cleared an + # exact number of times because the RTT hello may or may not have + # triggered this failpoint as well. + + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-network-error + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + + - description: Network error on Monitor check + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 250 + heartbeatFrequencyMS: 500 + appname: networkErrorCheckTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # Configure the next streaming hello check to fail with a non-timeout + # network error. Use "times: 4" to increase the probability that the + # Monitor check fails since the RTT hello may trigger this failpoint one + # or many times as well. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 4 + data: + failCommands: + - hello + - isMaster + appName: networkErrorCheckTest + closeConnection: true + client: *setupClient + # The network error on the next check should mark the server Unknown and + # clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform an operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + # We cannot assert the server was marked Unknown and pool was cleared an + # exact number of times because the RTT hello may or may not have + # triggered this failpoint as well. + # - name: assertEventCount + # object: testRunner + # arguments: + # client: *client + # event: + # serverDescriptionChangedEvent: + # newDescription: + # type: Unknown + # count: 1 + # - name: assertEventCount + # object: testRunner + # arguments: + # event: + # poolClearedEvent: {} + # count: 1 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-network-error + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: hello-network-error + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 diff --git a/test/spec/server-discovery-and-monitoring/unified/hello-timeout.json b/test/spec/server-discovery-and-monitoring/unified/hello-timeout.json new file mode 100644 index 0000000000..dfa6b48d66 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/hello-timeout.json @@ -0,0 +1,514 @@ +{ + "description": "hello-timeout", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "hello-timeout", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Network timeout on Monitor handshake", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "timeoutMonitorHandshakeTest", + "blockConnection": true, + "blockTimeMS": 1000 + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 250, + "heartbeatFrequencyMS": 500, + "appname": "timeoutMonitorHandshakeTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-timeout" + } + } + ] + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-timeout", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-timeout", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ] + }, + { + "description": "Network timeout on Monitor check", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 750, + "heartbeatFrequencyMS": 500, + "appname": "timeoutMonitorCheckTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-timeout" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 4 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "timeoutMonitorCheckTest", + "blockConnection": true, + "blockTimeMS": 1000 + } + }, + "client": "setupClient" + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-timeout", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "hello-timeout", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-timeout", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + ] + }, + { + "description": "Driver extends timeout while streaming", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "connectTimeoutMS": 250, + "heartbeatFrequencyMS": 500, + "appname": "extendsTimeoutTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "hello-timeout" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + }, + { + "name": "wait", + "object": "testRunner", + "arguments": { + "ms": 2000 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 0 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 0 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "hello-timeout", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "hello-timeout", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "hello-timeout", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/hello-timeout.yml b/test/spec/server-discovery-and-monitoring/unified/hello-timeout.yml new file mode 100644 index 0000000000..efab836e65 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/hello-timeout.yml @@ -0,0 +1,318 @@ +--- +description: hello-timeout + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName hello-timeout + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Network timeout on Monitor handshake + operations: + # Configure the initial handshake to fail with a timeout. + # Use times: 2 so that the RTT hello is blocked as well. + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 2 + data: + failCommands: + - hello + - isMaster + appName: timeoutMonitorHandshakeTest + blockConnection: true + blockTimeMS: 1000 + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 250 + heartbeatFrequencyMS: 500 + appname: timeoutMonitorHandshakeTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # The network error on the initial handshake should mark the server + # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # We cannot assert the server was marked Unknown and pool was cleared an + # exact number of times because the RTT hello may or may not have + # triggered this failpoint as well. + # - name: assertEventCount + # object: testRunner + # arguments: + # event: ServerMarkedUnknownEvent + # count: 1 + # - name: assertEventCount + # object: testRunner + # arguments: + # event: PoolClearedEvent + # count: 1 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-timeout + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + + - description: Network timeout on Monitor check + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 750 + heartbeatFrequencyMS: 500 + appname: timeoutMonitorCheckTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # Configure the next streaming hello check to fail with a timeout. + # Use "times: 4" to increase the probability that the Monitor check times + # out since the RTT hello may trigger this failpoint one or many times as + # well. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 4 + data: + failCommands: + - hello + - isMaster + appName: timeoutMonitorCheckTest + blockConnection: true + # blockTimeMS is evaluated after the waiting for heartbeatFrequencyMS server-side, so this value only + # needs to be greater than connectTimeoutMS. The driver will wait for (500+750)ms and the server will + # respond after (500+1000)ms. + blockTimeMS: 1000 + client: *setupClient + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + # The network error on the next check should mark the server Unknown and + # clear the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform an operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + # We cannot assert the server was marked Unknown and pool was cleared an + # exact number of times because the RTT hello may have triggered this + # failpoint one or many times as well. + + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-timeout + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: hello-timeout + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 + + - description: Driver extends timeout while streaming + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + connectTimeoutMS: 250 + heartbeatFrequencyMS: 500 + appname: extendsTimeoutTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 1 + - _id: 2 + # Wait for multiple monitor checks to complete. + - name: wait + object: testRunner + arguments: + ms: 2000 + # Perform an operation to ensure the node is still selectable. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + # Assert that the server was never marked Unknown and the pool was never + # cleared. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 0 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 0 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: hello-timeout + documents: + - _id: 1 + - _id: 2 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: hello-timeout + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 diff --git a/test/spec/server-discovery-and-monitoring/unified/insert-network-error.json b/test/spec/server-discovery-and-monitoring/unified/insert-network-error.json new file mode 100644 index 0000000000..e4ba6684ae --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/insert-network-error.json @@ -0,0 +1,246 @@ +{ + "description": "insert-network-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "insert-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Reset server and pool after network error on insert", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "insert" + ], + "closeConnection": true, + "appName": "insertNetworkErrorTest" + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "commandStartedEvent", + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": false, + "appname": "insertNetworkErrorTest" + }, + "useMultipleMongoses": false + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "insert-network-error" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "expectError": { + "isError": true + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "insert-network-error", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "insert-network-error", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "insert-network-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/insert-network-error.yml b/test/spec/server-discovery-and-monitoring/unified/insert-network-error.yml new file mode 100644 index 0000000000..fc9c2f4921 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/insert-network-error.yml @@ -0,0 +1,137 @@ +--- +description: insert-network-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName insert-network-error + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Reset server and pool after network error on insert + operations: + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + times: 1 + data: + failCommands: + - insert + closeConnection: true + appName: insertNetworkErrorTest + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + observeEvents: + - commandStartedEvent + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: false + appname: insertNetworkErrorTest + useMultipleMongoses: false + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + expectError: + isError: true + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform another operation to ensure the node is rediscovered. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: insert-network-error + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: insert-network-error + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 5 + - _id: 6 diff --git a/test/spec/server-discovery-and-monitoring/unified/insert-shutdown-error.json b/test/spec/server-discovery-and-monitoring/unified/insert-shutdown-error.json new file mode 100644 index 0000000000..3c724fa5e4 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/insert-shutdown-error.json @@ -0,0 +1,250 @@ +{ + "description": "insert-shutdown-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "single", + "replicaset", + "sharded" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "insert-shutdown-error", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Concurrent shutdown error on insert", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "uriOptions": { + "retryWrites": false, + "heartbeatFrequencyMS": 500, + "appname": "shutdownErrorInsertTest" + }, + "observeEvents": [ + "serverDescriptionChangedEvent", + "poolClearedEvent" + ] + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "insert-shutdown-error" + } + } + ] + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 1 + } + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "insert" + ], + "appName": "shutdownErrorInsertTest", + "errorCode": 91, + "blockConnection": true, + "blockTimeMS": 500 + } + }, + "client": "setupClient" + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "thread": { + "id": "thread0" + } + }, + { + "thread": { + "id": "thread1" + } + } + ] + } + }, + { + "name": "runOnThread", + "object": "testRunner", + "arguments": { + "thread": "thread0", + "operation": { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 2 + } + }, + "expectError": { + "isError": true + } + } + } + }, + { + "name": "runOnThread", + "object": "testRunner", + "arguments": { + "thread": "thread1", + "operation": { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 3 + } + }, + "expectError": { + "isError": true + } + } + } + }, + { + "name": "waitForThread", + "object": "testRunner", + "arguments": { + "thread": "thread0" + } + }, + { + "name": "waitForThread", + "object": "testRunner", + "arguments": { + "thread": "thread1" + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 4 + } + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + } + ], + "outcome": [ + { + "collectionName": "insert-shutdown-error", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 4 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/insert-shutdown-error.yml b/test/spec/server-discovery-and-monitoring/unified/insert-shutdown-error.yml new file mode 100644 index 0000000000..1ec920a6bc --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/insert-shutdown-error.yml @@ -0,0 +1,162 @@ +--- +description: insert-shutdown-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.4" + serverless: forbid + topologies: [ single, replicaset, sharded ] + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName insert-shutdown-error + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Concurrent shutdown error on insert + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + uriOptions: + retryWrites: false + heartbeatFrequencyMS: 500 + appname: shutdownErrorInsertTest + observeEvents: + - serverDescriptionChangedEvent + - poolClearedEvent + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Perform an operation to ensure the node is discovered. + - name: insertOne + object: *collection + arguments: + document: + _id: 1 + # Configure the next two inserts to fail with a non-timeout shutdown + # errors. Block the connection for 500ms to ensure both operations check + # out connections from the same pool generation. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: + times: 2 + data: + failCommands: + - insert + appName: shutdownErrorInsertTest + errorCode: 91 + blockConnection: true + blockTimeMS: 500 + client: *setupClient + # Start threads. + - name: createEntities + object: testRunner + arguments: + entities: + - thread: + id: &thread0 thread0 + - thread: + id: &thread1 thread1 + # Perform concurrent insert operations. Both fail with shutdown errors. + - name: runOnThread + object: testRunner + arguments: + thread: *thread0 + operation: + name: insertOne + object: *collection + arguments: + document: + _id: 2 + expectError: + isError: true + - name: runOnThread + object: testRunner + arguments: + thread: *thread1 + operation: + name: insertOne + object: *collection + arguments: + document: + _id: 3 + expectError: + isError: true + # Stop threads. + - name: waitForThread + object: testRunner + arguments: + thread: *thread0 + - name: waitForThread + object: testRunner + arguments: + thread: *thread1 + # The first shutdown error should mark the server Unknown and then clear + # the pool. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # Perform an operation to ensure the node is rediscovered. + - name: insertOne + object: *collection + arguments: + document: + _id: 4 + # Assert the server was marked Unknown and pool was cleared exactly once. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + + # Order of operations is non-deterministic so we cannot check events. + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 4 diff --git a/test/spec/server-discovery-and-monitoring/unified/minPoolSize-error.json b/test/spec/server-discovery-and-monitoring/unified/minPoolSize-error.json new file mode 100644 index 0000000000..0234ac9929 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/minPoolSize-error.json @@ -0,0 +1,177 @@ +{ + "description": "minPoolSize-error", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.9", + "serverless": "forbid", + "topologies": [ + "single" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "sdam-minPoolSize-error", + "databaseName": "sdam-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "Network error on minPoolSize background creation", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "setupClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "skip": 3 + }, + "data": { + "failCommands": [ + "hello", + "isMaster" + ], + "appName": "SDAMminPoolSizeError", + "closeConnection": true + } + } + } + }, + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "serverDescriptionChangedEvent", + "poolClearedEvent", + "poolReadyEvent" + ], + "uriOptions": { + "heartbeatFrequencyMS": 10000, + "appname": "SDAMminPoolSizeError", + "minPoolSize": 10, + "serverSelectionTimeoutMS": 1000 + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "sdam-minPoolSize-error" + } + } + ] + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolReadyEvent": {} + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 1 + } + }, + { + "name": "waitForEvent", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, + "count": 1 + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "ping": {} + }, + "commandName": "ping" + }, + "expectError": { + "isError": true + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "failPoint": { + "configureFailPoint": "failCommand", + "mode": "off" + }, + "client": "setupClient" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "ping": 1 + }, + "commandName": "ping" + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolReadyEvent": {} + }, + "count": 2 + } + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/minPoolSize-error.yml b/test/spec/server-discovery-and-monitoring/unified/minPoolSize-error.yml new file mode 100644 index 0000000000..cc72af578b --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/minPoolSize-error.yml @@ -0,0 +1,125 @@ +--- +description: minPoolSize-error + +schemaVersion: "1.10" + +runOnRequirements: + # failCommand appName requirements + - minServerVersion: "4.9" + serverless: forbid + topologies: + - single + +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false + +initialData: &initialData + - collectionName: &collectionName sdam-minPoolSize-error + databaseName: &databaseName sdam-tests + documents: [] + +tests: + - description: Network error on minPoolSize background creation + operations: + # Configure the initial monitor handshake to succeed but the + # first or second background minPoolSize establishments to fail. + - name: failPoint + object: testRunner + arguments: + client: *setupClient + failPoint: + configureFailPoint: failCommand + mode: + skip: 3 + data: + failCommands: + - hello + - isMaster + appName: SDAMminPoolSizeError + closeConnection: true + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - serverDescriptionChangedEvent + - poolClearedEvent + - poolReadyEvent + uriOptions: + heartbeatFrequencyMS: 10000 + appname: SDAMminPoolSizeError + minPoolSize: 10 + serverSelectionTimeoutMS: 1000 + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Wait for monitor to succeed handshake and mark the pool as ready. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolReadyEvent: {} + count: 1 + # Background connection establishment ensuring minPoolSize should fail, + # causing the pool to be cleared. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 1 + # The server should be marked as Unknown as part of this. + - name: waitForEvent + object: testRunner + arguments: + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown + count: 1 + # Executing a command should fail server selection due to not being able + # to find the primary. + - name: runCommand + object: *database + arguments: + command: + ping: {} + commandName: ping + expectError: + isError: true + # Disable the failpoint, allowing the monitor to discover the primary again. + - name: failPoint + object: testRunner + arguments: + failPoint: + configureFailPoint: failCommand + mode: "off" + client: *setupClient + # Perform an operation to ensure the node is discovered. + - name: runCommand + object: *database + arguments: + command: + ping: 1 + commandName: ping + # Assert that the monitor discovered the primary and mark the pool as ready again. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolReadyEvent: {} + count: 2 diff --git a/test/spec/server-discovery-and-monitoring/integration/pool-cleared-error.json b/test/spec/server-discovery-and-monitoring/unified/pool-cleared-error.json similarity index 60% rename from test/spec/server-discovery-and-monitoring/integration/pool-cleared-error.json rename to test/spec/server-discovery-and-monitoring/unified/pool-cleared-error.json index 52456f9e13..9a7dfd901c 100644 --- a/test/spec/server-discovery-and-monitoring/integration/pool-cleared-error.json +++ b/test/spec/server-discovery-and-monitoring/unified/pool-cleared-error.json @@ -1,25 +1,72 @@ { - "runOn": [ + "description": "pool-cleared-error", + "schemaVersion": "1.10", + "runOnRequirements": [ { "minServerVersion": "4.9", - "topology": [ + "serverless": "forbid", + "topologies": [ "replicaset", "sharded" ] } ], - "database_name": "sdam-tests", - "collection_name": "pool-cleared-error", - "data": [], + "createEntities": [ + { + "client": { + "id": "setupClient", + "useMultipleMongoses": false + } + } + ], + "initialData": [ + { + "collectionName": "pool-cleared-error", + "databaseName": "sdam-tests", + "documents": [] + } + ], "tests": [ { "description": "PoolClearedError does not mark server unknown", - "clientOptions": { - "retryWrites": true, - "maxPoolSize": 1, - "appname": "poolClearedErrorTest" - }, "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "useMultipleMongoses": false, + "observeEvents": [ + "serverDescriptionChangedEvent", + "poolClearedEvent" + ], + "uriOptions": { + "retryWrites": true, + "maxPoolSize": 1, + "appname": "poolClearedErrorTest" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "pool-cleared-error" + } + } + ] + } + }, { "name": "insertOne", "object": "collection", @@ -30,7 +77,7 @@ } }, { - "name": "configureFailPoint", + "name": "failPoint", "object": "testRunner", "arguments": { "failPoint": { @@ -47,56 +94,53 @@ "closeConnection": true, "appName": "poolClearedErrorTest" } - } - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread1" - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread2" - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread3" - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread4" - } - }, - { - "name": "startThread", - "object": "testRunner", - "arguments": { - "name": "thread5" + }, + "client": "setupClient" } }, { - "name": "startThread", + "name": "createEntities", "object": "testRunner", "arguments": { - "name": "thread6" + "entities": [ + { + "thread": { + "id": "thread0" + } + }, + { + "thread": { + "id": "thread1" + } + }, + { + "thread": { + "id": "thread2" + } + }, + { + "thread": { + "id": "thread3" + } + }, + { + "thread": { + "id": "thread4" + } + }, + { + "thread": { + "id": "thread5" + } + } + ] } }, { "name": "runOnThread", "object": "testRunner", "arguments": { - "name": "thread1", + "thread": "thread0", "operation": { "name": "insertOne", "object": "collection", @@ -112,7 +156,7 @@ "name": "runOnThread", "object": "testRunner", "arguments": { - "name": "thread2", + "thread": "thread1", "operation": { "name": "insertOne", "object": "collection", @@ -128,7 +172,7 @@ "name": "runOnThread", "object": "testRunner", "arguments": { - "name": "thread3", + "thread": "thread2", "operation": { "name": "insertOne", "object": "collection", @@ -144,7 +188,7 @@ "name": "runOnThread", "object": "testRunner", "arguments": { - "name": "thread4", + "thread": "thread3", "operation": { "name": "insertOne", "object": "collection", @@ -160,7 +204,7 @@ "name": "runOnThread", "object": "testRunner", "arguments": { - "name": "thread5", + "thread": "thread4", "operation": { "name": "insertOne", "object": "collection", @@ -176,7 +220,7 @@ "name": "runOnThread", "object": "testRunner", "arguments": { - "name": "thread6", + "thread": "thread5", "operation": { "name": "insertOne", "object": "collection", @@ -192,49 +236,56 @@ "name": "waitForThread", "object": "testRunner", "arguments": { - "name": "thread1" + "thread": "thread0" } }, { "name": "waitForThread", "object": "testRunner", "arguments": { - "name": "thread2" + "thread": "thread1" } }, { "name": "waitForThread", "object": "testRunner", "arguments": { - "name": "thread3" + "thread": "thread2" } }, { "name": "waitForThread", "object": "testRunner", "arguments": { - "name": "thread4" + "thread": "thread3" } }, { "name": "waitForThread", "object": "testRunner", "arguments": { - "name": "thread5" + "thread": "thread4" } }, { "name": "waitForThread", "object": "testRunner", "arguments": { - "name": "thread6" + "thread": "thread5" } }, { "name": "waitForEvent", "object": "testRunner", "arguments": { - "event": "ServerMarkedUnknownEvent", + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, "count": 1 } }, @@ -242,7 +293,10 @@ "name": "waitForEvent", "object": "testRunner", "arguments": { - "event": "PoolClearedEvent", + "client": "client", + "event": { + "poolClearedEvent": {} + }, "count": 1 } }, @@ -259,7 +313,14 @@ "name": "assertEventCount", "object": "testRunner", "arguments": { - "event": "ServerMarkedUnknownEvent", + "client": "client", + "event": { + "serverDescriptionChangedEvent": { + "newDescription": { + "type": "Unknown" + } + } + }, "count": 1 } }, @@ -267,14 +328,19 @@ "name": "assertEventCount", "object": "testRunner", "arguments": { - "event": "PoolClearedEvent", + "client": "client", + "event": { + "poolClearedEvent": {} + }, "count": 1 } } ], - "outcome": { - "collection": { - "data": [ + "outcome": [ + { + "collectionName": "pool-cleared-error", + "databaseName": "sdam-tests", + "documents": [ { "_id": 1 }, @@ -301,7 +367,7 @@ } ] } - } + ] } ] } diff --git a/test/spec/server-discovery-and-monitoring/integration/pool-cleared-error.yml b/test/spec/server-discovery-and-monitoring/unified/pool-cleared-error.yml similarity index 54% rename from test/spec/server-discovery-and-monitoring/integration/pool-cleared-error.yml rename to test/spec/server-discovery-and-monitoring/unified/pool-cleared-error.yml index f2e1e04b79..07bfc0c0d5 100644 --- a/test/spec/server-discovery-and-monitoring/integration/pool-cleared-error.yml +++ b/test/spec/server-discovery-and-monitoring/unified/pool-cleared-error.yml @@ -1,67 +1,92 @@ -# Test SDAM error handling. -runOn: +--- +description: pool-cleared-error + +schemaVersion: "1.10" + +runOnRequirements: # This test requires retryable writes, failCommand appName, and # failCommand blockConnection with closeConnection:true (SERVER-53512). - - minServerVersion: "4.9" - topology: ["replicaset", "sharded"] + - minServerVersion: "4.9" + serverless: forbid + topologies: + - replicaset + - sharded -database_name: &database_name "sdam-tests" -collection_name: &collection_name "pool-cleared-error" +createEntities: + - client: + id: &setupClient setupClient + useMultipleMongoses: false -data: [] +initialData: &initialData + - collectionName: &collectionName pool-cleared-error + databaseName: &databaseName sdam-tests + documents: [] tests: - description: PoolClearedError does not mark server unknown - clientOptions: - retryWrites: true - maxPoolSize: 1 - appname: poolClearedErrorTest operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + useMultipleMongoses: false + observeEvents: + - serverDescriptionChangedEvent + - poolClearedEvent + uriOptions: + retryWrites: true + maxPoolSize: 1 + appname: poolClearedErrorTest + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName # Perform an operation to ensure the node is discovered. - name: insertOne - object: collection + object: *collection arguments: document: _id: 1 # Configure the next insert to fail with a network error which will # clear the pool leaving it paused until the server is rediscovered. - - name: configureFailPoint + - name: failPoint object: testRunner arguments: failPoint: configureFailPoint: failCommand - mode: { times: 1 } + mode: + times: 1 data: - failCommands: ["insert"] - blockConnection: true - blockTimeMS: 100 - closeConnection: true - appName: poolClearedErrorTest + failCommands: + - insert + blockConnection: true + blockTimeMS: 100 + closeConnection: true + appName: poolClearedErrorTest + client: *setupClient # Start threads. - - name: startThread - object: testRunner - arguments: - name: thread1 - - name: startThread - object: testRunner - arguments: - name: thread2 - - name: startThread - object: testRunner - arguments: - name: thread3 - - name: startThread - object: testRunner - arguments: - name: thread4 - - name: startThread - object: testRunner - arguments: - name: thread5 - - name: startThread - object: testRunner - arguments: - name: thread6 + - name: createEntities + object: testRunner + arguments: + entities: + - thread: + id: &thread0 thread0 + - thread: + id: &thread1 thread1 + - thread: + id: &thread2 thread2 + - thread: + id: &thread3 thread3 + - thread: + id: &thread4 thread4 + - thread: + id: &thread5 thread5 # Perform concurrent insert operations. The first one to execute will # fail with a network error, mark the server Unknown, clear the pool, # and retry. @@ -75,60 +100,60 @@ tests: - name: runOnThread object: testRunner arguments: - name: thread1 + thread: *thread0 operation: name: insertOne - object: collection + object: *collection arguments: document: _id: 2 - name: runOnThread object: testRunner arguments: - name: thread2 + thread: *thread1 operation: name: insertOne - object: collection + object: *collection arguments: document: _id: 3 - name: runOnThread object: testRunner arguments: - name: thread3 + thread: *thread2 operation: name: insertOne - object: collection + object: *collection arguments: document: _id: 4 - name: runOnThread object: testRunner arguments: - name: thread4 + thread: *thread3 operation: name: insertOne - object: collection + object: *collection arguments: document: _id: 5 - name: runOnThread object: testRunner arguments: - name: thread5 + thread: *thread4 operation: name: insertOne - object: collection + object: *collection arguments: document: _id: 6 - name: runOnThread object: testRunner arguments: - name: thread6 + thread: *thread5 operation: name: insertOne - object: collection + object: *collection arguments: document: _id: 7 @@ -136,42 +161,48 @@ tests: - name: waitForThread object: testRunner arguments: - name: thread1 + thread: *thread0 - name: waitForThread object: testRunner arguments: - name: thread2 + thread: *thread1 - name: waitForThread object: testRunner arguments: - name: thread3 + thread: *thread2 - name: waitForThread object: testRunner arguments: - name: thread4 + thread: *thread3 - name: waitForThread object: testRunner arguments: - name: thread5 + thread: *thread4 - name: waitForThread object: testRunner arguments: - name: thread6 + thread: *thread5 # The first shutdown error should mark the server Unknown and then clear # the pool. - name: waitForEvent object: testRunner arguments: - event: ServerMarkedUnknownEvent + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown count: 1 - name: waitForEvent object: testRunner arguments: - event: PoolClearedEvent + client: *client + event: + poolClearedEvent: {} count: 1 # Perform an operation to ensure the node still useable. - name: insertOne - object: collection + object: *collection arguments: document: _id: 8 @@ -179,23 +210,30 @@ tests: - name: assertEventCount object: testRunner arguments: - event: ServerMarkedUnknownEvent + client: *client + event: + serverDescriptionChangedEvent: + newDescription: + type: Unknown count: 1 - name: assertEventCount object: testRunner arguments: - event: PoolClearedEvent + client: *client + event: + poolClearedEvent: {} count: 1 # Order of operations is non-deterministic so we cannot check events. outcome: - collection: - data: - - {_id: 1} - - {_id: 2} - - {_id: 3} - - {_id: 4} - - {_id: 5} - - {_id: 6} - - {_id: 7} - - {_id: 8} + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 + - _id: 5 + - _id: 6 + - _id: 7 + - _id: 8 diff --git a/test/spec/server-discovery-and-monitoring/unified/rediscover-quickly-after-step-down.json b/test/spec/server-discovery-and-monitoring/unified/rediscover-quickly-after-step-down.json new file mode 100644 index 0000000000..c7c2494857 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/rediscover-quickly-after-step-down.json @@ -0,0 +1,242 @@ +{ + "description": "rediscover-quickly-after-step-down", + "schemaVersion": "1.10", + "runOnRequirements": [ + { + "minServerVersion": "4.4", + "serverless": "forbid", + "topologies": [ + "replicaset" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "setupClient" + } + }, + { + "database": { + "id": "adminDatabase", + "client": "setupClient", + "databaseName": "admin" + } + } + ], + "initialData": [ + { + "collectionName": "test-replSetStepDown", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ], + "tests": [ + { + "description": "Rediscover quickly after replSetStepDown", + "operations": [ + { + "name": "createEntities", + "object": "testRunner", + "arguments": { + "entities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "poolClearedEvent", + "commandStartedEvent" + ], + "uriOptions": { + "appname": "replSetStepDownTest", + "heartbeatFrequencyMS": 60000, + "serverSelectionTimeoutMS": 5000, + "w": "majority" + } + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "sdam-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "test-replSetStepDown" + } + } + ] + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + } + }, + { + "name": "recordTopologyDescription", + "object": "testRunner", + "arguments": { + "client": "client", + "id": "topologyDescription" + } + }, + { + "name": "assertTopologyType", + "object": "testRunner", + "arguments": { + "topologyDescription": "topologyDescription", + "topologyType": "ReplicaSetWithPrimary" + } + }, + { + "name": "runCommand", + "object": "adminDatabase", + "arguments": { + "command": { + "replSetFreeze": 0 + }, + "readPreference": { + "mode": "secondary" + }, + "commandName": "replSetFreeze" + } + }, + { + "name": "runCommand", + "object": "adminDatabase", + "arguments": { + "command": { + "replSetStepDown": 30, + "secondaryCatchUpPeriodSecs": 30, + "force": false + }, + "commandName": "replSetStepDown" + } + }, + { + "name": "waitForPrimaryChange", + "object": "testRunner", + "arguments": { + "client": "client", + "priorTopologyDescription": "topologyDescription", + "timeoutMS": 15000 + } + }, + { + "name": "insertMany", + "object": "collection", + "arguments": { + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + }, + { + "name": "assertEventCount", + "object": "testRunner", + "arguments": { + "client": "client", + "event": { + "poolClearedEvent": {} + }, + "count": 0 + } + } + ], + "expectEvents": [ + { + "client": "client", + "eventType": "command", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test-replSetStepDown", + "documents": [ + { + "_id": 3 + }, + { + "_id": 4 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test-replSetStepDown", + "documents": [ + { + "_id": 5 + }, + { + "_id": 6 + } + ] + }, + "commandName": "insert", + "databaseName": "sdam-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test-replSetStepDown", + "databaseName": "sdam-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + }, + { + "_id": 4 + }, + { + "_id": 5 + }, + { + "_id": 6 + } + ] + } + ] + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/unified/rediscover-quickly-after-step-down.yml b/test/spec/server-discovery-and-monitoring/unified/rediscover-quickly-after-step-down.yml new file mode 100644 index 0000000000..e5b49de35d --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/unified/rediscover-quickly-after-step-down.yml @@ -0,0 +1,144 @@ +--- +description: rediscover-quickly-after-step-down + +schemaVersion: "1.10" + +runOnRequirements: + # 4.4 is required for streaming. + # A replica set is required for replSetStepDown. + - minServerVersion: "4.4" + serverless: forbid + topologies: + - replicaset + +createEntities: + - client: + id: &setupClient setupClient + - database: + id: &adminDatabase adminDatabase + client: *setupClient + databaseName: admin + +initialData: &initialData + - collectionName: &collectionName test-replSetStepDown + databaseName: &databaseName sdam-tests + documents: + - _id: 1 + - _id: 2 + +tests: + - description: Rediscover quickly after replSetStepDown + operations: + - name: createEntities + object: testRunner + arguments: + entities: + - client: + id: &client client + observeEvents: + - poolClearedEvent + - commandStartedEvent + uriOptions: + appname: replSetStepDownTest + # Configure a large heartbeatFrequencyMS + heartbeatFrequencyMS: 60000 + # Configure a much smaller server selection timeout so that the test + # will error when it cannot discover the new primary soon. + serverSelectionTimeoutMS: 5000 + w: majority + - database: + id: &database database + client: *client + databaseName: *databaseName + - collection: + id: &collection collection + database: *database + collectionName: *collectionName + # Discover the primary. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 3 + - _id: 4 + - name: recordTopologyDescription + object: testRunner + arguments: + client: *client + id: &topologyDescription topologyDescription + - name: assertTopologyType + object: testRunner + arguments: + topologyDescription: *topologyDescription + topologyType: ReplicaSetWithPrimary + # Unfreeze a secondary with replSetFreeze:0 to ensure a speedy election. + - name: runCommand + object: *adminDatabase + arguments: + command: + replSetFreeze: 0 + readPreference: + mode: secondary + commandName: replSetFreeze + # Run replSetStepDown on the meta client. + - name: runCommand + object: *adminDatabase + arguments: + command: + replSetStepDown: 30 + secondaryCatchUpPeriodSecs: 30 + force: false + commandName: replSetStepDown + - name: waitForPrimaryChange + object: testRunner + arguments: + client: *client + priorTopologyDescription: *topologyDescription + # We use a relatively large timeout here to workaround slow + # elections on Windows, possibly caused by SERVER-48154. + timeoutMS: 15000 + # Rediscover the new primary. + - name: insertMany + object: *collection + arguments: + documents: + - _id: 5 + - _id: 6 + # Assert that no pools were cleared. + - name: assertEventCount + object: testRunner + arguments: + client: *client + event: + poolClearedEvent: {} + count: 0 + expectEvents: + - client: *client + eventType: command + events: + - commandStartedEvent: + command: + insert: test-replSetStepDown + documents: + - _id: 3 + - _id: 4 + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: test-replSetStepDown + documents: + - _id: 5 + - _id: 6 + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - _id: 1 + - _id: 2 + - _id: 3 + - _id: 4 + - _id: 5 + - _id: 6 diff --git a/test/spec/unified-test-format/invalid/collectionData-additionalProperties.json b/test/spec/unified-test-format/invalid/collectionData-additionalProperties.json index 2d85093109..1f4ed4c154 100644 --- a/test/spec/unified-test-format/invalid/collectionData-additionalProperties.json +++ b/test/spec/unified-test-format/invalid/collectionData-additionalProperties.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-additionalProperties.yml b/test/spec/unified-test-format/invalid/collectionData-additionalProperties.yml index 6a2256a639..62a4a81b6a 100644 --- a/test/spec/unified-test-format/invalid/collectionData-additionalProperties.yml +++ b/test/spec/unified-test-format/invalid/collectionData-additionalProperties.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: *collection0Name diff --git a/test/spec/unified-test-format/invalid/collectionData-collectionName-required.json b/test/spec/unified-test-format/invalid/collectionData-collectionName-required.json index 040dd86a1c..5426418c88 100644 --- a/test/spec/unified-test-format/invalid/collectionData-collectionName-required.json +++ b/test/spec/unified-test-format/invalid/collectionData-collectionName-required.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-collectionName-required.yml b/test/spec/unified-test-format/invalid/collectionData-collectionName-required.yml index 2f20805581..f8da422eab 100644 --- a/test/spec/unified-test-format/invalid/collectionData-collectionName-required.yml +++ b/test/spec/unified-test-format/invalid/collectionData-collectionName-required.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - databaseName: *database0Name diff --git a/test/spec/unified-test-format/invalid/collectionData-collectionName-type.json b/test/spec/unified-test-format/invalid/collectionData-collectionName-type.json index 676d822e5e..2a922de13e 100644 --- a/test/spec/unified-test-format/invalid/collectionData-collectionName-type.json +++ b/test/spec/unified-test-format/invalid/collectionData-collectionName-type.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-collectionName-type.yml b/test/spec/unified-test-format/invalid/collectionData-collectionName-type.yml index a9da0e0129..d14ecb5fab 100644 --- a/test/spec/unified-test-format/invalid/collectionData-collectionName-type.yml +++ b/test/spec/unified-test-format/invalid/collectionData-collectionName-type.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: 0 diff --git a/test/spec/unified-test-format/invalid/collectionData-createOptions-type.json b/test/spec/unified-test-format/invalid/collectionData-createOptions-type.json new file mode 100644 index 0000000000..5b78bbcbb6 --- /dev/null +++ b/test/spec/unified-test-format/invalid/collectionData-createOptions-type.json @@ -0,0 +1,39 @@ +{ + "description": "collectionData-createOptions-type", + "schemaVersion": "1.9", + "createEntities": [ + { + "client": { + "id": "client0" + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "foo" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "foo" + } + } + ], + "initialData": [ + { + "collectionName": "foo", + "databaseName": "foo", + "createOptions": 0, + "documents": [] + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/collectionData-createOptions-type.yml b/test/spec/unified-test-format/invalid/collectionData-createOptions-type.yml new file mode 100644 index 0000000000..5bc17a15f9 --- /dev/null +++ b/test/spec/unified-test-format/invalid/collectionData-createOptions-type.yml @@ -0,0 +1,25 @@ +description: "collectionData-createOptions-type" + +schemaVersion: "1.9" + +createEntities: + - client: + id: &client0 "client0" + - database: + id: &database0 "database0" + client: *client0 + databaseName: &database0Name "foo" + - collection: + id: &collection0 "collection0" + database: *database0 + collectionName: &collection0Name "foo" + +initialData: + - collectionName: *collection0Name + databaseName: *database0Name + createOptions: 0 + documents: [] + +tests: + - description: "foo" + operations: [] diff --git a/test/spec/unified-test-format/invalid/collectionData-databaseName-required.json b/test/spec/unified-test-format/invalid/collectionData-databaseName-required.json index 7548f9d5be..8417801390 100644 --- a/test/spec/unified-test-format/invalid/collectionData-databaseName-required.json +++ b/test/spec/unified-test-format/invalid/collectionData-databaseName-required.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-databaseName-required.yml b/test/spec/unified-test-format/invalid/collectionData-databaseName-required.yml index d8d6e4d571..595ae798e8 100644 --- a/test/spec/unified-test-format/invalid/collectionData-databaseName-required.yml +++ b/test/spec/unified-test-format/invalid/collectionData-databaseName-required.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: *collection0Name diff --git a/test/spec/unified-test-format/invalid/collectionData-databaseName-type.json b/test/spec/unified-test-format/invalid/collectionData-databaseName-type.json index ef719bbf6a..d3480e8034 100644 --- a/test/spec/unified-test-format/invalid/collectionData-databaseName-type.json +++ b/test/spec/unified-test-format/invalid/collectionData-databaseName-type.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-databaseName-type.yml b/test/spec/unified-test-format/invalid/collectionData-databaseName-type.yml index 27dfaafee1..bc5b47fe1b 100644 --- a/test/spec/unified-test-format/invalid/collectionData-databaseName-type.yml +++ b/test/spec/unified-test-format/invalid/collectionData-databaseName-type.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: *collection0Name diff --git a/test/spec/unified-test-format/invalid/collectionData-documents-items.json b/test/spec/unified-test-format/invalid/collectionData-documents-items.json index 2916718d50..beb5af61c4 100644 --- a/test/spec/unified-test-format/invalid/collectionData-documents-items.json +++ b/test/spec/unified-test-format/invalid/collectionData-documents-items.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-documents-items.yml b/test/spec/unified-test-format/invalid/collectionData-documents-items.yml index 6e860e896f..f129ee371a 100644 --- a/test/spec/unified-test-format/invalid/collectionData-documents-items.yml +++ b/test/spec/unified-test-format/invalid/collectionData-documents-items.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: *collection0Name diff --git a/test/spec/unified-test-format/invalid/collectionData-documents-required.json b/test/spec/unified-test-format/invalid/collectionData-documents-required.json index 7b8a7ead2a..4aadf9b159 100644 --- a/test/spec/unified-test-format/invalid/collectionData-documents-required.json +++ b/test/spec/unified-test-format/invalid/collectionData-documents-required.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-documents-required.yml b/test/spec/unified-test-format/invalid/collectionData-documents-required.yml index 0452842bc7..b275e7610c 100644 --- a/test/spec/unified-test-format/invalid/collectionData-documents-required.yml +++ b/test/spec/unified-test-format/invalid/collectionData-documents-required.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: *collection0Name diff --git a/test/spec/unified-test-format/invalid/collectionData-documents-type.json b/test/spec/unified-test-format/invalid/collectionData-documents-type.json index 953cabae6e..9cbd3c164c 100644 --- a/test/spec/unified-test-format/invalid/collectionData-documents-type.json +++ b/test/spec/unified-test-format/invalid/collectionData-documents-type.json @@ -18,8 +18,7 @@ "collection": { "id": "collection0", "database": "database0", - "collectionName": "foo", - "foo": 0 + "collectionName": "foo" } } ], diff --git a/test/spec/unified-test-format/invalid/collectionData-documents-type.yml b/test/spec/unified-test-format/invalid/collectionData-documents-type.yml index db6d8b417a..a51a506508 100644 --- a/test/spec/unified-test-format/invalid/collectionData-documents-type.yml +++ b/test/spec/unified-test-format/invalid/collectionData-documents-type.yml @@ -13,7 +13,6 @@ createEntities: id: &collection0 "collection0" database: *database0 collectionName: &collection0Name "foo" - foo: 0 initialData: - collectionName: *collection0Name diff --git a/test/spec/unified-test-format/invalid/collectionOrDatabaseOptions-timeoutMS-type.json b/test/spec/unified-test-format/invalid/collectionOrDatabaseOptions-timeoutMS-type.json new file mode 100644 index 0000000000..088e9d1eb2 --- /dev/null +++ b/test/spec/unified-test-format/invalid/collectionOrDatabaseOptions-timeoutMS-type.json @@ -0,0 +1,27 @@ +{ + "description": "collectionOrDatabaseOptions-timeoutMS-type", + "schemaVersion": "1.9", + "createEntities": [ + { + "client": { + "id": "client0" + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "foo", + "databaseOptions": { + "timeoutMS": 4.5 + } + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/collectionOrDatabaseOptions-timeoutMS-type.yml b/test/spec/unified-test-format/invalid/collectionOrDatabaseOptions-timeoutMS-type.yml new file mode 100644 index 0000000000..6a24053583 --- /dev/null +++ b/test/spec/unified-test-format/invalid/collectionOrDatabaseOptions-timeoutMS-type.yml @@ -0,0 +1,17 @@ +description: "collectionOrDatabaseOptions-timeoutMS-type" + +schemaVersion: "1.9" + +createEntities: + - client: + id: &client0 "client0" + - database: + id: &database0 "database0" + client: *client0 + databaseName: "foo" + databaseOptions: + timeoutMS: 4.5 # Must be an integer, not a float. + +tests: + - description: "foo" + operations: [] diff --git a/test/spec/unified-test-format/invalid/entity-thread-additionalProperties.json b/test/spec/unified-test-format/invalid/entity-thread-additionalProperties.json new file mode 100644 index 0000000000..b296719f13 --- /dev/null +++ b/test/spec/unified-test-format/invalid/entity-thread-additionalProperties.json @@ -0,0 +1,18 @@ +{ + "description": "entity-thread-additionalProperties", + "schemaVersion": "1.10", + "createEntities": [ + { + "thread": { + "id": "thread0", + "foo": "bar" + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/entity-thread-additionalProperties.yml b/test/spec/unified-test-format/invalid/entity-thread-additionalProperties.yml new file mode 100644 index 0000000000..b3fb1dc514 --- /dev/null +++ b/test/spec/unified-test-format/invalid/entity-thread-additionalProperties.yml @@ -0,0 +1,12 @@ +description: "entity-thread-additionalProperties" + +schemaVersion: "1.10" + +createEntities: + - thread: + id: &thread0 "thread0" + foo: "bar" + +tests: + - description: "foo" + operations: [] diff --git a/test/spec/unified-test-format/invalid/entity-thread-id-required.json b/test/spec/unified-test-format/invalid/entity-thread-id-required.json new file mode 100644 index 0000000000..3b197e3d6b --- /dev/null +++ b/test/spec/unified-test-format/invalid/entity-thread-id-required.json @@ -0,0 +1,15 @@ +{ + "description": "entity-thread-id-required", + "schemaVersion": "1.10", + "createEntities": [ + { + "thread": {} + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/entity-thread-id-required.yml b/test/spec/unified-test-format/invalid/entity-thread-id-required.yml new file mode 100644 index 0000000000..b940d4d5c6 --- /dev/null +++ b/test/spec/unified-test-format/invalid/entity-thread-id-required.yml @@ -0,0 +1,10 @@ +description: "entity-thread-id-required" + +schemaVersion: "1.10" + +createEntities: + - thread: {} + +tests: + - description: "foo" + operations: [] diff --git a/test/spec/unified-test-format/invalid/entity-thread-id-type.json b/test/spec/unified-test-format/invalid/entity-thread-id-type.json new file mode 100644 index 0000000000..8f281ef6f4 --- /dev/null +++ b/test/spec/unified-test-format/invalid/entity-thread-id-type.json @@ -0,0 +1,17 @@ +{ + "description": "entity-thread-id-type", + "schemaVersion": "1.10", + "createEntities": [ + { + "thread": { + "id": 0 + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/entity-thread-id-type.yml b/test/spec/unified-test-format/invalid/entity-thread-id-type.yml new file mode 100644 index 0000000000..85646ce9c0 --- /dev/null +++ b/test/spec/unified-test-format/invalid/entity-thread-id-type.yml @@ -0,0 +1,11 @@ +description: "entity-thread-id-type" + +schemaVersion: "1.10" + +createEntities: + - thread: + id: 0 + +tests: + - description: "foo" + operations: [] diff --git a/test/spec/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type.json b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type.json new file mode 100644 index 0000000000..7787ea6516 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type.json @@ -0,0 +1,29 @@ +{ + "description": "expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type", + "schemaVersion": "1.6", + "createEntities": [ + { + "client": { + "id": "client0" + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandFailedEvent": { + "hasServerConnectionId": "foo" + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type.yml b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type.yml new file mode 100644 index 0000000000..3940147192 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type.yml @@ -0,0 +1,16 @@ +description: expectedCommandEvent-commandFailedEvent-hasServerConnectionId-type + +schemaVersion: '1.6' + +createEntities: + - client: + id: &client0 client0 + +tests: + - description: foo + operations: [] + expectEvents: + - client: *client0 + events: + - commandFailedEvent: + hasServerConnectionId: foo diff --git a/test/spec/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type.json b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type.json new file mode 100644 index 0000000000..a913f00ab7 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type.json @@ -0,0 +1,29 @@ +{ + "description": "expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type", + "schemaVersion": "1.6", + "createEntities": [ + { + "client": { + "id": "client0" + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "hasServerConnectionId": "foo" + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type.yml b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type.yml new file mode 100644 index 0000000000..a78e6aac45 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type.yml @@ -0,0 +1,16 @@ +description: expectedCommandEvent-commandStartedEvent-hasServerConnectionId-type + +schemaVersion: '1.6' + +createEntities: + - client: + id: &client0 client0 + +tests: + - description: foo + operations: [] + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + hasServerConnectionId: foo diff --git a/test/spec/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type.json b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type.json new file mode 100644 index 0000000000..0712c33694 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type.json @@ -0,0 +1,29 @@ +{ + "description": "expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type", + "schemaVersion": "1.6", + "createEntities": [ + { + "client": { + "id": "client0" + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandSucceededEvent": { + "hasServerConnectionId": "foo" + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type.yml b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type.yml new file mode 100644 index 0000000000..6b2219f6db --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type.yml @@ -0,0 +1,16 @@ +description: expectedCommandEvent-commandSucceededEvent-hasServerConnectionId-type + +schemaVersion: '1.6' + +createEntities: + - client: + id: &client0 client0 + +tests: + - description: foo + operations: [] + expectEvents: + - client: *client0 + events: + - commandSucceededEvent: + hasServerConnectionId: foo diff --git a/test/spec/unified-test-format/invalid/expectedError-isTimeoutError-type.json b/test/spec/unified-test-format/invalid/expectedError-isTimeoutError-type.json new file mode 100644 index 0000000000..5683911d0d --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedError-isTimeoutError-type.json @@ -0,0 +1,25 @@ +{ + "description": "expectedError-isTimeoutError-type", + "schemaVersion": "1.9", + "createEntities": [ + { + "client": { + "id": "client0" + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [ + { + "name": "foo", + "object": "client0", + "expectError": { + "isTimeoutError": 0 + } + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedError-isTimeoutError-type.yml b/test/spec/unified-test-format/invalid/expectedError-isTimeoutError-type.yml new file mode 100644 index 0000000000..9d9db95350 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedError-isTimeoutError-type.yml @@ -0,0 +1,15 @@ +description: "expectedError-isTimeoutError-type" + +schemaVersion: "1.9" + +createEntities: + - client: + id: &client0 "client0" + +tests: + - description: "foo" + operations: + - name: "foo" + object: *client0 + expectError: + isTimeoutError: 0 diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties.json b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties.json new file mode 100644 index 0000000000..1c6ec460b7 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties", + "schemaVersion": "1.10", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "sdam", + "events": [ + { + "serverDescriptionChangedEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties.yml b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties.yml new file mode 100644 index 0000000000..7d9580fe71 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties.yml @@ -0,0 +1,13 @@ +description: expectedSdamEvent-serverDescriptionChangedEvent-additionalProperties + +schemaVersion: '1.10' + +tests: + - description: foo + operations: [] + expectEvents: + - client: client0 + eventType: sdam + events: + - serverDescriptionChangedEvent: + foo: bar diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties.json b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties.json new file mode 100644 index 0000000000..58f686739a --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties.json @@ -0,0 +1,25 @@ +{ + "description": "expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties", + "schemaVersion": "1.10", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "sdam", + "events": [ + { + "serverDescriptionChangedEvent": { + "previousDescription": { + "foo": "bar" + } + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties.yml b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties.yml new file mode 100644 index 0000000000..4f5d744220 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties.yml @@ -0,0 +1,14 @@ +description: expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-additionalProperties + +schemaVersion: '1.10' + +tests: + - description: foo + operations: [] + expectEvents: + - client: client0 + eventType: sdam + events: + - serverDescriptionChangedEvent: + previousDescription: + foo: bar diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum.json b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum.json new file mode 100644 index 0000000000..1b4a7e2e70 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum.json @@ -0,0 +1,25 @@ +{ + "description": "expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum", + "schemaVersion": "1.10", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "sdam", + "events": [ + { + "serverDescriptionChangedEvent": { + "previousDescription": { + "type": "not a server type" + } + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum.yml b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum.yml new file mode 100644 index 0000000000..5211cde784 --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum.yml @@ -0,0 +1,14 @@ +description: expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-enum + +schemaVersion: '1.10' + +tests: + - description: foo + operations: [] + expectEvents: + - client: client0 + eventType: sdam + events: + - serverDescriptionChangedEvent: + previousDescription: + type: "not a server type" diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type.json b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type.json new file mode 100644 index 0000000000..c7ea9cc9be --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type.json @@ -0,0 +1,25 @@ +{ + "description": "expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type", + "schemaVersion": "1.10", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "sdam", + "events": [ + { + "serverDescriptionChangedEvent": { + "previousDescription": { + "type": 12 + } + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type.yml b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type.yml new file mode 100644 index 0000000000..3f856bbdae --- /dev/null +++ b/test/spec/unified-test-format/invalid/expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type.yml @@ -0,0 +1,14 @@ +description: expectedSdamEvent-serverDescriptionChangedEvent-serverDescription-type-type + +schemaVersion: '1.10' + +tests: + - description: foo + operations: [] + expectEvents: + - client: client0 + eventType: sdam + events: + - serverDescriptionChangedEvent: + previousDescription: + type: 12 diff --git a/test/spec/unified-test-format/invalid/runOnRequirement-csfle-type.json b/test/spec/unified-test-format/invalid/runOnRequirement-csfle-type.json new file mode 100644 index 0000000000..b48c850d14 --- /dev/null +++ b/test/spec/unified-test-format/invalid/runOnRequirement-csfle-type.json @@ -0,0 +1,15 @@ +{ + "description": "runOnRequirement-csfle-type", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": "foo" + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/spec/unified-test-format/invalid/runOnRequirement-csfle-type.yml b/test/spec/unified-test-format/invalid/runOnRequirement-csfle-type.yml new file mode 100644 index 0000000000..c82bba410d --- /dev/null +++ b/test/spec/unified-test-format/invalid/runOnRequirement-csfle-type.yml @@ -0,0 +1,10 @@ +description: "runOnRequirement-csfle-type" + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: foo + +tests: + - description: "foo" + operations: [] diff --git a/test/tools/unified-spec-runner/entities.ts b/test/tools/unified-spec-runner/entities.ts index 7afb4d30a2..8173a8cd4e 100644 --- a/test/tools/unified-spec-runner/entities.ts +++ b/test/tools/unified-spec-runner/entities.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { expect } from 'chai'; +import { EventEmitter } from 'events'; import { ChangeStream } from '../../../src/change_stream'; import { @@ -27,7 +28,9 @@ import { GridFSBucket, HostAddress, MongoClient, - MongoCredentials + MongoCredentials, + ServerDescriptionChangedEvent, + TopologyDescription } from '../../../src/index'; import { ReadConcern } from '../../../src/read_concern'; import { ReadPreference } from '../../../src/read_preference'; @@ -48,6 +51,37 @@ export interface UnifiedChangeStream extends ChangeStream { eventCollector: InstanceType; } +export class UnifiedThread { + // Every function queued will have a catch handler attached to it, which will prevent `await this.#promise` from throwing + // The potential error thrown by the functionToQueue can still be inspected on the `this.#error` property + #promise: Promise; + #error: Error | null = null; + #killed = false; + + id: string; + + constructor(id) { + this.id = id; + this.#promise = Promise.resolve(); + } + + queue(functionToQueue: () => Promise) { + if (this.#killed || this.#error) { + return; + } + + this.#promise = this.#promise.then(functionToQueue).catch(e => (this.#error = e)); + } + + async finish() { + this.#killed = true; + await this.#promise; + if (this.#error) { + throw this.#error; + } + } +} + export type CommandEvent = CommandStartedEvent | CommandSucceededEvent | CommandFailedEvent; export type CmapEvent = | ConnectionPoolCreatedEvent @@ -60,15 +94,17 @@ export type CmapEvent = | ConnectionCheckedOutEvent | ConnectionCheckedInEvent | ConnectionPoolClearedEvent; +export type SdamEvent = ServerDescriptionChangedEvent; function getClient(address) { return new MongoClient(`mongodb://${address}`, getEnvironmentalOptions()); } export class UnifiedMongoClient extends MongoClient { - commandEvents: CommandEvent[]; - cmapEvents: CmapEvent[]; - failPoints: Document[]; + commandEvents: CommandEvent[] = []; + cmapEvents: CmapEvent[] = []; + sdamEvents: SdamEvent[] = []; + failPoints: Document[] = []; ignoredEvents: string[]; observedCommandEvents: ('commandStarted' | 'commandSucceeded' | 'commandFailed')[]; observedCmapEvents: ( @@ -83,6 +119,8 @@ export class UnifiedMongoClient extends MongoClient { | 'connectionCheckedOut' | 'connectionCheckedIn' )[]; + observedSdamEvents: 'serverDescriptionChangedEvent'[]; + observedEventEmitter = new EventEmitter(); _credentials: MongoCredentials | null; static COMMAND_EVENT_NAME_LOOKUP = { @@ -104,6 +142,10 @@ export class UnifiedMongoClient extends MongoClient { connectionCheckedInEvent: 'connectionCheckedIn' } as const; + static SDAM_EVENT_NAME_LOOKUP = { + serverDescriptionChangedEvent: 'serverDescriptionChanged' + } as const; + constructor(uri: string, description: ClientEntity) { super(uri, { monitorCommands: true, @@ -112,9 +154,6 @@ export class UnifiedMongoClient extends MongoClient { ...(description.serverApi ? { serverApi: description.serverApi } : {}) }); - this.commandEvents = []; - this.cmapEvents = []; - this.failPoints = []; this.ignoredEvents = [ ...(description.ignoreCommandMonitoringEvents ?? []), 'configureFailPoint' @@ -126,24 +165,40 @@ export class UnifiedMongoClient extends MongoClient { this.observedCmapEvents = (description.observeEvents ?? []) .map(e => UnifiedMongoClient.CMAP_EVENT_NAME_LOOKUP[e]) .filter(e => !!e); + this.observedSdamEvents = (description.observeEvents ?? []) + .map(e => UnifiedMongoClient.SDAM_EVENT_NAME_LOOKUP[e]) + .filter(e => !!e); for (const eventName of this.observedCommandEvents) { this.on(eventName, this.pushCommandEvent); } for (const eventName of this.observedCmapEvents) { this.on(eventName, this.pushCmapEvent); } + for (const eventName of this.observedSdamEvents) { + this.on(eventName, this.pushSdamEvent); + } } isIgnored(e: CommandEvent): boolean { return this.ignoredEvents.includes(e.commandName); } - getCapturedEvents(eventType: string): CommandEvent[] | CmapEvent[] { + getCapturedEvents( + eventType: 'command' | 'cmap' | 'sdam' + ): CommandEvent[] | CmapEvent[] | SdamEvent[]; + getCapturedEvents(eventType: 'all'): (CommandEvent | CmapEvent | SdamEvent)[]; + getCapturedEvents( + eventType: 'command' | 'cmap' | 'sdam' | 'all' + ): (CommandEvent | CmapEvent | SdamEvent)[] { switch (eventType) { case 'command': return this.commandEvents; case 'cmap': return this.cmapEvents; + case 'sdam': + return this.sdamEvents; + case 'all': + return [...this.commandEvents, ...this.cmapEvents, ...this.sdamEvents]; default: throw new Error(`Unknown eventType: ${eventType}`); } @@ -153,12 +208,20 @@ export class UnifiedMongoClient extends MongoClient { pushCommandEvent: (e: CommandEvent) => void = e => { if (!this.isIgnored(e)) { this.commandEvents.push(e); + this.observedEventEmitter.emit('observedEvent'); } }; // NOTE: pushCmapEvent must be an arrow function pushCmapEvent: (e: CmapEvent) => void = e => { this.cmapEvents.push(e); + this.observedEventEmitter.emit('observedEvent'); + }; + + // NOTE: pushSdamEvent must be an arrow function + pushSdamEvent: (e: SdamEvent) => void = e => { + this.sdamEvents.push(e); + this.observedEventEmitter.emit('observedEvent'); }; /** Disables command monitoring for the client and returns a list of the captured events. */ @@ -169,6 +232,9 @@ export class UnifiedMongoClient extends MongoClient { for (const eventName of this.observedCmapEvents) { this.off(eventName, this.pushCmapEvent); } + for (const eventName of this.observedSdamEvents) { + this.off(eventName, this.pushSdamEvent); + } } } @@ -239,6 +305,7 @@ export type Entity = | UnifiedChangeStream | GridFSBucket | ClientEncryption + | TopologyDescription // From recordTopologyDescription operation | Document; // Results from operations export type EntityCtor = @@ -249,6 +316,7 @@ export type EntityCtor = | typeof ChangeStream | typeof AbstractCursor | typeof GridFSBucket + | typeof UnifiedThread | ClientEncryption; export type EntityTypeId = @@ -257,6 +325,7 @@ export type EntityTypeId = | 'collection' | 'session' | 'bucket' + | 'thread' | 'cursor' | 'stream' | 'clientEncryption'; @@ -267,6 +336,7 @@ ENTITY_CTORS.set('db', Db); ENTITY_CTORS.set('collection', Collection); ENTITY_CTORS.set('session', ClientSession); ENTITY_CTORS.set('bucket', GridFSBucket); +ENTITY_CTORS.set('thread', UnifiedThread); ENTITY_CTORS.set('cursor', AbstractCursor); ENTITY_CTORS.set('stream', ChangeStream); @@ -299,6 +369,7 @@ export class EntitiesMap extends Map { getEntity(type: 'collection', key: string, assertExists?: boolean): Collection; getEntity(type: 'session', key: string, assertExists?: boolean): ClientSession; getEntity(type: 'bucket', key: string, assertExists?: boolean): GridFSBucket; + getEntity(type: 'thread', key: string, assertExists?: boolean): UnifiedThread; getEntity(type: 'cursor', key: string, assertExists?: boolean): AbstractCursor; getEntity(type: 'stream', key: string, assertExists?: boolean): UnifiedChangeStream; getEntity(type: 'clientEncryption', key: string, assertExists?: boolean): ClientEncryption; @@ -351,9 +422,10 @@ export class EntitiesMap extends Map { static async createEntities( config: TestConfiguration, - entities?: EntityDescription[] + entities?: EntityDescription[], + entityMap?: EntitiesMap ): Promise { - const map = new EntitiesMap(); + const map = entityMap ?? new EntitiesMap(); for (const entity of entities ?? []) { if ('client' in entity) { const useMultipleMongoses = @@ -437,6 +509,8 @@ export class EntitiesMap extends Map { } map.set(entity.bucket.id, new GridFSBucket(db, options)); + } else if ('thread' in entity) { + map.set(entity.thread.id, new UnifiedThread(entity.thread.id)); } else if ('stream' in entity) { throw new Error(`Unsupported Entity ${JSON.stringify(entity)}`); } else if ('clientEncryption' in entity) { diff --git a/test/tools/unified-spec-runner/match.ts b/test/tools/unified-spec-runner/match.ts index 4aaad51a8e..123c57f50a 100644 --- a/test/tools/unified-spec-runner/match.ts +++ b/test/tools/unified-spec-runner/match.ts @@ -10,7 +10,8 @@ import { MongoError, MongoServerError, ObjectId, - OneOrMore + OneOrMore, + ServerDescriptionChangedEvent } from '../../../src'; import { CommandFailedEvent, @@ -30,12 +31,13 @@ import { ConnectionReadyEvent } from '../../../src/cmap/connection_pool_events'; import { ejson } from '../utils'; -import { CmapEvent, CommandEvent, EntitiesMap } from './entities'; +import { CmapEvent, CommandEvent, EntitiesMap, SdamEvent } from './entities'; import { ExpectedCmapEvent, ExpectedCommandEvent, ExpectedError, - ExpectedEventsForClient + ExpectedEventsForClient, + ExpectedSdamEvent } from './schema'; export interface ExistsOperator { @@ -338,18 +340,14 @@ const EMPTY_CMAP_EVENTS = { connectionCheckedInEvent: ConnectionCheckedInEvent }; -function validEmptyCmapEvent( - expected: ExpectedCommandEvent | ExpectedCmapEvent, - actual: CommandEvent | CmapEvent -) { - return Object.values(EMPTY_CMAP_EVENTS).some(value => { - return actual instanceof value; - }); +function validEmptyCmapEvent(expected: ExpectedCommandEvent | ExpectedCmapEvent) { + const expectedEventName = Object.keys(expected)[0]; + return !!EMPTY_CMAP_EVENTS[expectedEventName]; } function failOnMismatchedCount( - actual: CommandEvent[] | CmapEvent[], - expected: (ExpectedCommandEvent & ExpectedCmapEvent)[] + actual: CommandEvent[] | CmapEvent[] | SdamEvent[], + expected: (ExpectedCommandEvent & ExpectedCmapEvent & ExpectedSdamEvent)[] ) { const actualNames = actual.map(a => a.constructor.name); const expectedNames = expected.map(e => Object.keys(e)[0]); @@ -423,8 +421,8 @@ function compareCommandFailedEvents( } function compareEvents( - actual: CommandEvent[] | CmapEvent[], - expected: (ExpectedCommandEvent & ExpectedCmapEvent)[], + actual: CommandEvent[] | CmapEvent[] | SdamEvent[], + expected: (ExpectedCommandEvent & ExpectedCmapEvent & ExpectedSdamEvent)[], entities: EntitiesMap ) { if (actual.length !== expected.length) { @@ -467,7 +465,27 @@ function compareEvents( if (expectedEvent.poolClearedEvent.hasServiceId) { expect(actualEvent).property('serviceId').to.exist; } - } else if (validEmptyCmapEvent(expectedEvent, actualEvent)) { + } else if (validEmptyCmapEvent(expectedEvent as ExpectedCmapEvent)) { + const expectedEventName = Object.keys(expectedEvent)[0]; + const expectedEventInstance = EMPTY_CMAP_EVENTS[expectedEventName]; + expect(actualEvent).to.be.instanceOf(expectedEventInstance); + } else if (expectedEvent.serverDescriptionChangedEvent) { + expect(actualEvent).to.be.instanceOf(ServerDescriptionChangedEvent); + const expectedServerDescriptionKeys = ['previousDescription', 'newDescription']; + expect(expectedServerDescriptionKeys).to.include.all.members( + Object.keys(expectedEvent.serverDescriptionChangedEvent) + ); + for (const descriptionKey of expectedServerDescriptionKeys) { + expect(actualEvent).to.have.property(descriptionKey); + const expectedDescription = + expectedEvent.serverDescriptionChangedEvent[descriptionKey] ?? {}; + for (const nestedKey of Object.keys(expectedDescription)) { + expect(actualEvent[descriptionKey]).to.have.property( + nestedKey, + expectedDescription[nestedKey] + ); + } + } return; } else { expect.fail(`Encountered unexpected event - ${inspect(actualEvent)}`); @@ -477,7 +495,7 @@ function compareEvents( export function matchesEvents( { events: expected, ignoreExtraEvents }: ExpectedEventsForClient, - actual: CommandEvent[] | CmapEvent[], + actual: CommandEvent[] | CmapEvent[] | SdamEvent[], entities: EntitiesMap ): void { ignoreExtraEvents = ignoreExtraEvents ?? false; diff --git a/test/tools/unified-spec-runner/operations.ts b/test/tools/unified-spec-runner/operations.ts index 514c27cbc0..c49eea0b97 100644 --- a/test/tools/unified-spec-runner/operations.ts +++ b/test/tools/unified-spec-runner/operations.ts @@ -1,5 +1,5 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { expect } from 'chai'; import { @@ -9,22 +9,28 @@ import { Document, GridFSFile, MongoClient, - ObjectId + ObjectId, + ServerType, + TopologyDescription, + TopologyType } from '../../../src'; import { CommandStartedEvent } from '../../../src/cmap/command_monitoring_events'; +import { SERVER_DESCRIPTION_CHANGED } from '../../../src/constants'; import { ReadConcern } from '../../../src/read_concern'; import { ReadPreference } from '../../../src/read_preference'; import { WriteConcern } from '../../../src/write_concern'; -import { getSymbolFrom } from '../../tools/utils'; +import { getSymbolFrom, sleep } from '../../tools/utils'; +import { TestConfiguration } from '../runner/config'; import { EntitiesMap, UnifiedChangeStream } from './entities'; import { expectErrorCheck, resultCheck } from './match'; -import type { OperationDescription } from './schema'; -import { translateOptions } from './unified-utils'; +import type { ExpectedEvent, OperationDescription } from './schema'; +import { getMatchingEventCount, translateOptions } from './unified-utils'; interface OperationFunctionParams { client: MongoClient; operation: OperationDescription; entities: EntitiesMap; + testConfig: TestConfiguration; } type RunOperationFn = ( @@ -32,6 +38,13 @@ type RunOperationFn = ( ) => Promise; export const operations = new Map(); +operations.set('createEntities', async ({ entities, operation, testConfig }) => { + if (!operation.arguments?.entities) { + throw new Error('encountered createEntities operation without entities argument'); + } + await EntitiesMap.createEntities(testConfig, operation.arguments.entities!, entities); +}); + operations.set('abortTransaction', async ({ entities, operation }) => { const session = entities.getEntity('session', operation.object); return session.abortTransaction(); @@ -408,7 +421,162 @@ operations.set('upload', async ({ entities, operation }) => { }); }); -operations.set('withTransaction', async ({ entities, operation, client }) => { +operations.set('wait', async ({ operation }) => { + expect(operation, 'Error in wait operation').to.have.nested.property('arguments.ms'); + expect(operation.arguments!.ms).to.be.a('number', 'Error in wait operation'); + await sleep(operation.arguments!.ms); +}); + +operations.set('waitForEvent', async ({ entities, operation }) => { + expect(operation, 'Error in waitForEvent operation').to.have.property('arguments'); + const { + client, + event, + count + }: { + client: string; + event: ExpectedEvent; + count: number; + } = operation.arguments! as any; + expect(count).to.be.a('number', 'Error in waitForEvent operation, invalid count'); + + const mongoClient = entities.getEntity('client', client, true); + + const eventName = Object.keys(event)[0]; + const eventPromise = new Promise(resolve => { + function checkForEvent() { + if (getMatchingEventCount(event, mongoClient, entities) >= count) { + return resolve(); + } + + mongoClient.observedEventEmitter.once('observedEvent', checkForEvent); + } + checkForEvent(); + }); + await Promise.race([ + eventPromise, + sleep(10000).then(() => + Promise.reject( + new Error( + `Timed out waiting for ${eventName}; captured [${mongoClient + .getCapturedEvents('all') + .map(e => e.constructor.name) + .join(', ')}]` + ) + ) + ) + ]); +}); + +operations.set('assertEventCount', async ({ entities, operation }) => { + expect(operation, 'Error in assertEventCount operation').to.have.property('arguments'); + const { + client, + event, + count + }: { + client: string; + event: ExpectedEvent; + count: number; + } = operation.arguments! as any; + expect(count).to.be.a('number', 'Error in assertEventCount operation, invalid count'); + + const mongoClient = entities.getEntity('client', client, true); + + const eventName = Object.keys(event)[0]; + const actualEventCount = getMatchingEventCount(event, mongoClient, entities); + expect(actualEventCount, `Error in assertEventCount for ${eventName}`).to.equal(count); +}); + +operations.set('recordTopologyDescription', async ({ entities, operation }) => { + const { client, id }: { client: string; id: string } = operation.arguments! as any; + expect(id).to.be.a('string'); + const mongoClient = entities.getEntity('client', client, true); + const description = mongoClient.topology?.description; + expect(description, `Undefined topology description for client ${client}`).to.exist; + + entities.set(id, description!); +}); + +operations.set('assertTopologyType', async ({ entities, operation }) => { + const { + topologyDescription, + topologyType + }: { topologyDescription: string; topologyType: TopologyType } = operation.arguments! as any; + expect(topologyDescription).to.be.a('string'); + const actualDescription = entities.get(topologyDescription) as TopologyDescription; + expect(actualDescription, `Failed to retrieve description for topology ${topologyDescription}`).to + .exist; + expect(actualDescription).to.have.property('type', topologyType); +}); + +operations.set('waitForPrimaryChange', async ({ entities, operation }) => { + const { + client, + priorTopologyDescription, + timeoutMS + }: { client: string; priorTopologyDescription: TopologyType; timeoutMS?: number } = + operation.arguments! as any; + + const mongoClient = entities.getEntity('client', client, true); + + expect(priorTopologyDescription).to.be.a('string'); + const priorTopologyDescriptionObject = entities.get( + priorTopologyDescription + ) as TopologyDescription; + expect( + priorTopologyDescriptionObject, + `Failed to retrieve description for topology ${priorTopologyDescription}` + ).to.exist; + + const priorPrimary = Array.from(priorTopologyDescriptionObject.servers.values()).find( + serverDescription => serverDescription.type === ServerType.RSPrimary + ); + + const newPrimaryPromise = new Promise(resolve => { + function checkForNewPrimary() { + const currentPrimary = Array.from(mongoClient.topology!.description.servers.values()).find( + serverDescription => serverDescription.type === ServerType.RSPrimary + ); + if ( + (!priorPrimary && currentPrimary) || + (currentPrimary && !currentPrimary.equals(priorPrimary)) + ) { + return resolve(); + } + + mongoClient.once(SERVER_DESCRIPTION_CHANGED, checkForNewPrimary); + } + checkForNewPrimary(); + }); + await Promise.race([ + newPrimaryPromise, + sleep(timeoutMS ?? 10000).then(() => + Promise.reject(new Error(`Timed out waiting for primary change on ${client}`)) + ) + ]); +}); + +operations.set('runOnThread', async ({ entities, operation, client, testConfig }) => { + const threadId: string = operation.arguments!.thread; + expect(threadId).to.be.a('string'); + const thread = entities.getEntity('thread', threadId, true); + const operationToQueue = operation.arguments!.operation; + const executeFn = () => executeOperationAndCheck(operationToQueue, entities, client, testConfig); + thread.queue(executeFn); +}); + +operations.set('waitForThread', async ({ entities, operation }) => { + const threadId: string = operation.arguments!.thread; + expect(threadId).to.be.a('string'); + const thread = entities.getEntity('thread', threadId, true); + await Promise.race([ + thread.finish(), + sleep(10000).then(() => Promise.reject(new Error(`Timed out waiting for thread: ${threadId}`))) + ]); +}); + +operations.set('withTransaction', async ({ entities, operation, client, testConfig }) => { const session = entities.getEntity('session', operation.object); const options = { @@ -420,7 +588,7 @@ operations.set('withTransaction', async ({ entities, operation, client }) => { return session.withTransaction(async () => { for (const callbackOperation of operation.arguments!.callback) { - await executeOperationAndCheck(callbackOperation, entities, client); + await executeOperationAndCheck(callbackOperation, entities, client, testConfig); } }, options); }); @@ -545,7 +713,8 @@ operations.set('getKeyByAltName', async ({ entities, operation }) => { export async function executeOperationAndCheck( operation: OperationDescription, entities: EntitiesMap, - client: MongoClient + client: MongoClient, + testConfig: TestConfiguration ): Promise { const opFunc = operations.get(operation.name); expect(opFunc, `Unknown operation: ${operation.name}`).to.exist; @@ -558,7 +727,7 @@ export async function executeOperationAndCheck( let result; try { - result = await opFunc!({ entities, operation, client }); + result = await opFunc!({ entities, operation, client, testConfig }); } catch (error) { if (operation.expectError) { expectErrorCheck(error, operation.expectError, entities); diff --git a/test/tools/unified-spec-runner/runner.ts b/test/tools/unified-spec-runner/runner.ts index 70313b81e5..0a05f00f8f 100644 --- a/test/tools/unified-spec-runner/runner.ts +++ b/test/tools/unified-spec-runner/runner.ts @@ -190,7 +190,7 @@ async function runUnifiedTest( for (const operation of test.operations) { trace(operation.name); try { - await executeOperationAndCheck(operation, entities, utilClient); + await executeOperationAndCheck(operation, entities, utilClient, ctx.configuration); } catch (e) { // clean up all sessions on failed test, and rethrow await terminateOpenTransactions(utilClient); diff --git a/test/tools/unified-spec-runner/schema.ts b/test/tools/unified-spec-runner/schema.ts index f3196d8143..05562c0ba1 100644 --- a/test/tools/unified-spec-runner/schema.ts +++ b/test/tools/unified-spec-runner/schema.ts @@ -5,6 +5,7 @@ import type { ReadPreferenceMode } from '../../../src/read_preference'; import type { TagSet } from '../../../src/sdam/server_description'; import type { W } from '../../../src/write_concern'; import { TestConfiguration } from '../runner/config'; +import { UnifiedThread } from './entities'; export const SupportedVersion = '^1.0'; @@ -199,6 +200,7 @@ export type EntityDescription = | { database: DatabaseEntity } | { collection: CollectionEntity } | { bucket: BucketEntity } + | { thread: Pick } | { stream: StreamEntity } | { session: SessionEntity } | { clientEncryption: ClientEncryptionEntity }; @@ -239,10 +241,13 @@ export interface Test { } export interface ExpectedEventsForClient { client: string; - eventType?: string; - events: (ExpectedCommandEvent | ExpectedCmapEvent)[]; + eventType?: 'command' | 'cmap' | 'sdam'; + events: ExpectedEvent[]; ignoreExtraEvents?: boolean; } + +export type ExpectedEvent = ExpectedCommandEvent | ExpectedCmapEvent | ExpectedSdamEvent; + export interface ExpectedCommandEvent { commandStartedEvent?: { command?: Document; @@ -276,6 +281,16 @@ export interface ExpectedCmapEvent { connectionCheckedOutEvent?: Record; connectionCheckedInEvent?: Record; } +export interface ExpectedSdamEvent { + serverDescriptionChangedEvent?: { + previousDescription?: { + type?: string; + }; + newDescription?: { + type?: string; + }; + }; +} export interface ExpectedError { isError?: true; isClientError?: boolean; diff --git a/test/tools/unified-spec-runner/unified-utils.ts b/test/tools/unified-spec-runner/unified-utils.ts index c22723ebf5..6da9a9f438 100644 --- a/test/tools/unified-spec-runner/unified-utils.ts +++ b/test/tools/unified-spec-runner/unified-utils.ts @@ -14,11 +14,13 @@ import { } from '../../../src'; import { getMongoDBClientEncryption } from '../../../src/utils'; import { shouldRunServerlessTest } from '../../tools/utils'; -import { EntitiesMap } from './entities'; +import { CmapEvent, CommandEvent, EntitiesMap } from './entities'; +import { matchesEvents } from './match'; import type { ClientEncryption, ClientEncryptionEntity, CollectionOrDatabaseOptions, + ExpectedEventsForClient, KMSProvidersEntity, RunOnRequirement, StringOrPlaceholder @@ -75,7 +77,7 @@ export async function topologySatisfies( if (!topologyType) throw new Error(`Topology undiscovered: ${config.topologyType}`); ok &&= r.topologies.includes(topologyType); if (!ok && skipReason == null) { - skipReason = `requires ${r.topologies} but against a ${topologyType} topology`; + skipReason = `requires ${r.topologies} but discovered a ${topologyType} topology`; } } } @@ -202,6 +204,21 @@ export function makeConnectionString( return connectionString.toString(); } +export function getMatchingEventCount(event, client, entities): number { + return client.getCapturedEvents('all').filter(capturedEvent => { + try { + matchesEvents( + { events: [event] } as ExpectedEventsForClient, + [capturedEvent] as CommandEvent[] | CmapEvent[], + entities + ); + return true; + } catch { + return false; + } + }).length; +} + /** * attempts to import mongodb-client-encryption and extract the client encryption class for * use in the csfle unified tests diff --git a/test/unit/assorted/server_discovery_and_monitoring.spec.test.ts b/test/unit/assorted/server_discovery_and_monitoring.spec.test.ts index a6564385c3..ed3a12f7e4 100644 --- a/test/unit/assorted/server_discovery_and_monitoring.spec.test.ts +++ b/test/unit/assorted/server_discovery_and_monitoring.spec.test.ts @@ -58,7 +58,7 @@ function collectTests(): Record { const testTypes = fs .readdirSync(specDir) .filter(d => fs.statSync(path.resolve(specDir, d)).isDirectory()) - .filter(d => d !== 'integration'); + .filter(d => d !== 'unified'); const tests = {}; for (const testType of testTypes) {