From 8a0fdf7e3be5bb7de6be9fd4894e8b6f3fe113df Mon Sep 17 00:00:00 2001 From: Isabel Atkinson Date: Mon, 10 Jan 2022 14:53:14 -0500 Subject: [PATCH] RUST-1088 Always specify error labels at the top level --- .../spec/json/retryable-writes/README.rst | 99 ++++- .../{ => legacy}/bulkWrite-errorLabels.json | 0 .../{ => legacy}/bulkWrite-errorLabels.yml | 0 .../{ => legacy}/bulkWrite-serverErrors.json | 8 +- .../{ => legacy}/bulkWrite-serverErrors.yml | 2 +- .../{ => legacy}/bulkWrite.json | 0 .../{ => legacy}/bulkWrite.yml | 0 .../{ => legacy}/deleteMany.json | 0 .../{ => legacy}/deleteMany.yml | 0 .../{ => legacy}/deleteOne-errorLabels.json | 0 .../{ => legacy}/deleteOne-errorLabels.yml | 0 .../{ => legacy}/deleteOne-serverErrors.json | 8 +- .../{ => legacy}/deleteOne-serverErrors.yml | 2 +- .../{ => legacy}/deleteOne.json | 0 .../{ => legacy}/deleteOne.yml | 0 .../findOneAndDelete-errorLabels.json | 0 .../findOneAndDelete-errorLabels.yml | 0 .../findOneAndDelete-serverErrors.json | 8 +- .../findOneAndDelete-serverErrors.yml | 2 +- .../{ => legacy}/findOneAndDelete.json | 0 .../{ => legacy}/findOneAndDelete.yml | 0 .../findOneAndReplace-errorLabels.json | 0 .../findOneAndReplace-errorLabels.yml | 0 .../findOneAndReplace-serverErrors.json | 8 +- .../findOneAndReplace-serverErrors.yml | 2 +- .../{ => legacy}/findOneAndReplace.json | 0 .../{ => legacy}/findOneAndReplace.yml | 0 .../findOneAndUpdate-errorLabels.json | 0 .../findOneAndUpdate-errorLabels.yml | 0 .../findOneAndUpdate-serverErrors.json | 8 +- .../findOneAndUpdate-serverErrors.yml | 2 +- .../{ => legacy}/findOneAndUpdate.json | 0 .../{ => legacy}/findOneAndUpdate.yml | 0 .../{ => legacy}/insertMany-errorLabels.json | 0 .../{ => legacy}/insertMany-errorLabels.yml | 0 .../{ => legacy}/insertMany-serverErrors.json | 8 +- .../{ => legacy}/insertMany-serverErrors.yml | 2 +- .../{ => legacy}/insertMany.json | 0 .../{ => legacy}/insertMany.yml | 0 .../{ => legacy}/insertOne-errorLabels.json | 0 .../{ => legacy}/insertOne-errorLabels.yml | 0 .../{ => legacy}/insertOne-serverErrors.json | 40 +-- .../{ => legacy}/insertOne-serverErrors.yml | 10 +- .../{ => legacy}/insertOne.json | 0 .../{ => legacy}/insertOne.yml | 0 .../{ => legacy}/replaceOne-errorLabels.json | 0 .../{ => legacy}/replaceOne-errorLabels.yml | 0 .../{ => legacy}/replaceOne-serverErrors.json | 8 +- .../{ => legacy}/replaceOne-serverErrors.yml | 2 +- .../{ => legacy}/replaceOne.json | 0 .../{ => legacy}/replaceOne.yml | 0 .../{ => legacy}/updateMany.json | 0 .../{ => legacy}/updateMany.yml | 0 .../{ => legacy}/updateOne-errorLabels.json | 0 .../{ => legacy}/updateOne-errorLabels.yml | 0 .../{ => legacy}/updateOne-serverErrors.json | 8 +- .../{ => legacy}/updateOne-serverErrors.yml | 2 +- .../{ => legacy}/updateOne.json | 0 .../{ => legacy}/updateOne.yml | 0 .../unified/bulkWrite-serverErrors.json | 205 +++++++++++ .../unified/bulkWrite-serverErrors.yml | 96 +++++ .../unified/insertOne-serverErrors.json | 173 +++++++++ .../unified/insertOne-serverErrors.yml | 78 ++++ src/test/spec/json/transactions/README.rst | 24 +- .../transactions/legacy/error-labels.json | 13 +- .../json/transactions/legacy/error-labels.yml | 9 +- .../transactions/legacy/errors-client.json | 96 +++++ .../transactions/legacy/errors-client.yml | 55 +++ .../legacy/mongos-pin-auto-tests.py | 340 ++++++++++++++++++ .../transactions/legacy/mongos-pin-auto.json | 3 +- .../transactions/legacy/mongos-pin-auto.yml | 3 + .../legacy/mongos-recovery-token.json | 14 +- .../legacy/mongos-recovery-token.yml | 10 +- .../json/transactions/legacy/pin-mongos.json | 6 +- .../json/transactions/legacy/pin-mongos.yml | 9 +- .../transactions/legacy/retryable-abort.json | 30 +- .../transactions/legacy/retryable-abort.yml | 14 +- .../transactions/legacy/retryable-commit.json | 30 +- .../transactions/legacy/retryable-commit.yml | 14 +- src/test/spec/retryable_writes/mod.rs | 22 +- src/test/util/failpoint.rs | 14 +- 81 files changed, 1316 insertions(+), 171 deletions(-) rename src/test/spec/json/retryable-writes/{ => legacy}/bulkWrite-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/bulkWrite-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/bulkWrite-serverErrors.json (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/bulkWrite-serverErrors.yml (98%) rename src/test/spec/json/retryable-writes/{ => legacy}/bulkWrite.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/bulkWrite.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteMany.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteMany.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteOne-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteOne-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteOne-serverErrors.json (95%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteOne-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteOne.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/deleteOne.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndDelete-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndDelete-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndDelete-serverErrors.json (95%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndDelete-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndDelete.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndDelete.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndReplace-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndReplace-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndReplace-serverErrors.json (96%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndReplace-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndReplace.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndReplace.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndUpdate-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndUpdate-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndUpdate-serverErrors.json (96%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndUpdate-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndUpdate.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/findOneAndUpdate.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertMany-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertMany-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertMany-serverErrors.json (96%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertMany-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertMany.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertMany.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertOne-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertOne-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertOne-serverErrors.json (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertOne-serverErrors.yml (98%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertOne.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/insertOne.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/replaceOne-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/replaceOne-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/replaceOne-serverErrors.json (96%) rename src/test/spec/json/retryable-writes/{ => legacy}/replaceOne-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/replaceOne.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/replaceOne.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateMany.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateMany.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateOne-errorLabels.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateOne-errorLabels.yml (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateOne-serverErrors.json (96%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateOne-serverErrors.yml (97%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateOne.json (100%) rename src/test/spec/json/retryable-writes/{ => legacy}/updateOne.yml (100%) create mode 100644 src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.json create mode 100644 src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.yml create mode 100644 src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.json create mode 100644 src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.yml create mode 100644 src/test/spec/json/transactions/legacy/errors-client.json create mode 100644 src/test/spec/json/transactions/legacy/errors-client.yml create mode 100644 src/test/spec/json/transactions/legacy/mongos-pin-auto-tests.py diff --git a/src/test/spec/json/retryable-writes/README.rst b/src/test/spec/json/retryable-writes/README.rst index 2f431ba39..7cc234d51 100644 --- a/src/test/spec/json/retryable-writes/README.rst +++ b/src/test/spec/json/retryable-writes/README.rst @@ -9,8 +9,13 @@ Retryable Write Tests Introduction ============ -The YAML and JSON files in this directory tree are platform-independent tests -that drivers can use to prove their conformance to the Retryable Writes spec. +Tests in this directory are platform-independent tests that drivers can use to +prove their conformance to the Retryable Writes specification. + +Tests in the ``unified`` directory are implemented in the +`Unified Test Format <../../unified-test-format/unified-test-format.rst>`__. + +Tests in the ``legacy`` directory should be executed as described below. Several prose tests, which are not easily expressed in YAML, are also presented in this file. Those tests will need to be manually implemented by each driver. @@ -91,6 +96,11 @@ disabled like so:: mode: "off" }); +Speeding Up Tests +================= + +See `Speeding Up Tests <../../retryable-reads/tests/README.rst#speeding-up-tests>`_ in the retryable reads spec tests. + Use as Integration Tests ======================== @@ -154,9 +164,22 @@ Each YAML file has the following keys: version. - ``topology`` (optional): An array of server topologies against which the - tests can be run successfully. Valid topologies are "single", "replicaset", - and "sharded". If this field is omitted, the default is all topologies (i.e. - ``["single", "replicaset", "sharded"]``). + tests can be run successfully. Valid topologies are "single", + "replicaset", "sharded", and "load-balanced". If this field is omitted, + the default is all topologies (i.e. ``["single", "replicaset", "sharded", + "load-balanced"]``). + + - ``serverless``: Optional string. Whether or not the test should be run on + serverless instances imitating sharded clusters. Valid values are "require", + "forbid", and "allow". If "require", the test MUST only be run on serverless + instances. If "forbid", the test MUST NOT be run on serverless instances. If + omitted or "allow", this option has no effect. + + The test runner MUST be informed whether or not serverless is being used in + order to determine if this requirement is met (e.g. through an environment + variable or configuration option). Since the serverless proxy imitates a + mongos, the runner is not capable of determining this by issuing a server + command such as ``buildInfo`` or ``hello``. - ``data``: The data that should exist in the collection under test before each test run. @@ -168,10 +191,18 @@ Each YAML file has the following keys: - ``clientOptions``: Parameters to pass to MongoClient(). - - ``useMultipleMongoses`` (optional): If ``true``, the MongoClient for this - test should be initialized with multiple mongos seed addresses. If ``false`` - or omitted, only a single mongos address should be specified. This field has - no effect for non-sharded topologies. + - ``useMultipleMongoses`` (optional): If ``true``, and the topology type is + ``Sharded``, the MongoClient for this test should be initialized with multiple + mongos seed addresses. If ``false`` or omitted, only a single mongos address + should be specified. + + If ``true``, and the topology type is ``LoadBalanced``, the MongoClient for + this test should be initialized with the URI of the load balancer fronting + multiple servers. If ``false`` or omitted, the MongoClient for this test + should be initialized with the URI of the load balancer fronting a single + server. + + ``useMultipleMongoses`` only affects ``Sharded`` and ``LoadBalanced`` topologies. - ``failPoint`` (optional): The ``configureFailPoint`` command document to run to configure a fail point on the primary server. Drivers must ensure that @@ -322,10 +353,58 @@ and sharded clusters. in use MAY skip this test for sharded clusters, since ``mongos`` does not report this information in its ``serverStatus`` response. +#. Test that drivers properly retry after encountering PoolClearedErrors. This + test MUST be implemented by any driver that implements the CMAP + specification. This test requires MongoDB 4.2.9+ for ``blockConnection`` support in the failpoint. + + 1. Create a client with maxPoolSize=1 and retryWrites=true. If testing + against a sharded deployment, be sure to connect to only a single mongos. + + 2. Enable the following failpoint:: + + { + configureFailPoint: "failCommand", + mode: { times: 1 }, + data: { + failCommands: ["insert"], + errorCode: 91, + blockConnection: true, + blockTimeMS: 1000, + errorLabels: ["RetryableWriteError"] + } + } + + 3. Start two threads and attempt to perform an ``insertOne`` simultaneously on both. + + 4. Verify that both ``insertOne`` attempts succeed. + + 5. Via CMAP monitoring, assert that the first check out succeeds. + + 6. Via CMAP monitoring, assert that a PoolClearedEvent is then emitted. + + 7. Via CMAP monitoring, assert that the second check out then fails due to a + connection error. + + 8. Via Command Monitoring, assert that exactly three ``insert`` + CommandStartedEvents were observed in total. + + 9. Disable the failpoint. + + Changelog ========= -:2019-10-21: Add ``errorLabelsContain`` and ``errorLabelsContain`` fields to ``result`` + + +:2021-08-27: Add ``serverless`` to ``runOn``. Clarify behavior of + ``useMultipleMongoses`` for ``LoadBalanced`` topologies. + +:2021-04-23: Add ``load-balanced`` to test topology requirements. + +:2021-03-24: Add prose test verifying ``PoolClearedErrors`` are retried. + +:2019-10-21: Add ``errorLabelsContain`` and ``errorLabelsContain`` fields to + ``result`` :2019-08-07: Add Prose Tests section diff --git a/src/test/spec/json/retryable-writes/bulkWrite-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/bulkWrite-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/bulkWrite-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/bulkWrite-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/bulkWrite-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/bulkWrite-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/bulkWrite-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/bulkWrite-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/bulkWrite-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/bulkWrite-serverErrors.json similarity index 97% rename from src/test/spec/json/retryable-writes/bulkWrite-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/bulkWrite-serverErrors.json index 9d792ceaf..1e6cc74c0 100644 --- a/src/test/spec/json/retryable-writes/bulkWrite-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/bulkWrite-serverErrors.json @@ -119,12 +119,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/bulkWrite-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/bulkWrite-serverErrors.yml similarity index 98% rename from src/test/spec/json/retryable-writes/bulkWrite-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/bulkWrite-serverErrors.yml index 0235a8a1c..6ca6540f6 100644 --- a/src/test/spec/json/retryable-writes/bulkWrite-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/bulkWrite-serverErrors.yml @@ -58,10 +58,10 @@ tests: mode: { times: 1 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "bulkWrite" arguments: diff --git a/src/test/spec/json/retryable-writes/bulkWrite.json b/src/test/spec/json/retryable-writes/legacy/bulkWrite.json similarity index 100% rename from src/test/spec/json/retryable-writes/bulkWrite.json rename to src/test/spec/json/retryable-writes/legacy/bulkWrite.json diff --git a/src/test/spec/json/retryable-writes/bulkWrite.yml b/src/test/spec/json/retryable-writes/legacy/bulkWrite.yml similarity index 100% rename from src/test/spec/json/retryable-writes/bulkWrite.yml rename to src/test/spec/json/retryable-writes/legacy/bulkWrite.yml diff --git a/src/test/spec/json/retryable-writes/deleteMany.json b/src/test/spec/json/retryable-writes/legacy/deleteMany.json similarity index 100% rename from src/test/spec/json/retryable-writes/deleteMany.json rename to src/test/spec/json/retryable-writes/legacy/deleteMany.json diff --git a/src/test/spec/json/retryable-writes/deleteMany.yml b/src/test/spec/json/retryable-writes/legacy/deleteMany.yml similarity index 100% rename from src/test/spec/json/retryable-writes/deleteMany.yml rename to src/test/spec/json/retryable-writes/legacy/deleteMany.yml diff --git a/src/test/spec/json/retryable-writes/deleteOne-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/deleteOne-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/deleteOne-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/deleteOne-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/deleteOne-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/deleteOne-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/deleteOne-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/deleteOne-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/deleteOne-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/deleteOne-serverErrors.json similarity index 95% rename from src/test/spec/json/retryable-writes/deleteOne-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/deleteOne-serverErrors.json index 4eab2fa29..a1a27838d 100644 --- a/src/test/spec/json/retryable-writes/deleteOne-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/deleteOne-serverErrors.json @@ -75,12 +75,12 @@ "failCommands": [ "delete" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/deleteOne-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/deleteOne-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/deleteOne-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/deleteOne-serverErrors.yml index 73cab927e..f4c98c919 100644 --- a/src/test/spec/json/retryable-writes/deleteOne-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/deleteOne-serverErrors.yml @@ -37,10 +37,10 @@ tests: mode: { times: 1 } data: failCommands: ["delete"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "deleteOne" arguments: diff --git a/src/test/spec/json/retryable-writes/deleteOne.json b/src/test/spec/json/retryable-writes/legacy/deleteOne.json similarity index 100% rename from src/test/spec/json/retryable-writes/deleteOne.json rename to src/test/spec/json/retryable-writes/legacy/deleteOne.json diff --git a/src/test/spec/json/retryable-writes/deleteOne.yml b/src/test/spec/json/retryable-writes/legacy/deleteOne.yml similarity index 100% rename from src/test/spec/json/retryable-writes/deleteOne.yml rename to src/test/spec/json/retryable-writes/legacy/deleteOne.yml diff --git a/src/test/spec/json/retryable-writes/findOneAndDelete-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndDelete-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndDelete-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/findOneAndDelete-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndDelete-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndDelete-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/findOneAndDelete-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete-serverErrors.json similarity index 95% rename from src/test/spec/json/retryable-writes/findOneAndDelete-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndDelete-serverErrors.json index 4c1086161..c18b63f45 100644 --- a/src/test/spec/json/retryable-writes/findOneAndDelete-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete-serverErrors.json @@ -81,12 +81,12 @@ "failCommands": [ "findAndModify" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/findOneAndDelete-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/findOneAndDelete-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndDelete-serverErrors.yml index 5926026f0..688ee3342 100644 --- a/src/test/spec/json/retryable-writes/findOneAndDelete-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete-serverErrors.yml @@ -37,10 +37,10 @@ tests: mode: { times: 1 } data: failCommands: ["findAndModify"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "findOneAndDelete" arguments: diff --git a/src/test/spec/json/retryable-writes/findOneAndDelete.json b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete.json similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndDelete.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndDelete.json diff --git a/src/test/spec/json/retryable-writes/findOneAndDelete.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndDelete.yml similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndDelete.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndDelete.yml diff --git a/src/test/spec/json/retryable-writes/findOneAndReplace-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndReplace-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndReplace-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/findOneAndReplace-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndReplace-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndReplace-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/findOneAndReplace-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace-serverErrors.json similarity index 96% rename from src/test/spec/json/retryable-writes/findOneAndReplace-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndReplace-serverErrors.json index 64c69e2f6..944a3af84 100644 --- a/src/test/spec/json/retryable-writes/findOneAndReplace-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace-serverErrors.json @@ -85,12 +85,12 @@ "failCommands": [ "findAndModify" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/findOneAndReplace-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/findOneAndReplace-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndReplace-serverErrors.yml index 5a483e60b..6f0f31874 100644 --- a/src/test/spec/json/retryable-writes/findOneAndReplace-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace-serverErrors.yml @@ -39,10 +39,10 @@ tests: mode: { times: 1 } data: failCommands: ["findAndModify"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "findOneAndReplace" arguments: diff --git a/src/test/spec/json/retryable-writes/findOneAndReplace.json b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace.json similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndReplace.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndReplace.json diff --git a/src/test/spec/json/retryable-writes/findOneAndReplace.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndReplace.yml similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndReplace.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndReplace.yml diff --git a/src/test/spec/json/retryable-writes/findOneAndUpdate-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndUpdate-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/findOneAndUpdate-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndUpdate-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/findOneAndUpdate-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-serverErrors.json similarity index 96% rename from src/test/spec/json/retryable-writes/findOneAndUpdate-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-serverErrors.json index 9f5460499..e83a61061 100644 --- a/src/test/spec/json/retryable-writes/findOneAndUpdate-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-serverErrors.json @@ -86,12 +86,12 @@ "failCommands": [ "findAndModify" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/findOneAndUpdate-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/findOneAndUpdate-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-serverErrors.yml index 3c1fbe822..c1e0b6a7c 100644 --- a/src/test/spec/json/retryable-writes/findOneAndUpdate-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate-serverErrors.yml @@ -39,10 +39,10 @@ tests: mode: { times: 1 } data: failCommands: ["findAndModify"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "findOneAndUpdate" arguments: diff --git a/src/test/spec/json/retryable-writes/findOneAndUpdate.json b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate.json similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndUpdate.json rename to src/test/spec/json/retryable-writes/legacy/findOneAndUpdate.json diff --git a/src/test/spec/json/retryable-writes/findOneAndUpdate.yml b/src/test/spec/json/retryable-writes/legacy/findOneAndUpdate.yml similarity index 100% rename from src/test/spec/json/retryable-writes/findOneAndUpdate.yml rename to src/test/spec/json/retryable-writes/legacy/findOneAndUpdate.yml diff --git a/src/test/spec/json/retryable-writes/insertMany-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/insertMany-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/insertMany-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/insertMany-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/insertMany-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/insertMany-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/insertMany-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/insertMany-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/insertMany-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/insertMany-serverErrors.json similarity index 96% rename from src/test/spec/json/retryable-writes/insertMany-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/insertMany-serverErrors.json index 7b45b506c..fe8dbf4a6 100644 --- a/src/test/spec/json/retryable-writes/insertMany-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/insertMany-serverErrors.json @@ -92,12 +92,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/insertMany-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/insertMany-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/insertMany-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/insertMany-serverErrors.yml index 140329fcb..0dc7518c6 100644 --- a/src/test/spec/json/retryable-writes/insertMany-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/insertMany-serverErrors.yml @@ -41,10 +41,10 @@ tests: mode: { times: 1 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "insertMany" arguments: diff --git a/src/test/spec/json/retryable-writes/insertMany.json b/src/test/spec/json/retryable-writes/legacy/insertMany.json similarity index 100% rename from src/test/spec/json/retryable-writes/insertMany.json rename to src/test/spec/json/retryable-writes/legacy/insertMany.json diff --git a/src/test/spec/json/retryable-writes/insertMany.yml b/src/test/spec/json/retryable-writes/legacy/insertMany.yml similarity index 100% rename from src/test/spec/json/retryable-writes/insertMany.yml rename to src/test/spec/json/retryable-writes/legacy/insertMany.yml diff --git a/src/test/spec/json/retryable-writes/insertOne-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/insertOne-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/insertOne-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/insertOne-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/insertOne-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/insertOne-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/insertOne-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/insertOne-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/insertOne-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/insertOne-serverErrors.json similarity index 97% rename from src/test/spec/json/retryable-writes/insertOne-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/insertOne-serverErrors.json index e8571f8cf..5179a6ab7 100644 --- a/src/test/spec/json/retryable-writes/insertOne-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/insertOne-serverErrors.json @@ -761,12 +761,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 11600, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, @@ -812,12 +812,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 11602, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, @@ -863,12 +863,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 189, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, @@ -914,12 +914,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, @@ -965,12 +965,12 @@ "failCommands": [ "insert" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/insertOne-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/insertOne-serverErrors.yml similarity index 98% rename from src/test/spec/json/retryable-writes/insertOne-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/insertOne-serverErrors.yml index af50e761e..bfbd18774 100644 --- a/src/test/spec/json/retryable-writes/insertOne-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/insertOne-serverErrors.yml @@ -347,10 +347,10 @@ tests: mode: { times: 1 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 11600 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "insertOne" arguments: @@ -370,10 +370,10 @@ tests: mode: { times: 1 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 11602 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "insertOne" arguments: @@ -393,10 +393,10 @@ tests: mode: { times: 1 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 189 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "insertOne" arguments: @@ -416,10 +416,10 @@ tests: mode: { times: 1 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "insertOne" arguments: @@ -439,10 +439,10 @@ tests: mode: { times: 2 } data: failCommands: ["insert"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "insertOne" arguments: diff --git a/src/test/spec/json/retryable-writes/insertOne.json b/src/test/spec/json/retryable-writes/legacy/insertOne.json similarity index 100% rename from src/test/spec/json/retryable-writes/insertOne.json rename to src/test/spec/json/retryable-writes/legacy/insertOne.json diff --git a/src/test/spec/json/retryable-writes/insertOne.yml b/src/test/spec/json/retryable-writes/legacy/insertOne.yml similarity index 100% rename from src/test/spec/json/retryable-writes/insertOne.yml rename to src/test/spec/json/retryable-writes/legacy/insertOne.yml diff --git a/src/test/spec/json/retryable-writes/replaceOne-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/replaceOne-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/replaceOne-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/replaceOne-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/replaceOne-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/replaceOne-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/replaceOne-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/replaceOne-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/replaceOne-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/replaceOne-serverErrors.json similarity index 96% rename from src/test/spec/json/retryable-writes/replaceOne-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/replaceOne-serverErrors.json index 7457228cd..6b35722e1 100644 --- a/src/test/spec/json/retryable-writes/replaceOne-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/replaceOne-serverErrors.json @@ -85,12 +85,12 @@ "failCommands": [ "update" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/replaceOne-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/replaceOne-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/replaceOne-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/replaceOne-serverErrors.yml index 292f96ecb..3dd79db75 100644 --- a/src/test/spec/json/retryable-writes/replaceOne-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/replaceOne-serverErrors.yml @@ -41,10 +41,10 @@ tests: mode: { times: 1 } data: failCommands: ["update"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "replaceOne" arguments: diff --git a/src/test/spec/json/retryable-writes/replaceOne.json b/src/test/spec/json/retryable-writes/legacy/replaceOne.json similarity index 100% rename from src/test/spec/json/retryable-writes/replaceOne.json rename to src/test/spec/json/retryable-writes/legacy/replaceOne.json diff --git a/src/test/spec/json/retryable-writes/replaceOne.yml b/src/test/spec/json/retryable-writes/legacy/replaceOne.yml similarity index 100% rename from src/test/spec/json/retryable-writes/replaceOne.yml rename to src/test/spec/json/retryable-writes/legacy/replaceOne.yml diff --git a/src/test/spec/json/retryable-writes/updateMany.json b/src/test/spec/json/retryable-writes/legacy/updateMany.json similarity index 100% rename from src/test/spec/json/retryable-writes/updateMany.json rename to src/test/spec/json/retryable-writes/legacy/updateMany.json diff --git a/src/test/spec/json/retryable-writes/updateMany.yml b/src/test/spec/json/retryable-writes/legacy/updateMany.yml similarity index 100% rename from src/test/spec/json/retryable-writes/updateMany.yml rename to src/test/spec/json/retryable-writes/legacy/updateMany.yml diff --git a/src/test/spec/json/retryable-writes/updateOne-errorLabels.json b/src/test/spec/json/retryable-writes/legacy/updateOne-errorLabels.json similarity index 100% rename from src/test/spec/json/retryable-writes/updateOne-errorLabels.json rename to src/test/spec/json/retryable-writes/legacy/updateOne-errorLabels.json diff --git a/src/test/spec/json/retryable-writes/updateOne-errorLabels.yml b/src/test/spec/json/retryable-writes/legacy/updateOne-errorLabels.yml similarity index 100% rename from src/test/spec/json/retryable-writes/updateOne-errorLabels.yml rename to src/test/spec/json/retryable-writes/legacy/updateOne-errorLabels.yml diff --git a/src/test/spec/json/retryable-writes/updateOne-serverErrors.json b/src/test/spec/json/retryable-writes/legacy/updateOne-serverErrors.json similarity index 96% rename from src/test/spec/json/retryable-writes/updateOne-serverErrors.json rename to src/test/spec/json/retryable-writes/legacy/updateOne-serverErrors.json index 116019801..cf274f57e 100644 --- a/src/test/spec/json/retryable-writes/updateOne-serverErrors.json +++ b/src/test/spec/json/retryable-writes/legacy/updateOne-serverErrors.json @@ -86,12 +86,12 @@ "failCommands": [ "update" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/retryable-writes/updateOne-serverErrors.yml b/src/test/spec/json/retryable-writes/legacy/updateOne-serverErrors.yml similarity index 97% rename from src/test/spec/json/retryable-writes/updateOne-serverErrors.yml rename to src/test/spec/json/retryable-writes/legacy/updateOne-serverErrors.yml index 35ed406a5..fffe851ca 100644 --- a/src/test/spec/json/retryable-writes/updateOne-serverErrors.yml +++ b/src/test/spec/json/retryable-writes/legacy/updateOne-serverErrors.yml @@ -41,10 +41,10 @@ tests: mode: { times: 1 } data: failCommands: ["update"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operation: name: "updateOne" arguments: diff --git a/src/test/spec/json/retryable-writes/updateOne.json b/src/test/spec/json/retryable-writes/legacy/updateOne.json similarity index 100% rename from src/test/spec/json/retryable-writes/updateOne.json rename to src/test/spec/json/retryable-writes/legacy/updateOne.json diff --git a/src/test/spec/json/retryable-writes/updateOne.yml b/src/test/spec/json/retryable-writes/legacy/updateOne.yml similarity index 100% rename from src/test/spec/json/retryable-writes/updateOne.yml rename to src/test/spec/json/retryable-writes/legacy/updateOne.yml diff --git a/src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.json b/src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.json new file mode 100644 index 000000000..23cf2869a --- /dev/null +++ b/src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.json @@ -0,0 +1,205 @@ +{ + "description": "retryable-writes bulkWrite serverErrors", + "schemaVersion": "1.0", + "runOnRequirements": [ + { + "minServerVersion": "3.6", + "topologies": [ + "replicaset" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "retryable-writes-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll" + } + } + ], + "initialData": [ + { + "collectionName": "coll", + "databaseName": "retryable-writes-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + } + ] + } + ], + "tests": [ + { + "description": "BulkWrite succeeds after retryable writeConcernError in first batch", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.7", + "topologies": [ + "sharded-replicaset" + ] + } + ], + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "insert" + ], + "errorLabels": [ + "RetryableWriteError" + ], + "writeConcernError": { + "code": 91, + "errmsg": "Replication is being shut down" + } + } + } + } + }, + { + "name": "bulkWrite", + "object": "collection0", + "arguments": { + "requests": [ + { + "insertOne": { + "document": { + "_id": 3, + "x": 33 + } + } + }, + { + "deleteOne": { + "filter": { + "_id": 2 + } + } + } + ] + }, + "expectResult": { + "deletedCount": 1, + "insertedCount": 1, + "matchedCount": 0, + "modifiedCount": 0, + "upsertedCount": 0, + "insertedIds": { + "$$unsetOrMatches": { + "0": 3 + } + }, + "upsertedIds": {} + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 3, + "x": 33 + } + ] + }, + "commandName": "insert", + "databaseName": "retryable-writes-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 3, + "x": 33 + } + ] + }, + "commandName": "insert", + "databaseName": "retryable-writes-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "delete": "coll", + "deletes": [ + { + "q": { + "_id": 2 + }, + "limit": 1 + } + ] + }, + "commandName": "delete", + "databaseName": "retryable-writes-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "coll", + "databaseName": "retryable-writes-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 3, + "x": 33 + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.yml b/src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.yml new file mode 100644 index 000000000..cb67304c7 --- /dev/null +++ b/src/test/spec/json/retryable-writes/unified/bulkWrite-serverErrors.yml @@ -0,0 +1,96 @@ +description: "retryable-writes bulkWrite serverErrors" + +schemaVersion: "1.0" + +runOnRequirements: + - minServerVersion: "3.6" + topologies: [ replicaset ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName retryable-writes-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName coll + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1, x: 11 } + - { _id: 2, x: 22 } + +tests: + - description: "BulkWrite succeeds after retryable writeConcernError in first batch" + runOnRequirements: + - minServerVersion: "4.0" + topologies: [ replicaset ] + - minServerVersion: "4.1.7" + topologies: [ sharded-replicaset ] + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: [ insert ] + errorLabels: [RetryableWriteError] # top-level error labels + writeConcernError: + code: 91 # ShutdownInProgress + errmsg: "Replication is being shut down" + - name: bulkWrite + object: *collection0 + arguments: + requests: + - insertOne: + document: { _id: 3, x: 33 } + - deleteOne: + filter: { _id: 2 } + expectResult: + deletedCount: 1 + insertedCount: 1 + matchedCount: 0 + modifiedCount: 0 + upsertedCount: 0 + insertedIds: { $$unsetOrMatches: { 0: 3 } } + upsertedIds: { } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: [{ _id: 3, x: 33 }] + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: *collectionName + documents: [{ _id: 3, x: 33 }] + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + delete: *collectionName + deletes: + - + q: { _id: 2 } + limit: 1 + commandName: delete + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1, x: 11 } + - { _id: 3, x: 33 } # The write was still applied diff --git a/src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.json b/src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.json new file mode 100644 index 000000000..77245a819 --- /dev/null +++ b/src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.json @@ -0,0 +1,173 @@ +{ + "description": "retryable-writes insertOne serverErrors", + "schemaVersion": "1.0", + "runOnRequirements": [ + { + "minServerVersion": "3.6", + "topologies": [ + "replicaset" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "retryable-writes-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll" + } + } + ], + "initialData": [ + { + "collectionName": "coll", + "databaseName": "retryable-writes-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + } + ] + } + ], + "tests": [ + { + "description": "InsertOne succeeds after retryable writeConcernError", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.7", + "topologies": [ + "sharded-replicaset" + ] + } + ], + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "insert" + ], + "errorLabels": [ + "RetryableWriteError" + ], + "writeConcernError": { + "code": 91, + "errmsg": "Replication is being shut down" + } + } + } + } + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 3, + "x": 33 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 3 + } + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 3, + "x": 33 + } + ] + }, + "commandName": "insert", + "databaseName": "retryable-writes-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "coll", + "documents": [ + { + "_id": 3, + "x": 33 + } + ] + }, + "commandName": "insert", + "databaseName": "retryable-writes-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "coll", + "databaseName": "retryable-writes-tests", + "documents": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": 2, + "x": 22 + }, + { + "_id": 3, + "x": 33 + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.yml b/src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.yml new file mode 100644 index 000000000..3d9672cdc --- /dev/null +++ b/src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.yml @@ -0,0 +1,78 @@ +description: "retryable-writes insertOne serverErrors" + +schemaVersion: "1.0" + +runOnRequirements: + - minServerVersion: "3.6" + topologies: [ replicaset ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName retryable-writes-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName coll + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1, x: 11 } + - { _id: 2, x: 22 } + +tests: + - description: "InsertOne succeeds after retryable writeConcernError" + runOnRequirements: + - minServerVersion: "4.0" + topologies: [ replicaset ] + - minServerVersion: "4.1.7" + topologies: [ sharded-replicaset ] + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: [ insert ] + errorLabels: [RetryableWriteError] # top-level error labels + writeConcernError: + code: 91 # ShutdownInProgress + errmsg: "Replication is being shut down" + - name: insertOne + object: *collection0 + arguments: + document: { _id: 3, x: 33 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 3 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: [{ _id: 3, x: 33 }] + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: *collectionName + documents: [{ _id: 3, x: 33 }] + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1, x: 11 } + - { _id: 2, x: 22 } + - { _id: 3, x: 33 } # The write was still applied diff --git a/src/test/spec/json/transactions/README.rst b/src/test/spec/json/transactions/README.rst index d4abd04f1..a1b27dcf0 100644 --- a/src/test/spec/json/transactions/README.rst +++ b/src/test/spec/json/transactions/README.rst @@ -9,10 +9,14 @@ Transactions Tests Introduction ============ -The YAML and JSON files in this directory are platform-independent tests that -drivers can use to prove their conformance to the Transactions Spec. They are -designed with the intention of sharing some test-runner code with the CRUD Spec -tests and the Command Monitoring Spec tests. +The YAML and JSON files in the ``legacy`` and ``unified`` sub-directories are +platform-independent tests that drivers can use to prove their conformance to +the Transactions Spec. The tests in the ``legacy`` directory are designed with +the intention of sharing some test-runner code with the CRUD Spec tests and the +Command Monitoring Spec tests. The format for these tests and instructions for +executing them are provided in the following sections. Tests in the +``unified`` directory are written using the `Unified Test Format +<../../unified-test-format/unified-test-format.rst>`_. Several prose tests, which are not easily expressed in YAML, are also presented in this file. Those tests will need to be manually implemented by each driver. @@ -108,6 +112,18 @@ Each YAML file has the following keys: and "sharded". If this field is omitted, the default is all topologies (i.e. ``["single", "replicaset", "sharded"]``). + - ``serverless``: Optional string. Whether or not the test should be run on + serverless instances imitating sharded clusters. Valid values are "require", + "forbid", and "allow". If "require", the test MUST only be run on serverless + instances. If "forbid", the test MUST NOT be run on serverless instances. If + omitted or "allow", this option has no effect. + + The test runner MUST be informed whether or not serverless is being used in + order to determine if this requirement is met (e.g. through an environment + variable or configuration option). Since the serverless proxy imitates a + mongos, the runner is not capable of determining this by issuing a server + command such as ``buildInfo`` or ``hello``. + - ``database_name`` and ``collection_name``: The database and collection to use for testing. diff --git a/src/test/spec/json/transactions/legacy/error-labels.json b/src/test/spec/json/transactions/legacy/error-labels.json index 2d3eed3cc..0be19c731 100644 --- a/src/test/spec/json/transactions/legacy/error-labels.json +++ b/src/test/spec/json/transactions/legacy/error-labels.json @@ -10,7 +10,8 @@ "minServerVersion": "4.1.8", "topology": [ "sharded" - ] + ], + "serverless": "forbid" } ], "database_name": "transaction-tests", @@ -102,7 +103,7 @@ } }, { - "description": "NotMaster errors contain transient label", + "description": "NotWritablePrimary errors contain transient label", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -962,12 +963,12 @@ "failCommands": [ "commitTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } }, diff --git a/src/test/spec/json/transactions/legacy/error-labels.yml b/src/test/spec/json/transactions/legacy/error-labels.yml index 3fc36c8f0..1f8dbe4db 100644 --- a/src/test/spec/json/transactions/legacy/error-labels.yml +++ b/src/test/spec/json/transactions/legacy/error-labels.yml @@ -5,6 +5,9 @@ runOn: - minServerVersion: "4.1.8" topology: ["sharded"] + # serverless proxy doesn't append error labels to errors in transactions + # caused by failpoints (CLOUDP-88216) + serverless: "forbid" database_name: &database_name "transaction-tests" collection_name: &collection_name "test" @@ -65,14 +68,14 @@ tests: collection: data: [] - - description: NotMaster errors contain transient label + - description: NotWritablePrimary errors contain transient label failPoint: configureFailPoint: failCommand mode: { times: 1 } data: failCommands: ["insert"] - errorCode: 10107 # NotMaster + errorCode: 10107 # NotWritablePrimary operations: - name: startTransaction @@ -587,10 +590,10 @@ tests: mode: { times: 2 } data: failCommands: ["commitTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] operations: - name: startTransaction diff --git a/src/test/spec/json/transactions/legacy/errors-client.json b/src/test/spec/json/transactions/legacy/errors-client.json new file mode 100644 index 000000000..15fae96fe --- /dev/null +++ b/src/test/spec/json/transactions/legacy/errors-client.json @@ -0,0 +1,96 @@ +{ + "runOn": [ + { + "minServerVersion": "4.0", + "topology": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topology": [ + "sharded" + ] + } + ], + "database_name": "transaction-tests", + "collection_name": "test", + "data": [], + "tests": [ + { + "description": "Client side error in command starting transaction", + "operations": [ + { + "name": "startTransaction", + "object": "session0" + }, + { + "name": "updateOne", + "object": "collection", + "arguments": { + "session": "session0", + "filter": { + "_id": 1 + }, + "update": { + "x": 1 + } + }, + "error": true + }, + { + "name": "assertSessionTransactionState", + "object": "testRunner", + "arguments": { + "session": "session0", + "state": "starting" + } + } + ] + }, + { + "description": "Client side error when transaction is in progress", + "operations": [ + { + "name": "startTransaction", + "object": "session0" + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "result": { + "insertedId": 1 + } + }, + { + "name": "updateOne", + "object": "collection", + "arguments": { + "session": "session0", + "filter": { + "_id": 1 + }, + "update": { + "x": 1 + } + }, + "error": true + }, + { + "name": "assertSessionTransactionState", + "object": "testRunner", + "arguments": { + "session": "session0", + "state": "in_progress" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/transactions/legacy/errors-client.yml b/src/test/spec/json/transactions/legacy/errors-client.yml new file mode 100644 index 000000000..38b110424 --- /dev/null +++ b/src/test/spec/json/transactions/legacy/errors-client.yml @@ -0,0 +1,55 @@ +runOn: + - + minServerVersion: "4.0" + topology: ["replicaset"] + - + minServerVersion: "4.1.8" + topology: ["sharded"] + +database_name: &database_name "transaction-tests" +collection_name: &collection_name "test" + +data: [] +tests: + - description: Client side error in command starting transaction + + operations: + - name: startTransaction + object: session0 + - name: updateOne + object: collection + arguments: + session: session0 + filter: { _id: 1 } + update: { x: 1 } + error: true + - name: assertSessionTransactionState + object: testRunner + arguments: + session: session0 + state: starting + + - description: Client side error when transaction is in progress + + operations: + - name: startTransaction + object: session0 + - name: insertOne + object: collection + arguments: + session: session0 + document: { _id: 1 } + result: + insertedId: 1 + - name: updateOne + object: collection + arguments: + session: session0 + filter: { _id: 1 } + update: { x: 1 } + error: true + - name: assertSessionTransactionState + object: testRunner + arguments: + session: session0 + state: in_progress diff --git a/src/test/spec/json/transactions/legacy/mongos-pin-auto-tests.py b/src/test/spec/json/transactions/legacy/mongos-pin-auto-tests.py new file mode 100644 index 000000000..1072ec290 --- /dev/null +++ b/src/test/spec/json/transactions/legacy/mongos-pin-auto-tests.py @@ -0,0 +1,340 @@ +import itertools +import sys + +# Require Python 3.7+ for ordered dictionaries so that the order of the +# generated tests remain the same. +# Usage: +# python3.7 mongos-pin-auto-tests.py > mongos-pin-auto.yml +if sys.version_info[:2] < (3, 7): + print('ERROR: This script requires Python >= 3.7, not:') + print(sys.version) + print('Usage: python3.7 mongos-pin-auto-tests.py > mongos-pin-auto.yml') + exit(1) + +HEADER = '''# Autogenerated tests that transient errors in a transaction unpin the session. +# See mongos-pin-auto-tests.py +runOn: + - + minServerVersion: "4.1.8" + topology: ["sharded"] + # serverless proxy doesn't append error labels to errors in transactions + # caused by failpoints (CLOUDP-88216) + serverless: "forbid" + +database_name: &database_name "transaction-tests" +collection_name: &collection_name "test" + +data: &data + - {_id: 1} + - {_id: 2} + +tests: + - description: remain pinned after non-transient Interrupted error on insertOne + useMultipleMongoses: true + operations: + - &startTransaction + name: startTransaction + object: session0 + - &initialCommand + name: insertOne + object: collection + arguments: + session: session0 + document: {_id: 3} + result: + insertedId: 3 + - name: targetedFailPoint + object: testRunner + arguments: + session: session0 + failPoint: + configureFailPoint: failCommand + mode: {times: 1} + data: + failCommands: ["insert"] + errorCode: 11601 + - name: insertOne + object: collection + arguments: + session: session0 + document: + _id: 4 + result: + errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] + errorCodeName: Interrupted + - &assertSessionPinned + name: assertSessionPinned + object: testRunner + arguments: + session: session0 + - &commitTransaction + name: commitTransaction + object: session0 + + expectations: + - command_started_event: + command: + insert: *collection_name + documents: + - _id: 3 + ordered: true + readConcern: + lsid: session0 + txnNumber: + $numberLong: "1" + startTransaction: true + autocommit: false + writeConcern: + command_name: insert + database_name: *database_name + - command_started_event: + command: + insert: *collection_name + documents: + - _id: 4 + ordered: true + readConcern: + lsid: session0 + txnNumber: + $numberLong: "1" + startTransaction: + autocommit: false + writeConcern: + command_name: insert + database_name: *database_name + - command_started_event: + command: + commitTransaction: 1 + lsid: session0 + txnNumber: + $numberLong: "1" + startTransaction: + autocommit: false + writeConcern: + recoveryToken: 42 + command_name: commitTransaction + database_name: admin + + outcome: &outcome + collection: + data: + - {_id: 1} + - {_id: 2} + - {_id: 3} + + - description: unpin after transient error within a transaction + useMultipleMongoses: true + operations: + - &startTransaction + name: startTransaction + object: session0 + - &initialCommand + name: insertOne + object: collection + arguments: + session: session0 + document: + _id: 3 + result: + insertedId: 3 + - name: targetedFailPoint + object: testRunner + arguments: + session: session0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: ["insert"] + closeConnection: true + - name: insertOne + object: collection + arguments: + session: session0 + document: + _id: 4 + result: + errorLabelsContain: ["TransientTransactionError"] + errorLabelsOmit: ["UnknownTransactionCommitResult"] + # Session unpins from the first mongos after the insert error and + # abortTransaction succeeds immediately on any mongos. + - &assertSessionUnpinned + name: assertSessionUnpinned + object: testRunner + arguments: + session: session0 + - &abortTransaction + name: abortTransaction + object: session0 + + expectations: + - command_started_event: + command: + insert: *collection_name + documents: + - _id: 3 + ordered: true + readConcern: + lsid: session0 + txnNumber: + $numberLong: "1" + startTransaction: true + autocommit: false + writeConcern: + command_name: insert + database_name: *database_name + - command_started_event: + command: + insert: *collection_name + documents: + - _id: 4 + ordered: true + readConcern: + lsid: session0 + txnNumber: + $numberLong: "1" + startTransaction: + autocommit: false + writeConcern: + command_name: insert + database_name: *database_name + - command_started_event: + command: + abortTransaction: 1 + lsid: session0 + txnNumber: + $numberLong: "1" + startTransaction: + autocommit: false + writeConcern: + recoveryToken: 42 + command_name: abortTransaction + database_name: admin + + outcome: &outcome + collection: + data: *data + + # The rest of the tests in this file test every operation type against + # multiple types of transient errors (connection and error code).''' + +TEMPLATE = ''' + - description: {test_name} {error_name} error on {op_name} {command_name} + useMultipleMongoses: true + operations: + - *startTransaction + - *initialCommand + - name: targetedFailPoint + object: testRunner + arguments: + session: session0 + failPoint: + configureFailPoint: failCommand + mode: {{times: 1}} + data: + failCommands: ["{command_name}"] + {error_data} + - name: {op_name} + object: {object_name} + arguments: + session: session0 + {op_args} + result: + {error_labels}: ["TransientTransactionError"] + - *{assertion} + - *abortTransaction + outcome: *outcome +''' + + +# Maps from op_name to (command_name, object_name, op_args) +OPS = { + # Write ops: + 'insertOne': ('insert', 'collection', r'document: {_id: 4}'), + 'insertMany': ('insert', 'collection', r'documents: [{_id: 4}, {_id: 5}]'), + 'updateOne': ('update', 'collection', r'''filter: {_id: 1} + update: {$inc: {x: 1}}'''), + 'replaceOne': ('update', 'collection', r'''filter: {_id: 1} + replacement: {y: 1}'''), + 'updateMany': ('update', 'collection', r'''filter: {_id: {$gte: 1}} + update: {$set: {z: 1}}'''), + 'deleteOne': ('delete', 'collection', r'filter: {_id: 1}'), + 'deleteMany': ('delete', 'collection', r'filter: {_id: {$gte: 1}}'), + 'findOneAndDelete': ('findAndModify', 'collection', r'filter: {_id: 1}'), + 'findOneAndUpdate': ('findAndModify', 'collection', r'''filter: {_id: 1} + update: {$inc: {x: 1}} + returnDocument: Before'''), + 'findOneAndReplace': ('findAndModify', 'collection', r'''filter: {_id: 1} + replacement: {y: 1} + returnDocument: Before'''), + # Bulk write insert/update/delete: + 'bulkWrite insert': ('insert', 'collection', r'''requests: + - name: insertOne + arguments: + document: {_id: 1}'''), + 'bulkWrite update': ('update', 'collection', r'''requests: + - name: updateOne + arguments: + filter: {_id: 1} + update: {$set: {x: 1}}'''), + 'bulkWrite delete': ('delete', 'collection', r'''requests: + - name: deleteOne + arguments: + filter: {_id: 1}'''), + # Read ops: + 'find': ('find', 'collection', r'filter: {_id: 1}'), + 'countDocuments': ('aggregate', 'collection', r'filter: {}'), + 'aggregate': ('aggregate', 'collection', r'pipeline: []'), + 'distinct': ('distinct', 'collection', r'fieldName: _id'), + # runCommand: + 'runCommand': ( + 'insert', + r'''database + command_name: insert''', # runCommand requires command_name. + r'''command: + insert: *collection_name + documents: + - _id : 1'''), +} + +# Maps from error_name to error_data. +NON_TRANSIENT_ERRORS = { + 'Interrupted': 'errorCode: 11601', +} + +# Maps from error_name to error_data. +TRANSIENT_ERRORS = { + 'connection': 'closeConnection: true', + 'ShutdownInProgress': 'errorCode: 91', +} + + +def create_pin_test(op_name, error_name): + test_name = 'remain pinned after non-transient' + assertion = 'assertSessionPinned' + error_labels = 'errorLabelsOmit' + command_name, object_name, op_args = OPS[op_name] + error_data = NON_TRANSIENT_ERRORS[error_name] + if op_name.startswith('bulkWrite'): + op_name = 'bulkWrite' + return TEMPLATE.format(**locals()) + + +def create_unpin_test(op_name, error_name): + test_name = 'unpin after transient' + assertion = 'assertSessionUnpinned' + error_labels = 'errorLabelsContain' + command_name, object_name, op_args = OPS[op_name] + error_data = TRANSIENT_ERRORS[error_name] + if op_name.startswith('bulkWrite'): + op_name = 'bulkWrite' + return TEMPLATE.format(**locals()) + +tests = [] +for op_name, error_name in itertools.product(OPS, NON_TRANSIENT_ERRORS): + tests.append(create_pin_test(op_name, error_name)) +for op_name, error_name in itertools.product(OPS, TRANSIENT_ERRORS): + tests.append(create_unpin_test(op_name, error_name)) + +print(HEADER) +print(''.join(tests)) diff --git a/src/test/spec/json/transactions/legacy/mongos-pin-auto.json b/src/test/spec/json/transactions/legacy/mongos-pin-auto.json index f6ede5268..037f212f4 100644 --- a/src/test/spec/json/transactions/legacy/mongos-pin-auto.json +++ b/src/test/spec/json/transactions/legacy/mongos-pin-auto.json @@ -4,7 +4,8 @@ "minServerVersion": "4.1.8", "topology": [ "sharded" - ] + ], + "serverless": "forbid" } ], "database_name": "transaction-tests", diff --git a/src/test/spec/json/transactions/legacy/mongos-pin-auto.yml b/src/test/spec/json/transactions/legacy/mongos-pin-auto.yml index f2b84ac8d..7e2e3e445 100644 --- a/src/test/spec/json/transactions/legacy/mongos-pin-auto.yml +++ b/src/test/spec/json/transactions/legacy/mongos-pin-auto.yml @@ -4,6 +4,9 @@ runOn: - minServerVersion: "4.1.8" topology: ["sharded"] + # serverless proxy doesn't append error labels to errors in transactions + # caused by failpoints (CLOUDP-88216) + serverless: "forbid" database_name: &database_name "transaction-tests" collection_name: &collection_name "test" diff --git a/src/test/spec/json/transactions/legacy/mongos-recovery-token.json b/src/test/spec/json/transactions/legacy/mongos-recovery-token.json index 35ef45a03..da4e9861d 100644 --- a/src/test/spec/json/transactions/legacy/mongos-recovery-token.json +++ b/src/test/spec/json/transactions/legacy/mongos-recovery-token.json @@ -4,7 +4,8 @@ "minServerVersion": "4.1.8", "topology": [ "sharded" - ] + ], + "serverless": "forbid" } ], "database_name": "transaction-tests", @@ -179,12 +180,12 @@ "failCommands": [ "commitTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errmsg": "Replication is being shut down", - "errorLabels": [ - "RetryableWriteError" - ] + "errmsg": "Replication is being shut down" } } } @@ -306,7 +307,8 @@ "data": { "failCommands": [ "commitTransaction", - "isMaster" + "isMaster", + "hello" ], "closeConnection": true } diff --git a/src/test/spec/json/transactions/legacy/mongos-recovery-token.yml b/src/test/spec/json/transactions/legacy/mongos-recovery-token.yml index 94f32b1d3..e8763db88 100644 --- a/src/test/spec/json/transactions/legacy/mongos-recovery-token.yml +++ b/src/test/spec/json/transactions/legacy/mongos-recovery-token.yml @@ -2,6 +2,8 @@ runOn: - minServerVersion: "4.1.8" topology: ["sharded"] + # serverless proxy doesn't use recovery tokens + serverless: "forbid" database_name: &database_name "transaction-tests" collection_name: &collection_name "test" @@ -116,10 +118,10 @@ tests: mode: { times: 1 } data: failCommands: ["commitTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 errmsg: Replication is being shut down - errorLabels: ["RetryableWriteError"] # The client sees a retryable writeConcernError on the first # commitTransaction due to the fail point but it actually succeeds on the # server (SERVER-39346). The retry will succeed both on a new mongos and @@ -194,7 +196,7 @@ tests: result: insertedId: 1 # Enable the fail point only on the Mongos that session0 is pinned to. - # Fail isMaster to prevent the heartbeat requested directly after the + # Fail hello/legacy hello to prevent the heartbeat requested directly after the # retryable commit error from racing with server selection for the retry. # Note: times: 7 is slightly artbitrary but it accounts for one failed # commit and some SDAM heartbeats. A test runner will have multiple @@ -208,7 +210,7 @@ tests: configureFailPoint: failCommand mode: { times: 7 } data: - failCommands: ["commitTransaction", "isMaster"] + failCommands: ["commitTransaction", "isMaster", "hello"] closeConnection: true # The first commitTransaction sees a retryable connection error due to # the fail point and also fails on the server. The retry attempt on a @@ -216,7 +218,7 @@ tests: # because the transaction was aborted. Note that the retry attempt should # not select the original mongos because that server's SDAM state is # reset by the connection error, heartbeatFrequencyMS is high, and - # subsequent isMaster heartbeats should fail. + # subsequent heartbeats should fail. - name: commitTransaction object: session0 result: diff --git a/src/test/spec/json/transactions/legacy/pin-mongos.json b/src/test/spec/json/transactions/legacy/pin-mongos.json index 8e9d049d0..485a3d932 100644 --- a/src/test/spec/json/transactions/legacy/pin-mongos.json +++ b/src/test/spec/json/transactions/legacy/pin-mongos.json @@ -4,7 +4,8 @@ "minServerVersion": "4.1.8", "topology": [ "sharded" - ] + ], + "serverless": "forbid" } ], "database_name": "transaction-tests", @@ -1106,7 +1107,8 @@ "data": { "failCommands": [ "insert", - "isMaster" + "isMaster", + "hello" ], "closeConnection": true } diff --git a/src/test/spec/json/transactions/legacy/pin-mongos.yml b/src/test/spec/json/transactions/legacy/pin-mongos.yml index b611e5003..067506dba 100644 --- a/src/test/spec/json/transactions/legacy/pin-mongos.yml +++ b/src/test/spec/json/transactions/legacy/pin-mongos.yml @@ -16,6 +16,9 @@ runOn: - minServerVersion: "4.1.8" topology: ["sharded"] + # serverless proxy doesn't append error labels to errors in transactions + # caused by failpoints (CLOUDP-88216) + serverless: "forbid" database_name: &database_name "transaction-tests" collection_name: &collection_name "test" @@ -461,7 +464,7 @@ tests: result: insertedId: 3 # Enable the fail point only on the Mongos that session0 is pinned to. - # Fail isMaster to prevent the heartbeat requested directly after the + # Fail hello/legacy hello to prevent the heartbeat requested directly after the # insert error from racing with server selection for the commit. # Note: times: 7 is slightly artbitrary but it accounts for one failed # insert and some SDAM heartbeats. A test runner will have multiple @@ -475,7 +478,7 @@ tests: configureFailPoint: failCommand mode: { times: 7 } data: - failCommands: ["insert", "isMaster"] + failCommands: ["insert", "isMaster", "hello"] closeConnection: true - name: insertOne object: collection @@ -495,7 +498,7 @@ tests: # # Note that the commit attempt should not select the original mongos # because that server's SDAM state is reset by the connection error, - # heartbeatFrequencyMS is high, and subsequent isMaster heartbeats + # heartbeatFrequencyMS is high, and subsequent heartbeats # should fail. - name: commitTransaction object: session0 diff --git a/src/test/spec/json/transactions/legacy/retryable-abort.json b/src/test/spec/json/transactions/legacy/retryable-abort.json index 5a3aaa7bf..13cc7c88f 100644 --- a/src/test/spec/json/transactions/legacy/retryable-abort.json +++ b/src/test/spec/json/transactions/legacy/retryable-abort.json @@ -402,7 +402,7 @@ } }, { - "description": "abortTransaction succeeds after NotMaster", + "description": "abortTransaction succeeds after NotWritablePrimary", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -506,7 +506,7 @@ } }, { - "description": "abortTransaction succeeds after NotMasterOrSecondary", + "description": "abortTransaction succeeds after NotPrimaryOrSecondary", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -610,7 +610,7 @@ } }, { - "description": "abortTransaction succeeds after NotMasterNoSlaveOk", + "description": "abortTransaction succeeds after NotPrimaryNoSecondaryOk", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -1556,11 +1556,11 @@ "failCommands": [ "abortTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 11600, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } @@ -1673,11 +1673,11 @@ "failCommands": [ "abortTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 11602, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } @@ -1790,11 +1790,11 @@ "failCommands": [ "abortTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 189, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } @@ -1907,11 +1907,11 @@ "failCommands": [ "abortTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } diff --git a/src/test/spec/json/transactions/legacy/retryable-abort.yml b/src/test/spec/json/transactions/legacy/retryable-abort.yml index 5719b13a9..b129189d7 100644 --- a/src/test/spec/json/transactions/legacy/retryable-abort.yml +++ b/src/test/spec/json/transactions/legacy/retryable-abort.yml @@ -266,7 +266,7 @@ tests: collection: data: [] - - description: abortTransaction succeeds after NotMaster + - description: abortTransaction succeeds after NotWritablePrimary failPoint: configureFailPoint: failCommand @@ -334,7 +334,7 @@ tests: collection: data: [] - - description: abortTransaction succeeds after NotMasterOrSecondary + - description: abortTransaction succeeds after NotPrimaryOrSecondary failPoint: configureFailPoint: failCommand @@ -402,7 +402,7 @@ tests: collection: data: [] - - description: abortTransaction succeeds after NotMasterNoSlaveOk + - description: abortTransaction succeeds after NotPrimaryNoSecondaryOk failPoint: configureFailPoint: failCommand @@ -1021,9 +1021,9 @@ tests: mode: { times: 1 } data: failCommands: ["abortTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 11600 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: @@ -1096,9 +1096,9 @@ tests: mode: { times: 1 } data: failCommands: ["abortTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 11602 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: @@ -1171,9 +1171,9 @@ tests: mode: { times: 1 } data: failCommands: ["abortTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 189 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: @@ -1246,9 +1246,9 @@ tests: mode: { times: 1 } data: failCommands: ["abortTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: diff --git a/src/test/spec/json/transactions/legacy/retryable-commit.json b/src/test/spec/json/transactions/legacy/retryable-commit.json index 4895c6e0c..49148c62d 100644 --- a/src/test/spec/json/transactions/legacy/retryable-commit.json +++ b/src/test/spec/json/transactions/legacy/retryable-commit.json @@ -624,7 +624,7 @@ } }, { - "description": "commitTransaction succeeds after NotMaster", + "description": "commitTransaction succeeds after NotWritablePrimary", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -735,7 +735,7 @@ } }, { - "description": "commitTransaction succeeds after NotMasterOrSecondary", + "description": "commitTransaction succeeds after NotPrimaryOrSecondary", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -846,7 +846,7 @@ } }, { - "description": "commitTransaction succeeds after NotMasterNoSlaveOk", + "description": "commitTransaction succeeds after NotPrimaryNoSecondaryOk", "failPoint": { "configureFailPoint": "failCommand", "mode": { @@ -1855,11 +1855,11 @@ "failCommands": [ "commitTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 11600, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } @@ -1977,11 +1977,11 @@ "failCommands": [ "commitTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 11602, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } @@ -2099,11 +2099,11 @@ "failCommands": [ "commitTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 189, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } @@ -2221,11 +2221,11 @@ "failCommands": [ "commitTransaction" ], + "errorLabels": [ + "RetryableWriteError" + ], "writeConcernError": { "code": 91, - "errorLabels": [ - "RetryableWriteError" - ], "errmsg": "Replication is being shut down" } } diff --git a/src/test/spec/json/transactions/legacy/retryable-commit.yml b/src/test/spec/json/transactions/legacy/retryable-commit.yml index 6db06bb63..f38b7343a 100644 --- a/src/test/spec/json/transactions/legacy/retryable-commit.yml +++ b/src/test/spec/json/transactions/legacy/retryable-commit.yml @@ -385,7 +385,7 @@ tests: data: - _id: 1 - - description: commitTransaction succeeds after NotMaster + - description: commitTransaction succeeds after NotWritablePrimary failPoint: configureFailPoint: failCommand @@ -455,7 +455,7 @@ tests: data: - _id: 1 - - description: commitTransaction succeeds after NotMasterOrSecondary + - description: commitTransaction succeeds after NotPrimaryOrSecondary failPoint: configureFailPoint: failCommand @@ -525,7 +525,7 @@ tests: data: - _id: 1 - - description: commitTransaction succeeds after NotMasterNoSlaveOk + - description: commitTransaction succeeds after NotPrimaryNoSecondaryOk failPoint: configureFailPoint: failCommand @@ -1162,9 +1162,9 @@ tests: mode: { times: 1 } data: failCommands: ["commitTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 11600 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: @@ -1238,9 +1238,9 @@ tests: mode: { times: 1 } data: failCommands: ["commitTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 11602 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: @@ -1314,9 +1314,9 @@ tests: mode: { times: 1 } data: failCommands: ["commitTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 189 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: @@ -1390,9 +1390,9 @@ tests: mode: { times: 1 } data: failCommands: ["commitTransaction"] + errorLabels: ["RetryableWriteError"] writeConcernError: code: 91 - errorLabels: ["RetryableWriteError"] errmsg: Replication is being shut down operations: diff --git a/src/test/spec/retryable_writes/mod.rs b/src/test/spec/retryable_writes/mod.rs index c5cd4a507..2bf8499ac 100644 --- a/src/test/spec/retryable_writes/mod.rs +++ b/src/test/spec/retryable_writes/mod.rs @@ -2,7 +2,6 @@ mod test_file; use std::{sync::Arc, time::Duration}; -use bson::Bson; use futures::stream::TryStreamExt; use semver::VersionReq; use tokio::sync::{RwLockReadGuard, RwLockWriteGuard}; @@ -36,9 +35,18 @@ use crate::{ RUNTIME, }; +use super::run_unified_format_test; + +#[cfg_attr(feature = "tokio-runtime", tokio::test(flavor = "multi_thread"))] +#[cfg_attr(feature = "async-std-runtime", async_std::test)] +async fn run_unified() { + let _guard: RwLockWriteGuard<()> = LOCK.run_exclusively().await; + run_spec_test(&["retryable-writes", "unified"], run_unified_format_test).await; +} + #[cfg_attr(feature = "tokio-runtime", tokio::test)] #[cfg_attr(feature = "async-std-runtime", async_std::test)] -async fn run_spec_tests() { +async fn run_legacy() { async fn run_test(test_file: TestFile) { for mut test_case in test_file.tests { if test_case.operation.name == "bulkWrite" { @@ -77,14 +85,6 @@ async fn run_spec_tests() { } if let Some(ref mut fail_point) = test_case.fail_point { - // TODO: DRIVERS-1385 remove this logic for moving errorLabels to the top level. - if let Some(Bson::Document(data)) = fail_point.get_mut("data") { - if let Some(Bson::Document(wc_error)) = data.get("writeConcernError") { - if let Some(labels) = wc_error.get("errorLabels").cloned() { - data.insert("errorLabels", labels); - } - } - } client .database("admin") .run_command(fail_point.clone(), None) @@ -185,7 +185,7 @@ async fn run_spec_tests() { } let _guard: RwLockWriteGuard<()> = LOCK.run_exclusively().await; - run_spec_test(&["retryable-writes"], run_test).await; + run_spec_test(&["retryable-writes", "legacy"], run_test).await; } #[cfg_attr(feature = "tokio-runtime", tokio::test)] diff --git a/src/test/util/failpoint.rs b/src/test/util/failpoint.rs index 27a917b29..f87dfb031 100644 --- a/src/test/util/failpoint.rs +++ b/src/test/util/failpoint.rs @@ -1,4 +1,4 @@ -use bson::{doc, Bson, Document}; +use bson::{doc, Document}; use serde::{Deserialize, Serialize, Serializer}; use std::time::Duration; use typed_builder::TypedBuilder; @@ -48,20 +48,10 @@ impl FailPoint { client: &Client, criteria: impl Into>, ) -> Result { - // TODO: DRIVERS-1385 remove this logic for moving errorLabels to the top level. - let mut command = self.command.clone(); - if let Some(Bson::Document(data)) = command.get_mut("data") { - if let Some(Bson::Document(wc_error)) = data.get_mut("writeConcernError") { - if let Some(labels) = wc_error.remove("errorLabels") { - data.insert("errorLabels", labels); - } - } - } - let criteria = criteria.into(); client .database("admin") - .run_command(command, criteria.clone()) + .run_command(self.command.clone(), criteria.clone()) .await?; Ok(FailPointGuard { failpoint_name: self.name().to_string(),