diff --git a/test/retryable_reads/aggregate-merge.json b/test/retryable_reads/legacy/aggregate-merge.json similarity index 100% rename from test/retryable_reads/aggregate-merge.json rename to test/retryable_reads/legacy/aggregate-merge.json diff --git a/test/retryable_reads/aggregate-serverErrors.json b/test/retryable_reads/legacy/aggregate-serverErrors.json similarity index 100% rename from test/retryable_reads/aggregate-serverErrors.json rename to test/retryable_reads/legacy/aggregate-serverErrors.json diff --git a/test/retryable_reads/aggregate.json b/test/retryable_reads/legacy/aggregate.json similarity index 100% rename from test/retryable_reads/aggregate.json rename to test/retryable_reads/legacy/aggregate.json diff --git a/test/retryable_reads/changeStreams-client.watch-serverErrors.json b/test/retryable_reads/legacy/changeStreams-client.watch-serverErrors.json similarity index 100% rename from test/retryable_reads/changeStreams-client.watch-serverErrors.json rename to test/retryable_reads/legacy/changeStreams-client.watch-serverErrors.json diff --git a/test/retryable_reads/changeStreams-client.watch.json b/test/retryable_reads/legacy/changeStreams-client.watch.json similarity index 100% rename from test/retryable_reads/changeStreams-client.watch.json rename to test/retryable_reads/legacy/changeStreams-client.watch.json diff --git a/test/retryable_reads/changeStreams-db.coll.watch-serverErrors.json b/test/retryable_reads/legacy/changeStreams-db.coll.watch-serverErrors.json similarity index 100% rename from test/retryable_reads/changeStreams-db.coll.watch-serverErrors.json rename to test/retryable_reads/legacy/changeStreams-db.coll.watch-serverErrors.json diff --git a/test/retryable_reads/changeStreams-db.coll.watch.json b/test/retryable_reads/legacy/changeStreams-db.coll.watch.json similarity index 100% rename from test/retryable_reads/changeStreams-db.coll.watch.json rename to test/retryable_reads/legacy/changeStreams-db.coll.watch.json diff --git a/test/retryable_reads/changeStreams-db.watch-serverErrors.json b/test/retryable_reads/legacy/changeStreams-db.watch-serverErrors.json similarity index 100% rename from test/retryable_reads/changeStreams-db.watch-serverErrors.json rename to test/retryable_reads/legacy/changeStreams-db.watch-serverErrors.json diff --git a/test/retryable_reads/changeStreams-db.watch.json b/test/retryable_reads/legacy/changeStreams-db.watch.json similarity index 100% rename from test/retryable_reads/changeStreams-db.watch.json rename to test/retryable_reads/legacy/changeStreams-db.watch.json diff --git a/test/retryable_reads/count-serverErrors.json b/test/retryable_reads/legacy/count-serverErrors.json similarity index 100% rename from test/retryable_reads/count-serverErrors.json rename to test/retryable_reads/legacy/count-serverErrors.json diff --git a/test/retryable_reads/count.json b/test/retryable_reads/legacy/count.json similarity index 100% rename from test/retryable_reads/count.json rename to test/retryable_reads/legacy/count.json diff --git a/test/retryable_reads/countDocuments-serverErrors.json b/test/retryable_reads/legacy/countDocuments-serverErrors.json similarity index 100% rename from test/retryable_reads/countDocuments-serverErrors.json rename to test/retryable_reads/legacy/countDocuments-serverErrors.json diff --git a/test/retryable_reads/countDocuments.json b/test/retryable_reads/legacy/countDocuments.json similarity index 100% rename from test/retryable_reads/countDocuments.json rename to test/retryable_reads/legacy/countDocuments.json diff --git a/test/retryable_reads/distinct-serverErrors.json b/test/retryable_reads/legacy/distinct-serverErrors.json similarity index 100% rename from test/retryable_reads/distinct-serverErrors.json rename to test/retryable_reads/legacy/distinct-serverErrors.json diff --git a/test/retryable_reads/distinct.json b/test/retryable_reads/legacy/distinct.json similarity index 100% rename from test/retryable_reads/distinct.json rename to test/retryable_reads/legacy/distinct.json diff --git a/test/retryable_reads/estimatedDocumentCount-4.9.json b/test/retryable_reads/legacy/estimatedDocumentCount-4.9.json similarity index 100% rename from test/retryable_reads/estimatedDocumentCount-4.9.json rename to test/retryable_reads/legacy/estimatedDocumentCount-4.9.json diff --git a/test/retryable_reads/estimatedDocumentCount-pre4.9.json b/test/retryable_reads/legacy/estimatedDocumentCount-pre4.9.json similarity index 100% rename from test/retryable_reads/estimatedDocumentCount-pre4.9.json rename to test/retryable_reads/legacy/estimatedDocumentCount-pre4.9.json diff --git a/test/retryable_reads/estimatedDocumentCount-serverErrors-4.9.json b/test/retryable_reads/legacy/estimatedDocumentCount-serverErrors-4.9.json similarity index 100% rename from test/retryable_reads/estimatedDocumentCount-serverErrors-4.9.json rename to test/retryable_reads/legacy/estimatedDocumentCount-serverErrors-4.9.json diff --git a/test/retryable_reads/estimatedDocumentCount-serverErrors-pre4.9.json b/test/retryable_reads/legacy/estimatedDocumentCount-serverErrors-pre4.9.json similarity index 100% rename from test/retryable_reads/estimatedDocumentCount-serverErrors-pre4.9.json rename to test/retryable_reads/legacy/estimatedDocumentCount-serverErrors-pre4.9.json diff --git a/test/retryable_reads/find-serverErrors.json b/test/retryable_reads/legacy/find-serverErrors.json similarity index 100% rename from test/retryable_reads/find-serverErrors.json rename to test/retryable_reads/legacy/find-serverErrors.json diff --git a/test/retryable_reads/find.json b/test/retryable_reads/legacy/find.json similarity index 100% rename from test/retryable_reads/find.json rename to test/retryable_reads/legacy/find.json diff --git a/test/retryable_reads/findOne-serverErrors.json b/test/retryable_reads/legacy/findOne-serverErrors.json similarity index 100% rename from test/retryable_reads/findOne-serverErrors.json rename to test/retryable_reads/legacy/findOne-serverErrors.json diff --git a/test/retryable_reads/findOne.json b/test/retryable_reads/legacy/findOne.json similarity index 100% rename from test/retryable_reads/findOne.json rename to test/retryable_reads/legacy/findOne.json diff --git a/test/retryable_reads/gridfs-download-serverErrors.json b/test/retryable_reads/legacy/gridfs-download-serverErrors.json similarity index 100% rename from test/retryable_reads/gridfs-download-serverErrors.json rename to test/retryable_reads/legacy/gridfs-download-serverErrors.json diff --git a/test/retryable_reads/gridfs-download.json b/test/retryable_reads/legacy/gridfs-download.json similarity index 100% rename from test/retryable_reads/gridfs-download.json rename to test/retryable_reads/legacy/gridfs-download.json diff --git a/test/retryable_reads/gridfs-downloadByName-serverErrors.json b/test/retryable_reads/legacy/gridfs-downloadByName-serverErrors.json similarity index 100% rename from test/retryable_reads/gridfs-downloadByName-serverErrors.json rename to test/retryable_reads/legacy/gridfs-downloadByName-serverErrors.json diff --git a/test/retryable_reads/gridfs-downloadByName.json b/test/retryable_reads/legacy/gridfs-downloadByName.json similarity index 100% rename from test/retryable_reads/gridfs-downloadByName.json rename to test/retryable_reads/legacy/gridfs-downloadByName.json diff --git a/test/retryable_reads/listCollectionNames-serverErrors.json b/test/retryable_reads/legacy/listCollectionNames-serverErrors.json similarity index 100% rename from test/retryable_reads/listCollectionNames-serverErrors.json rename to test/retryable_reads/legacy/listCollectionNames-serverErrors.json diff --git a/test/retryable_reads/listCollectionNames.json b/test/retryable_reads/legacy/listCollectionNames.json similarity index 100% rename from test/retryable_reads/listCollectionNames.json rename to test/retryable_reads/legacy/listCollectionNames.json diff --git a/test/retryable_reads/listCollectionObjects-serverErrors.json b/test/retryable_reads/legacy/listCollectionObjects-serverErrors.json similarity index 100% rename from test/retryable_reads/listCollectionObjects-serverErrors.json rename to test/retryable_reads/legacy/listCollectionObjects-serverErrors.json diff --git a/test/retryable_reads/listCollectionObjects.json b/test/retryable_reads/legacy/listCollectionObjects.json similarity index 100% rename from test/retryable_reads/listCollectionObjects.json rename to test/retryable_reads/legacy/listCollectionObjects.json diff --git a/test/retryable_reads/listCollections-serverErrors.json b/test/retryable_reads/legacy/listCollections-serverErrors.json similarity index 100% rename from test/retryable_reads/listCollections-serverErrors.json rename to test/retryable_reads/legacy/listCollections-serverErrors.json diff --git a/test/retryable_reads/listCollections.json b/test/retryable_reads/legacy/listCollections.json similarity index 100% rename from test/retryable_reads/listCollections.json rename to test/retryable_reads/legacy/listCollections.json diff --git a/test/retryable_reads/listDatabaseNames-serverErrors.json b/test/retryable_reads/legacy/listDatabaseNames-serverErrors.json similarity index 100% rename from test/retryable_reads/listDatabaseNames-serverErrors.json rename to test/retryable_reads/legacy/listDatabaseNames-serverErrors.json diff --git a/test/retryable_reads/listDatabaseNames.json b/test/retryable_reads/legacy/listDatabaseNames.json similarity index 100% rename from test/retryable_reads/listDatabaseNames.json rename to test/retryable_reads/legacy/listDatabaseNames.json diff --git a/test/retryable_reads/listDatabaseObjects-serverErrors.json b/test/retryable_reads/legacy/listDatabaseObjects-serverErrors.json similarity index 100% rename from test/retryable_reads/listDatabaseObjects-serverErrors.json rename to test/retryable_reads/legacy/listDatabaseObjects-serverErrors.json diff --git a/test/retryable_reads/listDatabaseObjects.json b/test/retryable_reads/legacy/listDatabaseObjects.json similarity index 100% rename from test/retryable_reads/listDatabaseObjects.json rename to test/retryable_reads/legacy/listDatabaseObjects.json diff --git a/test/retryable_reads/listDatabases-serverErrors.json b/test/retryable_reads/legacy/listDatabases-serverErrors.json similarity index 100% rename from test/retryable_reads/listDatabases-serverErrors.json rename to test/retryable_reads/legacy/listDatabases-serverErrors.json diff --git a/test/retryable_reads/listDatabases.json b/test/retryable_reads/legacy/listDatabases.json similarity index 100% rename from test/retryable_reads/listDatabases.json rename to test/retryable_reads/legacy/listDatabases.json diff --git a/test/retryable_reads/listIndexNames-serverErrors.json b/test/retryable_reads/legacy/listIndexNames-serverErrors.json similarity index 100% rename from test/retryable_reads/listIndexNames-serverErrors.json rename to test/retryable_reads/legacy/listIndexNames-serverErrors.json diff --git a/test/retryable_reads/listIndexNames.json b/test/retryable_reads/legacy/listIndexNames.json similarity index 100% rename from test/retryable_reads/listIndexNames.json rename to test/retryable_reads/legacy/listIndexNames.json diff --git a/test/retryable_reads/listIndexes-serverErrors.json b/test/retryable_reads/legacy/listIndexes-serverErrors.json similarity index 100% rename from test/retryable_reads/listIndexes-serverErrors.json rename to test/retryable_reads/legacy/listIndexes-serverErrors.json diff --git a/test/retryable_reads/listIndexes.json b/test/retryable_reads/legacy/listIndexes.json similarity index 100% rename from test/retryable_reads/listIndexes.json rename to test/retryable_reads/legacy/listIndexes.json diff --git a/test/retryable_reads/mapReduce.json b/test/retryable_reads/legacy/mapReduce.json similarity index 100% rename from test/retryable_reads/mapReduce.json rename to test/retryable_reads/legacy/mapReduce.json diff --git a/test/retryable_reads/unified/handshakeError.json b/test/retryable_reads/unified/handshakeError.json new file mode 100644 index 000000000..2cf1d173f --- /dev/null +++ b/test/retryable_reads/unified/handshakeError.json @@ -0,0 +1,257 @@ +{ + "description": "retryable reads handshake failures", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.2", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ], + "auth": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "connectionCheckOutStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "retryable-handshake-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll" + } + } + ], + "initialData": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + }, + { + "_id": 3, + "x": 33 + } + ] + } + ], + "tests": [ + { + "description": "find succeeds after retryable handshake network error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "saslContinue", + "ping" + ], + "closeConnection": true + } + } + } + }, + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "ping", + "command": { + "ping": 1 + } + }, + "expectError": { + "isError": true + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": { + "_id": 2 + } + }, + "expectResult": [ + { + "_id": 2, + "x": 22 + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + } + ] + }, + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "ping": 1 + }, + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "find": "coll", + "filter": { + "_id": 2 + } + }, + "databaseName": "retryable-handshake-tests" + } + } + ] + } + ] + }, + { + "description": "find succeeds after retryable handshake network error (ShutdownInProgress)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "saslContinue", + "ping" + ], + "errorCode": 91 + } + } + } + }, + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "ping", + "command": { + "ping": 1 + } + }, + "expectError": { + "isError": true + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": { + "_id": 2 + } + }, + "expectResult": [ + { + "_id": 2, + "x": 22 + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + } + ] + }, + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "ping": 1 + }, + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "find": "coll", + "filter": { + "_id": 2 + } + }, + "databaseName": "retryable-handshake-tests" + } + } + ] + } + ] + } + ] +} diff --git a/test/retryable_writes/unified/handshakeError.json b/test/retryable_writes/unified/handshakeError.json new file mode 100644 index 000000000..6d6b4ac49 --- /dev/null +++ b/test/retryable_writes/unified/handshakeError.json @@ -0,0 +1,279 @@ +{ + "description": "retryable writes handshake failures", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.2", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ], + "auth": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "connectionCheckOutStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "retryable-handshake-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll" + } + } + ], + "initialData": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + } + ] + } + ], + "tests": [ + { + "description": "InsertOne succeeds after retryable handshake error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "saslContinue", + "ping" + ], + "closeConnection": true + } + } + } + }, + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "ping", + "command": { + "ping": 1 + } + }, + "expectError": { + "isError": true + } + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 2, + "x": 22 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + } + ] + }, + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "ping": 1 + }, + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 2, + "x": 22 + } + ] + }, + "commandName": "insert", + "databaseName": "retryable-handshake-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + } + ] + } + ] + }, + { + "description": "InsertOne succeeds after retryable handshake error ShutdownInProgress", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "saslContinue", + "ping" + ], + "errorCode": 91 + } + } + } + }, + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "ping", + "command": { + "ping": 1 + } + }, + "expectError": { + "isError": true + } + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 2, + "x": 22 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + } + ] + }, + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "ping": 1 + }, + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 2, + "x": 22 + } + ] + }, + "commandName": "insert", + "databaseName": "retryable-handshake-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + } + ] + } + ] + } + ] +} diff --git a/test/test_retryable_reads.py b/test/test_retryable_reads.py index 808477a8c..01fe6901a 100644 --- a/test/test_retryable_reads.py +++ b/test/test_retryable_reads.py @@ -46,7 +46,7 @@ from pymongo.monitoring import ( from pymongo.write_concern import WriteConcern # Location of JSON test specifications. -_TEST_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "retryable_reads") +_TEST_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "retryable_reads", "legacy") class TestClientOptions(PyMongoTestCase): diff --git a/test/test_retryable_reads_unified.py b/test/test_retryable_reads_unified.py new file mode 100644 index 000000000..6bf415776 --- /dev/null +++ b/test/test_retryable_reads_unified.py @@ -0,0 +1,32 @@ +# Copyright 2022-present MongoDB, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Test the Retryable Reads unified spec tests.""" + +import os +import sys + +sys.path[0:0] = [""] + +from test import unittest +from test.unified_format import generate_test_classes + +# Location of JSON test specifications. +TEST_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "retryable_reads", "unified") + +# Generate unified tests. +globals().update(generate_test_classes(TEST_PATH, module=__name__)) + +if __name__ == "__main__": + unittest.main() diff --git a/test/transactions/unified/retryable-abort-handshake.json b/test/transactions/unified/retryable-abort-handshake.json new file mode 100644 index 000000000..4ad56e2f2 --- /dev/null +++ b/test/transactions/unified/retryable-abort-handshake.json @@ -0,0 +1,204 @@ +{ + "description": "retryable abortTransaction on handshake errors", + "schemaVersion": "1.4", + "runOnRequirements": [ + { + "minServerVersion": "4.2", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ], + "serverless": "forbid", + "auth": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "connectionCheckOutStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "retryable-handshake-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + }, + { + "session": { + "id": "session1", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + } + ] + } + ], + "tests": [ + { + "description": "AbortTransaction succeeds after handshake network error", + "skipReason": "DRIVERS-2032: Pinned servers need to be checked if they are still selectable", + "operations": [ + { + "name": "startTransaction", + "object": "session0" + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2, + "x": 22 + } + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "session": "session1", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "saslContinue", + "ping" + ], + "closeConnection": true + } + } + } + }, + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "ping", + "command": { + "ping": 1 + }, + "session": "session1" + }, + "expectError": { + "isError": true + } + }, + { + "name": "abortTransaction", + "object": "session0" + } + ], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + } + ] + }, + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 2, + "x": 22 + } + ], + "startTransaction": true + }, + "commandName": "insert", + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "ping": 1 + }, + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "abortTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + } + }, + "commandName": "abortTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + } + ] + } + ] + } + ] +} diff --git a/test/transactions/unified/retryable-commit-handshake.json b/test/transactions/unified/retryable-commit-handshake.json new file mode 100644 index 000000000..d9315a8fc --- /dev/null +++ b/test/transactions/unified/retryable-commit-handshake.json @@ -0,0 +1,211 @@ +{ + "description": "retryable commitTransaction on handshake errors", + "schemaVersion": "1.4", + "runOnRequirements": [ + { + "minServerVersion": "4.2", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ], + "serverless": "forbid", + "auth": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent", + "connectionCheckOutStartedEvent" + ], + "uriOptions": { + "retryWrites": false + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "retryable-handshake-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + }, + { + "session": { + "id": "session1", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + } + ] + } + ], + "tests": [ + { + "description": "CommitTransaction succeeds after handshake network error", + "skipReason": "DRIVERS-2032: Pinned servers need to be checked if they are still selectable", + "operations": [ + { + "name": "startTransaction", + "object": "session0" + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2, + "x": 22 + } + } + }, + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "session": "session1", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "saslContinue", + "ping" + ], + "closeConnection": true + } + } + } + }, + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "ping", + "command": { + "ping": 1 + }, + "session": "session1" + }, + "expectError": { + "isError": true + } + }, + { + "name": "commitTransaction", + "object": "session0" + } + ], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + }, + { + "connectionCheckOutStartedEvent": {} + } + ] + }, + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 2, + "x": 22 + } + ], + "startTransaction": true + }, + "commandName": "insert", + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "ping": 1 + }, + "databaseName": "retryable-handshake-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "coll", + "databaseName": "retryable-handshake-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + } + ] + } + ] + } + ] +} diff --git a/test/unified_format.py b/test/unified_format.py index 6f1e38693..5bf98c545 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -1153,8 +1153,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest): self.assertEqual(actual_events, []) continue - if len(events) > len(actual_events): - self.fail("Expected to see %s events, got %s" % (len(events), len(actual_events))) + self.assertGreaterEqual(len(actual_events), len(events), actual_events) for idx, expected_event in enumerate(events): self.match_evaluator.match_event(event_type, expected_event, actual_events[idx])