From 690ef395bcff37a42124437abe6dcb3d3e5fc816 Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Tue, 13 Feb 2024 12:02:44 +0100 Subject: [PATCH] test(NODE-5930): convert convenient api to unified format --- src/sessions.ts | 2 + .../transactions-convenient-api.spec.test.js | 89 -- .../transactions-convenient-api.spec.test.ts | 18 + .../unified_test_format.spec.test.ts | 2 +- .../transactions-convenient-api/README.rst | 220 ---- .../callback-aborts.json | 244 ----- .../callback-aborts.yml | 170 --- .../callback-commits.json | 303 ------ .../callback-commits.yml | 204 ---- .../callback-retry.json | 315 ------ .../callback-retry.yml | 215 ---- .../commit-retry.json | 531 ---------- .../commit-retry.yml | 325 ------ .../commit-transienttransactionerror-4.2.json | 197 ---- .../commit-transienttransactionerror-4.2.yml | 139 --- .../commit-transienttransactionerror.json | 725 ------------- .../commit-transienttransactionerror.yml | 175 --- .../commit-writeconcernerror.json | 602 ----------- .../commit-writeconcernerror.yml | 216 ---- .../transactions-convenient-api/commit.json | 286 ----- .../transactions-convenient-api/commit.yml | 193 ---- .../transaction-options.json | 577 ---------- .../transaction-options.yml | 274 ----- .../unified/callback-aborts.json | 344 ++++++ .../unified/callback-aborts.yml | 178 ++++ .../unified/callback-commits.json | 423 ++++++++ .../unified/callback-commits.yml | 209 ++++ .../unified/callback-retry.json | 467 ++++++++ .../unified/callback-retry.yml | 245 +++++ .../unified/commit-retry-errorLabels.json | 231 ++++ .../unified/commit-retry-errorLabels.yml | 118 +++ .../unified/commit-retry.json | 542 ++++++++++ .../unified/commit-retry.yml | 271 +++++ .../commit-transienttransactionerror-4.2.json | 293 ++++++ .../commit-transienttransactionerror-4.2.yml | 156 +++ .../commit-transienttransactionerror.json | 995 ++++++++++++++++++ .../commit-transienttransactionerror.yml | 209 ++++ .../unified/commit-writeconcernerror.json | 814 ++++++++++++++ .../unified/commit-writeconcernerror.yml | 250 +++++ .../unified/commit.json | 398 +++++++ .../unified/commit.yml | 199 ++++ .../unified/transaction-options.json | 819 ++++++++++++++ .../unified/transaction-options.yml | 379 +++++++ test/tools/unified-spec-runner/match.ts | 1 + test/tools/unified-spec-runner/operations.ts | 9 +- 45 files changed, 7569 insertions(+), 6003 deletions(-) delete mode 100644 test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.js create mode 100644 test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.ts delete mode 100644 test/spec/transactions-convenient-api/README.rst delete mode 100644 test/spec/transactions-convenient-api/callback-aborts.json delete mode 100644 test/spec/transactions-convenient-api/callback-aborts.yml delete mode 100644 test/spec/transactions-convenient-api/callback-commits.json delete mode 100644 test/spec/transactions-convenient-api/callback-commits.yml delete mode 100644 test/spec/transactions-convenient-api/callback-retry.json delete mode 100644 test/spec/transactions-convenient-api/callback-retry.yml delete mode 100644 test/spec/transactions-convenient-api/commit-retry.json delete mode 100644 test/spec/transactions-convenient-api/commit-retry.yml delete mode 100644 test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.json delete mode 100644 test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.yml delete mode 100644 test/spec/transactions-convenient-api/commit-transienttransactionerror.json delete mode 100644 test/spec/transactions-convenient-api/commit-transienttransactionerror.yml delete mode 100644 test/spec/transactions-convenient-api/commit-writeconcernerror.json delete mode 100644 test/spec/transactions-convenient-api/commit-writeconcernerror.yml delete mode 100644 test/spec/transactions-convenient-api/commit.json delete mode 100644 test/spec/transactions-convenient-api/commit.yml delete mode 100644 test/spec/transactions-convenient-api/transaction-options.json delete mode 100644 test/spec/transactions-convenient-api/transaction-options.yml create mode 100644 test/spec/transactions-convenient-api/unified/callback-aborts.json create mode 100644 test/spec/transactions-convenient-api/unified/callback-aborts.yml create mode 100644 test/spec/transactions-convenient-api/unified/callback-commits.json create mode 100644 test/spec/transactions-convenient-api/unified/callback-commits.yml create mode 100644 test/spec/transactions-convenient-api/unified/callback-retry.json create mode 100644 test/spec/transactions-convenient-api/unified/callback-retry.yml create mode 100644 test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.json create mode 100644 test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.yml create mode 100644 test/spec/transactions-convenient-api/unified/commit-retry.json create mode 100644 test/spec/transactions-convenient-api/unified/commit-retry.yml create mode 100644 test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.json create mode 100644 test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.yml create mode 100644 test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.json create mode 100644 test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.yml create mode 100644 test/spec/transactions-convenient-api/unified/commit-writeconcernerror.json create mode 100644 test/spec/transactions-convenient-api/unified/commit-writeconcernerror.yml create mode 100644 test/spec/transactions-convenient-api/unified/commit.json create mode 100644 test/spec/transactions-convenient-api/unified/commit.yml create mode 100644 test/spec/transactions-convenient-api/unified/transaction-options.json create mode 100644 test/spec/transactions-convenient-api/unified/transaction-options.yml diff --git a/src/sessions.ts b/src/sessions.ts index e04c802b3cc..57a94ffa4d9 100644 --- a/src/sessions.ts +++ b/src/sessions.ts @@ -589,6 +589,7 @@ function attemptTransaction( try { promise = fn(session); } catch (err) { + console.log('1', err); promise = Promise.reject(err); } @@ -608,6 +609,7 @@ function attemptTransaction( return attemptTransactionCommit(session, startTime, fn, result, options); }, err => { + console.log('2', err); function maybeRetryOrThrow(err: MongoError): Promise { if ( err instanceof MongoError && diff --git a/test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.js b/test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.js deleted file mode 100644 index fa99f693ab6..00000000000 --- a/test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.js +++ /dev/null @@ -1,89 +0,0 @@ -'use strict'; - -const { expect } = require('chai'); -const { TestRunnerContext, generateTopologyTests } = require('../../tools/spec-runner'); -const { loadSpecTests } = require('../../spec'); - -function ignoreNsNotFoundForListIndexes(err) { - if (err.code !== 26) { - throw err; - } - - return []; -} - -class TransactionsRunnerContext extends TestRunnerContext { - assertCollectionExists(options) { - const client = this.sharedClient; - const db = client.db(options.database); - const collectionName = options.collection; - - return db - .listCollections() - .toArray() - .then(collections => expect(collections.some(coll => coll.name === collectionName)).to.be.ok); - } - - assertCollectionNotExists(options) { - const client = this.sharedClient; - const db = client.db(options.database); - const collectionName = options.collection; - - return db - .listCollections() - .toArray() - .then( - collections => expect(collections.every(coll => coll.name !== collectionName)).to.be.ok - ); - } - - assertIndexExists(options) { - const client = this.sharedClient; - const collection = client.db(options.database).collection(options.collection); - const indexName = options.index; - - return collection - .listIndexes() - .toArray() - .catch(ignoreNsNotFoundForListIndexes) - .then(indexes => expect(indexes.some(idx => idx.name === indexName)).to.be.ok); - } - - assertIndexNotExists(options) { - const client = this.sharedClient; - const collection = client.db(options.database).collection(options.collection); - const indexName = options.index; - - return collection - .listIndexes() - .toArray() - .catch(ignoreNsNotFoundForListIndexes) - .then(indexes => expect(indexes.every(idx => idx.name !== indexName)).to.be.ok); - } - - assertSessionPinned(options) { - expect(options).to.have.property('session'); - - const session = options.session; - expect(session.isPinned).to.be.true; - } - - assertSessionUnpinned(options) { - expect(options).to.have.property('session'); - - const session = options.session; - expect(session.isPinned).to.be.false; - } -} - -describe('Transactions Convenient API Spec Legacy Tests', function () { - const testContext = new TransactionsRunnerContext(); - const testSuites = loadSpecTests('transactions-convenient-api'); - - after(() => testContext.teardown()); - before(function () { - return testContext.setup(this.configuration); - }); - - generateTopologyTests(testSuites, testContext); -}); diff --git a/test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.ts b/test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.ts new file mode 100644 index 00000000000..e3ece312601 --- /dev/null +++ b/test/integration/transactions-convenient-api/transactions-convenient-api.spec.test.ts @@ -0,0 +1,18 @@ +import * as path from 'path'; + +import { loadSpecTests } from '../../spec'; +import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner'; + +const SKIPPED_TESTS = [ + 'callback succeeds after multiple connection errors', + 'callback is not retried after non-transient error', + 'callback is not retried after non-transient error (DuplicateKeyError)' +]; + +describe('Transactions Convenient API Spec Unified Tests', function () { + runUnifiedSuite(loadSpecTests(path.join('transactions-convenient-api', 'unified')), test => { + return SKIPPED_TESTS.includes(test.description) + ? 'TODO(NODE-): Skipping failing transaction tests' + : false; + }); +}); diff --git a/test/integration/unified-test-format/unified_test_format.spec.test.ts b/test/integration/unified-test-format/unified_test_format.spec.test.ts index 786b4c70ede..9c54798b4c0 100644 --- a/test/integration/unified-test-format/unified_test_format.spec.test.ts +++ b/test/integration/unified-test-format/unified_test_format.spec.test.ts @@ -37,7 +37,7 @@ const filter: TestFilter = ({ description }) => { return false; }; -describe('Unified test format runner', function unifiedTestRunner() { +describe.only('Unified test format runner', function unifiedTestRunner() { // Valid tests that should pass runUnifiedSuite(loadSpecTests('unified-test-format/valid-pass'), filter); }); diff --git a/test/spec/transactions-convenient-api/README.rst b/test/spec/transactions-convenient-api/README.rst deleted file mode 100644 index eabf244a6e3..00000000000 --- a/test/spec/transactions-convenient-api/README.rst +++ /dev/null @@ -1,220 +0,0 @@ -===================================== -Convenient API for Transactions Tests -===================================== - -.. contents:: - ----- - -Introduction -============ - -The YAML and JSON files in this directory are platform-independent tests that -drivers can use to prove their conformance to the Convenient API for -Transactions spec. They are designed with the intention of sharing some -test-runner code with the CRUD, Command Monitoring, and Transaction spec tests. - -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. - -Server Fail Point -================= - -See: `Server Fail Point <../../transactions/tests#server-fail-point>`_ in the -Transactions spec test suite. - -Test Format -=========== - -Each YAML file has the following keys: - -- ``runOn`` (optional): An array of server version and/or topology requirements - for which the tests can be run. If the test environment satisfies one or more - of these requirements, the tests may be executed; otherwise, this file should - be skipped. If this field is omitted, the tests can be assumed to have no - particular requirements and should be executed. Each element will have some or - all of the following fields: - - - ``minServerVersion`` (optional): The minimum server version (inclusive) - required to successfully run the tests. If this field is omitted, it should - be assumed that there is no lower bound on the required server version. - - - ``maxServerVersion`` (optional): The maximum server version (inclusive) - against which the tests can be run successfully. If this field is omitted, - it should be assumed that there is no upper bound on the required server - 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"]``). - -- ``database_name`` and ``collection_name``: The database and collection to use - for testing. - -- ``data``: The data that should exist in the collection under test before each - test run. - -- ``tests``: An array of tests that are to be run independently of each other. - Each test will have some or all of the following fields: - - - ``description``: The name of the test. - - - ``skipReason`` (optional): If present, the test should be skipped and the - string value will specify a reason. - - - ``failPoint`` (optional): The ``configureFailPoint`` command document to run - to configure a fail point on the primary server. This option and - ``useMultipleMongoses: true`` are mutually exclusive. - - - ``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. - - - ``clientOptions`` (optional): Names and values of options to pass to - ``MongoClient()``. - - - ``sessionOptions`` (optional): Names and values of options to pass to - ``MongoClient.startSession()``. - - - ``operations``: Array of documents, each describing an operation to be - executed. Each document has the following fields: - - - ``name``: The name of the operation on ``object``. - - - ``object``: The name of the object on which to perform the operation. The - value will be either "collection" or "session0". - - - ``arguments`` (optional): Names and values of arguments to pass to the - operation. - - - ``result`` (optional): The return value from the operation. This will - correspond to an operation's result object as defined in the CRUD - specification. If the operation is expected to return an error, the - ``result`` is a single document that has one or more of the following - fields: - - - ``errorContains``: A substring of the expected error message. - - - ``errorCodeName``: The expected "codeName" field in the server - error response. - - - ``errorLabelsContain``: A list of error label strings that the - error is expected to have. - - - ``errorLabelsOmit``: A list of error label strings that the - error is expected not to have. - - - ``expectations`` (optional): List of command-started events. - - - ``outcome``: Document describing the return value and/or expected state of - the collection after the operation is executed. Contains the following - fields: - - - ``collection``: - - - ``data``: The data that should exist in the collection after the - operations have run. - -``withTransaction`` Operation -````````````````````````````` - -These tests introduce a ``withTransaction`` operation, which may have the -following fields: - -- ``callback``: Document containing the following field: - - - ``operations``: Array of documents, each describing an operation to be - executed. Elements in this array will follow the same structure as the - ``operations`` field defined above (and in the CRUD and Transactions specs). - - Note that drivers are expected to evaluate ``error`` and ``result`` - assertions when executing operations within ``callback.operations``. - -- ``options`` (optional): Names and values of options to pass to - ``withTransaction()``, which will in turn be used for ``startTransaction()``. - -Use as Integration Tests -======================== - -Testing against a replica set will require server version 4.0.0 or later. The -replica set should include a primary, a secondary, and an arbiter. Including a -secondary ensures that server selection in a transaction works properly. -Including an arbiter helps ensure that no new bugs have been introduced related -to arbiters. - -Testing against a sharded cluster will require server version 4.1.6 or later. -A driver that implements support for sharded transactions MUST also run these -tests against a MongoDB sharded cluster with multiple mongoses. Including -multiple mongoses (and initializing the MongoClient with multiple mongos seeds!) -ensures that mongos transaction pinning works properly. - -See: `Use as Integration Tests <../../transactions/tests#use-as-integration-tests>`_ -in the Transactions spec test suite for instructions on executing each test. - -Take note of the following: - -- Most tests will consist of a single "withTransaction" operation to be invoked - on the "session0" object. The ``callback`` argument of that operation will - resemble the ``operations`` array found in transaction spec tests. - -Command-Started Events -`````````````````````` - -See: `Command-Started Events <../../transactions/tests#command-started-events>`_ -in the Transactions spec test suite for instructions on asserting -command-started events. - -Prose Tests -=========== - -Callback Raises a Custom Error -`````````````````````````````` - -Write a callback that raises a custom exception or error that does not include -either UnknownTransactionCommitResult or TransientTransactionError error labels. -Execute this callback using ``withTransaction`` and assert that the callback's -error bypasses any retry logic within ``withTransaction`` and is propagated to -the caller of ``withTransaction``. - -Callback Returns a Value -```````````````````````` - -Write a callback that returns a custom value (e.g. boolean, string, object). -Execute this callback using ``withTransaction`` and assert that the callback's -return value is propagated to the caller of ``withTransaction``. - -Retry Timeout is Enforced -````````````````````````` - -Drivers should test that ``withTransaction`` enforces a non-configurable timeout -before retrying both commits and entire transactions. Specifically, three cases -should be checked: - - * If the callback raises an error with the TransientTransactionError label and - the retry timeout has been exceeded, ``withTransaction`` should propagate the - error to its caller. - * If committing raises an error with the UnknownTransactionCommitResult label, - the error is not a write concern timeout, and the retry timeout has been - exceeded, ``withTransaction`` should propagate the error to its caller. - * If committing raises an error with the TransientTransactionError label and - the retry timeout has been exceeded, ``withTransaction`` should propagate the - error to its caller. This case may occur if the commit was internally retried - against a new primary after a failover and the second primary returned a - NoSuchTransaction error response. - - If possible, drivers should implement these tests without requiring the test - runner to block for the full duration of the retry timeout. This might be done - by internally modifying the timeout value used by ``withTransaction`` with some - private API or using a mock timer. - -Changelog -========= - -:2019-03-01: Add top-level ``runOn`` field to denote server version and/or - topology requirements requirements for the test file. Removes the - ``minServerVersion`` top-level field, which is now expressed within - ``runOn`` elements. - - Add test-level ``useMultipleMongoses`` field. diff --git a/test/spec/transactions-convenient-api/callback-aborts.json b/test/spec/transactions-convenient-api/callback-aborts.json deleted file mode 100644 index 2a3038e8baa..00000000000 --- a/test/spec/transactions-convenient-api/callback-aborts.json +++ /dev/null @@ -1,244 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction succeeds if callback aborts", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "withTransaction succeeds if callback aborts with no ops", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "abortTransaction", - "object": "session0" - } - ] - } - } - } - ], - "expectations": [], - "outcome": { - "collection": { - "data": [] - } - } - }, - { - "description": "withTransaction still succeeds if callback aborts and runs extra op", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "abortTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "autocommit": null, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/callback-aborts.yml b/test/spec/transactions-convenient-api/callback-aborts.yml deleted file mode 100644 index fcb4f391630..00000000000 --- a/test/spec/transactions-convenient-api/callback-aborts.yml +++ /dev/null @@ -1,170 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - # Session state will be ABORTED when callback returns to withTransaction - description: withTransaction succeeds if callback aborts - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: abortTransaction - object: session0 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - abortTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: abortTransaction - database_name: admin - outcome: - collection: - data: [] - - - # Session state will be ABORTED when callback returns to withTransaction - description: withTransaction succeeds if callback aborts with no ops - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: abortTransaction - object: session0 - expectations: [] - outcome: - collection: - data: [] - - - # Session state will be NO_TXN when callback returns to withTransaction - description: withTransaction still succeeds if callback aborts and runs extra op - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: abortTransaction - object: session0 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 2 } - result: - insertedId: 2 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - abortTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: abortTransaction - database_name: admin - - - command_started_event: - command: - # This test is agnostic about retryWrites, so we do not assert the - # txnNumber. If retryWrites=true, the txnNumber will be incremented - # from the value used in the previous transaction; otherwise, the - # field will not be present at all. - insert: *collection_name - documents: - - { _id: 2 } - ordered: true - lsid: session0 - # omitted fields - autocommit: ~ - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - outcome: - collection: - data: - - { _id: 2 } diff --git a/test/spec/transactions-convenient-api/callback-commits.json b/test/spec/transactions-convenient-api/callback-commits.json deleted file mode 100644 index 4abbbdd0e63..00000000000 --- a/test/spec/transactions-convenient-api/callback-commits.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction succeeds if callback commits", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0" - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "withTransaction still succeeds if callback commits and runs extra op", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 3 - } - }, - "result": { - "insertedId": 3 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 3 - } - ], - "ordered": true, - "lsid": "session0", - "autocommit": null, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - }, - { - "_id": 3 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/callback-commits.yml b/test/spec/transactions-convenient-api/callback-commits.yml deleted file mode 100644 index 6eb6bc6fccc..00000000000 --- a/test/spec/transactions-convenient-api/callback-commits.yml +++ /dev/null @@ -1,204 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - # Session state will be COMMITTED when callback returns to withTransaction - description: withTransaction succeeds if callback commits - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 2 } - result: - insertedId: 2 - - - name: commitTransaction - object: session0 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 2 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - { _id: 2 } - - - # Session state will be NO_TXN when callback returns to withTransaction - description: withTransaction still succeeds if callback commits and runs extra op - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 2 } - result: - insertedId: 2 - - - name: commitTransaction - object: session0 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 3 } - result: - insertedId: 3 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 2 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - # This test is agnostic about retryWrites, so we do not assert the - # txnNumber. If retryWrites=true, the txnNumber will be incremented - # from the value used in the previous transaction; otherwise, the - # field will not be present at all. - insert: *collection_name - documents: - - { _id: 3 } - ordered: true - lsid: session0 - # omitted fields - autocommit: ~ - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - outcome: - collection: - data: - - { _id: 1 } - - { _id: 2 } - - { _id: 3 } diff --git a/test/spec/transactions-convenient-api/callback-retry.json b/test/spec/transactions-convenient-api/callback-retry.json deleted file mode 100644 index a0391c1b5d0..00000000000 --- a/test/spec/transactions-convenient-api/callback-retry.json +++ /dev/null @@ -1,315 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "callback succeeds after multiple connection errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "insert" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "callback is not retried after non-transient error (DuplicateKeyError)", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ] - } - }, - "result": { - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ], - "errorContains": "E11000" - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "abortTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "abortTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/callback-retry.yml b/test/spec/transactions-convenient-api/callback-retry.yml deleted file mode 100644 index edff016bdb9..00000000000 --- a/test/spec/transactions-convenient-api/callback-retry.yml +++ /dev/null @@ -1,215 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - description: callback succeeds after multiple connection errors - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["insert"] - closeConnection: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - # We do not assert the result here, as insertOne will fail for - # the first two executions of the callback before ultimately - # succeeding and returning a result. Asserting the state of the - # output collection after the test is sufficient. - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - abortTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: abortTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - # second transaction will be causally consistent with the first - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented when retrying the transaction - txnNumber: { $numberLong: "2" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - abortTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "2" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: abortTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - # third transaction will be causally consistent with the second - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented when retrying the transaction - txnNumber: { $numberLong: "3" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "3" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - - description: callback is not retried after non-transient error (DuplicateKeyError) - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] - result: - errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] - # DuplicateKey error code included in the bulk write error message - # returned by the server - errorContains: E11000 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - abortTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: abortTransaction - database_name: admin - outcome: - collection: - data: [] diff --git a/test/spec/transactions-convenient-api/commit-retry.json b/test/spec/transactions-convenient-api/commit-retry.json deleted file mode 100644 index 02e38460d05..00000000000 --- a/test/spec/transactions-convenient-api/commit-retry.json +++ /dev/null @@ -1,531 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commitTransaction succeeds after multiple connection errors", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction retry only overwrites write concern w option", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "closeConnection": true - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "writeConcern": { - "w": 2, - "j": true, - "wtimeout": 5000 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 2, - "j": true, - "wtimeout": 5000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "j": true, - "wtimeout": 5000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "j": true, - "wtimeout": 5000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commit is retried after commitTransaction UnknownTransactionCommitResult (NotWritablePrimary)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 10107, - "errorLabels": [ - "RetryableWriteError" - ], - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commit is not retried after MaxTimeMSExpired error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 50 - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "maxCommitTimeMS": 60000 - } - }, - "result": { - "errorCodeName": "MaxTimeMSExpired", - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "maxTimeMS": 60000, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/commit-retry.yml b/test/spec/transactions-convenient-api/commit-retry.yml deleted file mode 100644 index 74c03dd9fbd..00000000000 --- a/test/spec/transactions-convenient-api/commit-retry.yml +++ /dev/null @@ -1,325 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - description: commitTransaction succeeds after multiple connection errors - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - closeConnection: true - operations: - - &withTransaction - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, wtimeout: 10000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, wtimeout: 10000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - - description: commitTransaction retry only overwrites write concern w option - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - closeConnection: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - options: - writeConcern: { w: 2, j: true, wtimeout: 5000 } - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - writeConcern: { w: 2, j: true, wtimeout: 5000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, j: true, wtimeout: 5000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, j: true, wtimeout: 5000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - - description: commit is retried after commitTransaction UnknownTransactionCommitResult (NotWritablePrimary) - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - errorCode: 10107 # NotWritablePrimary - errorLabels: ["RetryableWriteError"] # SPEC-1565 - closeConnection: false - operations: - - *withTransaction - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, wtimeout: 10000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, wtimeout: 10000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - - description: commit is not retried after MaxTimeMSExpired error - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["commitTransaction"] - errorCode: 50 # MaxTimeMSExpired - operations: - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - options: - maxCommitTimeMS: 60000 - result: - errorCodeName: MaxTimeMSExpired - errorLabelsContain: ["UnknownTransactionCommitResult"] - errorLabelsOmit: ["TransientTransactionError"] - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - maxTimeMS: 60000 - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - # In reality, the outcome of the commit is unknown but we fabricate - # the error with failCommand.errorCode which does not apply the commit - # operation. - data: [] diff --git a/test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.json b/test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.json deleted file mode 100644 index 7663bb54e18..00000000000 --- a/test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.1.6", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "transaction is retried after commitTransaction TransientTransactionError (PreparedTransactionInProgress)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 267, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.yml b/test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.yml deleted file mode 100644 index 10f51d079bb..00000000000 --- a/test/spec/transactions-convenient-api/commit-transienttransactionerror-4.2.yml +++ /dev/null @@ -1,139 +0,0 @@ -runOn: - - - minServerVersion: "4.1.6" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -# These tests use error codes where the TransientTransactionError label will be -# applied to the error response for commitTransaction. This will cause the -# entire transaction to be retried instead of commitTransaction. -# -# See: https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/db/handle_request_response.cpp -tests: - - - description: transaction is retried after commitTransaction TransientTransactionError (PreparedTransactionInProgress) - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - errorCode: 267 # PreparedTransactionInProgress - closeConnection: false - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - # second transaction will be causally consistent with the first - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented when retrying the transaction - txnNumber: { $numberLong: "2" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "2" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - # third transaction will be causally consistent with the second - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented when retrying the transaction - txnNumber: { $numberLong: "3" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "3" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } diff --git a/test/spec/transactions-convenient-api/commit-transienttransactionerror.json b/test/spec/transactions-convenient-api/commit-transienttransactionerror.json deleted file mode 100644 index 18becbe09c6..00000000000 --- a/test/spec/transactions-convenient-api/commit-transienttransactionerror.json +++ /dev/null @@ -1,725 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "transaction is retried after commitTransaction TransientTransactionError (LockTimeout)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 24, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction is retried after commitTransaction TransientTransactionError (WriteConflict)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 112, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction is retried after commitTransaction TransientTransactionError (SnapshotUnavailable)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 246, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "transaction is retried after commitTransaction TransientTransactionError (NoSuchTransaction)", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "errorCode": 251, - "closeConnection": false - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "3" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "3" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/commit-transienttransactionerror.yml b/test/spec/transactions-convenient-api/commit-transienttransactionerror.yml deleted file mode 100644 index db1f64ae542..00000000000 --- a/test/spec/transactions-convenient-api/commit-transienttransactionerror.yml +++ /dev/null @@ -1,175 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -# These tests use error codes where the TransientTransactionError label will be -# applied to the error response for commitTransaction. This will cause the -# entire transaction to be retried instead of commitTransaction. -# -# See: https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/db/handle_request_response.cpp -tests: - - - description: transaction is retried after commitTransaction TransientTransactionError (LockTimeout) - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - errorCode: 24 # LockTimeout - closeConnection: false - operations: &operations - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - expectations: &expectations - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - # second transaction will be causally consistent with the first - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented when retrying the transaction - txnNumber: { $numberLong: "2" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "2" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - # third transaction will be causally consistent with the second - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented when retrying the transaction - txnNumber: { $numberLong: "3" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "3" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: &outcome - collection: - data: - - { _id: 1 } - - - description: transaction is retried after commitTransaction TransientTransactionError (WriteConflict) - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - errorCode: 112 # WriteConflict - closeConnection: false - operations: *operations - expectations: *expectations - outcome: *outcome - - - description: transaction is retried after commitTransaction TransientTransactionError (SnapshotUnavailable) - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - errorCode: 246 # SnapshotUnavailable - closeConnection: false - operations: *operations - expectations: *expectations - outcome: *outcome - - - description: transaction is retried after commitTransaction TransientTransactionError (NoSuchTransaction) - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - errorCode: 251 # NoSuchTransaction - closeConnection: false - operations: *operations - expectations: *expectations - outcome: *outcome diff --git a/test/spec/transactions-convenient-api/commit-writeconcernerror.json b/test/spec/transactions-convenient-api/commit-writeconcernerror.json deleted file mode 100644 index fbad6455465..00000000000 --- a/test/spec/transactions-convenient-api/commit-writeconcernerror.json +++ /dev/null @@ -1,602 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "commitTransaction is retried after WriteConcernFailed timeout error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 64, - "codeName": "WriteConcernFailed", - "errmsg": "waiting for replication timed out", - "errInfo": { - "wtimeout": true - } - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is retried after WriteConcernFailed non-timeout error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 2 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 64, - "codeName": "WriteConcernFailed", - "errmsg": "multiple errors reported" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": "majority", - "wtimeout": 10000 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is not retried after UnknownReplWriteConcern error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 79, - "codeName": "UnknownReplWriteConcern", - "errmsg": "No write concern mode named 'foo' found in replica set configuration" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - }, - "result": { - "errorCodeName": "UnknownReplWriteConcern", - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is not retried after UnsatisfiableWriteConcern error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 100, - "codeName": "UnsatisfiableWriteConcern", - "errmsg": "Not enough data-bearing nodes" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - }, - "result": { - "errorCodeName": "UnsatisfiableWriteConcern", - "errorLabelsOmit": [ - "TransientTransactionError", - "UnknownTransactionCommitResult" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "commitTransaction is not retried after MaxTimeMSExpired error", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": [ - "commitTransaction" - ], - "writeConcernError": { - "code": 50, - "codeName": "MaxTimeMSExpired", - "errmsg": "operation exceeded time limit" - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - }, - "result": { - "errorCodeName": "MaxTimeMSExpired", - "errorLabelsContain": [ - "UnknownTransactionCommitResult" - ], - "errorLabelsOmit": [ - "TransientTransactionError" - ] - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/commit-writeconcernerror.yml b/test/spec/transactions-convenient-api/commit-writeconcernerror.yml deleted file mode 100644 index 5c5f364d58e..00000000000 --- a/test/spec/transactions-convenient-api/commit-writeconcernerror.yml +++ /dev/null @@ -1,216 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - description: commitTransaction is retried after WriteConcernFailed timeout error - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - # Do not specify closeConnection: false, since that would conflict - # with writeConcernError (see: SERVER-39292) - writeConcernError: - code: 64 - codeName: WriteConcernFailed - errmsg: "waiting for replication timed out" - errInfo: { wtimeout: true } - operations: - - &operation - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - expectations: &expectations_with_retries - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, wtimeout: 10000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # commitTransaction applies w:majority on retries (SPEC-1185) - writeConcern: { w: majority, wtimeout: 10000 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - # The write operation is still applied despite the write concern error - outcome: &outcome - collection: - data: - - { _id: 1 } - - - # This test configures the fail point to return an error with the - # WriteConcernFailed code but without errInfo that would identify it as a - # wtimeout error. This tests that drivers do not assume that all - # WriteConcernFailed errors are due to a replication timeout. - description: commitTransaction is retried after WriteConcernFailed non-timeout error - failPoint: - configureFailPoint: failCommand - mode: { times: 2 } - data: - failCommands: ["commitTransaction"] - # Do not specify closeConnection: false, since that would conflict - # with writeConcernError (see: SERVER-39292) - writeConcernError: - code: 64 - codeName: WriteConcernFailed - errmsg: "multiple errors reported" - operations: - - *operation - expectations: *expectations_with_retries - outcome: *outcome - - - description: commitTransaction is not retried after UnknownReplWriteConcern error - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["commitTransaction"] - writeConcernError: - code: 79 - codeName: UnknownReplWriteConcern - errmsg: "No write concern mode named 'foo' found in replica set configuration" - operations: - - <<: *operation - result: - errorCodeName: UnknownReplWriteConcern - errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] - expectations: &expectations_without_retries - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - # failCommand with writeConcernError still applies the write operation(s) - outcome: *outcome - - - - description: commitTransaction is not retried after UnsatisfiableWriteConcern error - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["commitTransaction"] - writeConcernError: - code: 100 - codeName: UnsatisfiableWriteConcern - errmsg: "Not enough data-bearing nodes" - operations: - - <<: *operation - result: - errorCodeName: UnsatisfiableWriteConcern - errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] - expectations: *expectations_without_retries - # failCommand with writeConcernError still applies the write operation(s) - outcome: *outcome - - - - description: commitTransaction is not retried after MaxTimeMSExpired error - failPoint: - configureFailPoint: failCommand - mode: { times: 1 } - data: - failCommands: ["commitTransaction"] - writeConcernError: - code: 50 - codeName: MaxTimeMSExpired - errmsg: "operation exceeded time limit" - operations: - - <<: *operation - result: - errorCodeName: MaxTimeMSExpired - errorLabelsContain: ["UnknownTransactionCommitResult"] - errorLabelsOmit: ["TransientTransactionError"] - expectations: *expectations_without_retries - # failCommand with writeConcernError still applies the write operation(s) - outcome: *outcome diff --git a/test/spec/transactions-convenient-api/commit.json b/test/spec/transactions-convenient-api/commit.json deleted file mode 100644 index 0a7451db952..00000000000 --- a/test/spec/transactions-convenient-api/commit.json +++ /dev/null @@ -1,286 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction commits after callback returns", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - }, - { - "description": "withTransaction commits after callback returns (second transaction)", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - }, - { - "name": "commitTransaction", - "object": "session0" - }, - { - "name": "startTransaction", - "object": "session0" - }, - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 2 - } - }, - "result": { - "insertedId": 2 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - }, - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 2 - } - ], - "ordered": true, - "lsid": "session0", - "readConcern": { - "afterClusterTime": 42 - }, - "txnNumber": { - "$numberLong": "2" - }, - "startTransaction": true, - "autocommit": false, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "2" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/commit.yml b/test/spec/transactions-convenient-api/commit.yml deleted file mode 100644 index b84a3e8bd0b..00000000000 --- a/test/spec/transactions-convenient-api/commit.yml +++ /dev/null @@ -1,193 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - description: withTransaction commits after callback returns - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 2 } - result: - insertedId: 2 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 2 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - { _id: 2 } - - - # In this scenario, the callback commits the transaction originally started - # by withTransaction and starts a second transaction before returning. Since - # withTransaction only examines the session's state, it should commit that - # second transaction after the callback returns. - description: withTransaction commits after callback returns (second transaction) - useMultipleMongoses: true - operations: - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - - - name: commitTransaction - object: session0 - - - name: startTransaction - object: session0 - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 2 } - result: - insertedId: 2 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 2 } - ordered: true - lsid: session0 - # second transaction will be causally consistent with the first - readConcern: { afterClusterTime: 42 } - # txnNumber is incremented for the second transaction - txnNumber: { $numberLong: "2" } - startTransaction: true - autocommit: false - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "2" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: - collection: - data: - - { _id: 1 } - - { _id: 2 } diff --git a/test/spec/transactions-convenient-api/transaction-options.json b/test/spec/transactions-convenient-api/transaction-options.json deleted file mode 100644 index 6deff43cf45..00000000000 --- a/test/spec/transactions-convenient-api/transaction-options.json +++ /dev/null @@ -1,577 +0,0 @@ -{ - "runOn": [ - { - "minServerVersion": "4.0", - "topology": [ - "replicaset" - ] - }, - { - "minServerVersion": "4.1.8", - "topology": [ - "sharded" - ] - } - ], - "database_name": "withTransaction-tests", - "collection_name": "test", - "data": [], - "tests": [ - { - "description": "withTransaction and no transaction options set", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": null, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "readConcern": null, - "startTransaction": null, - "writeConcern": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction inherits transaction options from client", - "useMultipleMongoses": true, - "clientOptions": { - "readConcernLevel": "local", - "w": 1 - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "local" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction inherits transaction options from defaultTransactionOptions", - "useMultipleMongoses": true, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "majority" - }, - "writeConcern": { - "w": 1 - } - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "majority" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction explicit transaction options", - "useMultipleMongoses": true, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "readConcern": { - "level": "majority" - }, - "writeConcern": { - "w": 1 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "majority" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction explicit transaction options override defaultTransactionOptions", - "useMultipleMongoses": true, - "sessionOptions": { - "session0": { - "defaultTransactionOptions": { - "readConcern": { - "level": "snapshot" - }, - "writeConcern": { - "w": "majority" - } - } - } - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "readConcern": { - "level": "majority" - }, - "writeConcern": { - "w": 1 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "majority" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - }, - { - "description": "withTransaction explicit transaction options override client options", - "useMultipleMongoses": true, - "clientOptions": { - "readConcernLevel": "local", - "w": "majority" - }, - "operations": [ - { - "name": "withTransaction", - "object": "session0", - "arguments": { - "callback": { - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "session": "session0", - "document": { - "_id": 1 - } - }, - "result": { - "insertedId": 1 - } - } - ] - }, - "options": { - "readConcern": { - "level": "majority" - }, - "writeConcern": { - "w": 1 - } - } - } - } - ], - "expectations": [ - { - "command_started_event": { - "command": { - "insert": "test", - "documents": [ - { - "_id": 1 - } - ], - "ordered": true, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "startTransaction": true, - "autocommit": false, - "readConcern": { - "level": "majority" - }, - "writeConcern": null - }, - "command_name": "insert", - "database_name": "withTransaction-tests" - } - }, - { - "command_started_event": { - "command": { - "commitTransaction": 1, - "lsid": "session0", - "txnNumber": { - "$numberLong": "1" - }, - "autocommit": false, - "writeConcern": { - "w": 1 - }, - "readConcern": null, - "startTransaction": null - }, - "command_name": "commitTransaction", - "database_name": "admin" - } - } - ], - "outcome": { - "collection": { - "data": [ - { - "_id": 1 - } - ] - } - } - } - ] -} diff --git a/test/spec/transactions-convenient-api/transaction-options.yml b/test/spec/transactions-convenient-api/transaction-options.yml deleted file mode 100644 index 15bdc65bfa9..00000000000 --- a/test/spec/transactions-convenient-api/transaction-options.yml +++ /dev/null @@ -1,274 +0,0 @@ -runOn: - - - minServerVersion: "4.0" - topology: ["replicaset"] - - - minServerVersion: "4.1.8" - topology: ["sharded"] - -database_name: &database_name "withTransaction-tests" -collection_name: &collection_name "test" - -data: [] - -tests: - - - description: withTransaction and no transaction options set - useMultipleMongoses: true - operations: &operations - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - # omitted fields - readConcern: ~ - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - # omitted fields - readConcern: ~ - startTransaction: ~ - writeConcern: ~ - command_name: commitTransaction - database_name: admin - outcome: &outcome - collection: - data: - - { _id: 1 } - - - description: withTransaction inherits transaction options from client - useMultipleMongoses: true - clientOptions: - readConcernLevel: local - w: 1 - operations: *operations - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - readConcern: { level: local } - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - writeConcern: { w: 1 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: *outcome - - - description: withTransaction inherits transaction options from defaultTransactionOptions - useMultipleMongoses: true - sessionOptions: - session0: - defaultTransactionOptions: - readConcern: { level: majority } - writeConcern: { w: 1 } - operations: *operations - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - readConcern: { level: majority } - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - writeConcern: { w: 1 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: *outcome - - - description: withTransaction explicit transaction options - useMultipleMongoses: true - operations: &operations_explicit_transactionOptions - - - name: withTransaction - object: session0 - arguments: - callback: - operations: - - - name: insertOne - object: collection - arguments: - session: session0 - document: { _id: 1 } - result: - insertedId: 1 - options: - readConcern: { level: majority } - writeConcern: { w: 1 } - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - readConcern: { level: majority } - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - writeConcern: { w: 1 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: *outcome - - - description: withTransaction explicit transaction options override defaultTransactionOptions - useMultipleMongoses: true - sessionOptions: - session0: - defaultTransactionOptions: - readConcern: { level: snapshot } - writeConcern: { w: majority } - operations: *operations_explicit_transactionOptions - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - readConcern: { level: majority } - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - writeConcern: { w: 1 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: *outcome - - - description: withTransaction explicit transaction options override client options - useMultipleMongoses: true - clientOptions: - readConcernLevel: local - w: majority - operations: *operations_explicit_transactionOptions - expectations: - - - command_started_event: - command: - insert: *collection_name - documents: - - { _id: 1 } - ordered: true - lsid: session0 - txnNumber: { $numberLong: "1" } - startTransaction: true - autocommit: false - readConcern: { level: majority } - # omitted fields - writeConcern: ~ - command_name: insert - database_name: *database_name - - - command_started_event: - command: - commitTransaction: 1 - lsid: session0 - txnNumber: { $numberLong: "1" } - autocommit: false - writeConcern: { w: 1 } - # omitted fields - readConcern: ~ - startTransaction: ~ - command_name: commitTransaction - database_name: admin - outcome: *outcome diff --git a/test/spec/transactions-convenient-api/unified/callback-aborts.json b/test/spec/transactions-convenient-api/unified/callback-aborts.json new file mode 100644 index 00000000000..206428715cd --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/callback-aborts.json @@ -0,0 +1,344 @@ +{ + "description": "callback-aborts", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": true, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "withTransaction succeeds if callback aborts", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "abortTransaction", + "object": "session0" + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "abortTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "abortTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ] + }, + { + "description": "withTransaction succeeds if callback aborts with no ops", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "abortTransaction", + "object": "session0" + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ] + }, + { + "description": "withTransaction still succeeds if callback aborts and runs extra op", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "abortTransaction", + "object": "session0" + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 2 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "abortTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "abortTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "autocommit": { + "$$exists": false + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 2 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/callback-aborts.yml b/test/spec/transactions-convenient-api/unified/callback-aborts.yml new file mode 100644 index 00000000000..9414040eca0 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/callback-aborts.yml @@ -0,0 +1,178 @@ +description: callback-aborts + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: true + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + # Session state will be ABORTED when callback returns to withTransaction + description: withTransaction succeeds if callback aborts + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: abortTransaction + object: *session0 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + abortTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: abortTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + - + # Session state will be ABORTED when callback returns to withTransaction + description: withTransaction succeeds if callback aborts with no ops + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: abortTransaction + object: *session0 + expectEvents: + - client: *client0 + events: [] + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + - + # Session state will be NO_TXN when callback returns to withTransaction + description: withTransaction still succeeds if callback aborts and runs extra op + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: abortTransaction + object: *session0 + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 2 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 2 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + abortTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: abortTransaction + databaseName: admin + - commandStartedEvent: + command: + # This test is agnostic about retryWrites, so we do not assert the + # txnNumber. If retryWrites=true, the txnNumber will be incremented + # from the value used in the previous transaction; otherwise, the + # field will not be present at all. + insert: *collectionName + documents: + - { _id: 2 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # omitted fields + autocommit: { $$exists: false } + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 2 } diff --git a/test/spec/transactions-convenient-api/unified/callback-commits.json b/test/spec/transactions-convenient-api/unified/callback-commits.json new file mode 100644 index 00000000000..06f791e9ae6 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/callback-commits.json @@ -0,0 +1,423 @@ +{ + "description": "callback-commits", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": true, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "withTransaction succeeds if callback commits", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 2 + } + } + } + }, + { + "name": "commitTransaction", + "object": "session0" + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ] + }, + { + "description": "withTransaction still succeeds if callback commits and runs extra op", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 2 + } + } + } + }, + { + "name": "commitTransaction", + "object": "session0" + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 3 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 3 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 3 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "autocommit": { + "$$exists": false + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/callback-commits.yml b/test/spec/transactions-convenient-api/unified/callback-commits.yml new file mode 100644 index 00000000000..b5cbb041519 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/callback-commits.yml @@ -0,0 +1,209 @@ +description: callback-commits + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: true + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + # Session state will be COMMITTED when callback returns to withTransaction + description: withTransaction succeeds if callback commits + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 2 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 2 } } + - name: commitTransaction + object: *session0 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 2 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - { _id: 2 } + - + # Session state will be NO_TXN when callback returns to withTransaction + description: withTransaction still succeeds if callback commits and runs extra op + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 2 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 2 } } + - name: commitTransaction + object: *session0 + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 3 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 3 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 2 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + # This test is agnostic about retryWrites, so we do not assert the + # txnNumber. If retryWrites=true, the txnNumber will be incremented + # from the value used in the previous transaction; otherwise, the + # field will not be present at all. + insert: *collectionName + documents: + - { _id: 3 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # omitted fields + autocommit: { $$exists: false } + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - { _id: 2 } + - { _id: 3 } diff --git a/test/spec/transactions-convenient-api/unified/callback-retry.json b/test/spec/transactions-convenient-api/unified/callback-retry.json new file mode 100644 index 00000000000..a2b267c3622 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/callback-retry.json @@ -0,0 +1,467 @@ +{ + "description": "callback-retry", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + }, + { + "client": { + "id": "client1", + "useMultipleMongoses": true, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database1", + "client": "client1", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection1", + "database": "database1", + "collectionName": "test" + } + }, + { + "session": { + "id": "session1", + "client": "client1" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "callback succeeds after multiple connection errors", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "insert" + ], + "closeConnection": true + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "ignoreResultAndError": true + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "abortTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "abortTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "abortTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "abortTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "3" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "3" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "callback is not retried after non-transient error (DuplicateKeyError)", + "operations": [ + { + "name": "withTransaction", + "object": "session1", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection1", + "arguments": { + "session": "session1", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "insertOne", + "object": "collection1", + "arguments": { + "session": "session1", + "document": { + "_id": 1 + } + }, + "expectError": { + "errorLabelsOmit": [ + "TransientTransactionError", + "UnknownTransactionCommitResult" + ] + } + } + ] + }, + "expectError": { + "errorLabelsOmit": [ + "TransientTransactionError", + "UnknownTransactionCommitResult" + ], + "errorContains": "E11000" + } + } + ], + "expectEvents": [ + { + "client": "client1", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "abortTransaction": 1, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "abortTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/callback-retry.yml b/test/spec/transactions-convenient-api/unified/callback-retry.yml new file mode 100644 index 00000000000..2c6f3463a8f --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/callback-retry.yml @@ -0,0 +1,245 @@ +description: callback-retry + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + # Define a second set of entities for useMultipleMongoses:true + - client: + id: &client1 client1 + useMultipleMongoses: true + observeEvents: [ commandStartedEvent ] + - database: + id: &database1 database1 + client: *client1 + databaseName: *databaseName + - collection: + id: &collection1 collection1 + database: *database1 + collectionName: *collectionName + - session: + id: &session1 session1 + client: *client1 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + description: callback succeeds after multiple connection errors + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ insert ] + closeConnection: true + - name: withTransaction + object: *session0 + arguments: + callback: + - + # We do not assert the result here, as insertOne will fail for + # the first two executions of the callback before ultimately + # succeeding and returning a result. Asserting the state of the + # output collection after the test is sufficient. + name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + ignoreResultAndError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + abortTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: abortTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # second transaction will be causally consistent with the first + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented when retrying the transaction + txnNumber: { $numberLong: "2" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + abortTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "2" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: abortTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # third transaction will be causally consistent with the second + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented when retrying the transaction + txnNumber: { $numberLong: "3" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "3" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - + description: callback is not retried after non-transient error (DuplicateKeyError) + operations: + - name: withTransaction + object: *session1 + arguments: + callback: + - name: insertOne + object: *collection1 + arguments: + session: *session1 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: insertOne + object: *collection1 + arguments: + session: *session1 + document: { _id: 1 } + expectError: + errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] + expectError: + errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] + # DuplicateKey error code included in the bulk write error message + # returned by the server + errorContains: E11000 + expectEvents: + - client: *client1 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + abortTransaction: 1 + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: abortTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] diff --git a/test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.json b/test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.json new file mode 100644 index 00000000000..c6a4e44d620 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.json @@ -0,0 +1,231 @@ +{ + "description": "commit-retry-errorLabels", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.3.1", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "commit is retried after commitTransaction UnknownTransactionCommitResult (NotWritablePrimary)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 10107, + "errorLabels": [ + "RetryableWriteError" + ], + "closeConnection": false + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.yml b/test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.yml new file mode 100644 index 00000000000..f6f61375b87 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-retry-errorLabels.yml @@ -0,0 +1,118 @@ +description: commit-retry-errorLabels + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: "4.3.1" # failCommand errorLabels option + topologies: [ replicaset, sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + description: commit is retried after commitTransaction UnknownTransactionCommitResult (NotWritablePrimary) + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + errorCode: 10107 # NotWritablePrimary + errorLabels: ["RetryableWriteError"] # SPEC-1565 + closeConnection: false + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, wtimeout: 10000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, wtimeout: 10000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } diff --git a/test/spec/transactions-convenient-api/unified/commit-retry.json b/test/spec/transactions-convenient-api/unified/commit-retry.json new file mode 100644 index 00000000000..c6d490d7bf6 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-retry.json @@ -0,0 +1,542 @@ +{ + "description": "commit-retry", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "commitTransaction succeeds after multiple connection errors", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "closeConnection": true + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "commitTransaction retry only overwrites write concern w option", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "closeConnection": true + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ], + "writeConcern": { + "w": 2, + "journal": true, + "wtimeoutMS": 5000 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": 2, + "j": true, + "wtimeout": 5000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "j": true, + "wtimeout": 5000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "j": true, + "wtimeout": 5000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "commit is not retried after MaxTimeMSExpired error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 50 + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ], + "maxCommitTimeMS": 60000 + }, + "expectError": { + "errorCodeName": "MaxTimeMSExpired", + "errorLabelsContain": [ + "UnknownTransactionCommitResult" + ], + "errorLabelsOmit": [ + "TransientTransactionError" + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "maxTimeMS": 60000, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/commit-retry.yml b/test/spec/transactions-convenient-api/unified/commit-retry.yml new file mode 100644 index 00000000000..e051d9d148a --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-retry.yml @@ -0,0 +1,271 @@ +description: commit-retry + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + description: commitTransaction succeeds after multiple connection errors + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + closeConnection: true + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, wtimeout: 10000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, wtimeout: 10000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - + description: commitTransaction retry only overwrites write concern w option + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + closeConnection: true + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + writeConcern: { w: 2, journal: true, wtimeoutMS: 5000 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + writeConcern: { w: 2, j: true, wtimeout: 5000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, j: true, wtimeout: 5000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, j: true, wtimeout: 5000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - + description: commit is not retried after MaxTimeMSExpired error + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: [ commitTransaction ] + errorCode: 50 # MaxTimeMSExpired + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + maxCommitTimeMS: 60000 + expectError: + errorCodeName: MaxTimeMSExpired + errorLabelsContain: ["UnknownTransactionCommitResult"] + errorLabelsOmit: ["TransientTransactionError"] + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + maxTimeMS: 60000 + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + # In reality, the outcome of the commit is unknown but we fabricate + # the error with failCommand.errorCode which does not apply the commit + # operation. + documents: [] diff --git a/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.json b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.json new file mode 100644 index 00000000000..5cffd71014a --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.json @@ -0,0 +1,293 @@ +{ + "description": "commit-transienttransactionerror-4.2", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.1.6", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "transaction is retried after commitTransaction TransientTransactionError (PreparedTransactionInProgress)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 267, + "closeConnection": false + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "3" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "3" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.yml b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.yml new file mode 100644 index 00000000000..f777ae8b49e --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror-4.2.yml @@ -0,0 +1,156 @@ +description: commit-transienttransactionerror-4.2 + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.1.6' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +# These tests use error codes where the TransientTransactionError label will be +# applied to the error response for commitTransaction. This will cause the +# entire transaction to be retried instead of commitTransaction. +# +# See: https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/db/handle_request_response.cpp +tests: + - + description: transaction is retried after commitTransaction TransientTransactionError (PreparedTransactionInProgress) + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + errorCode: 267 # PreparedTransactionInProgress + closeConnection: false + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # second transaction will be causally consistent with the first + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented when retrying the transaction + txnNumber: { $numberLong: "2" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "2" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # third transaction will be causally consistent with the second + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented when retrying the transaction + txnNumber: { $numberLong: "3" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "3" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } diff --git a/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.json b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.json new file mode 100644 index 00000000000..400507533ac --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.json @@ -0,0 +1,995 @@ +{ + "description": "commit-transienttransactionerror", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "transaction is retried after commitTransaction TransientTransactionError (LockTimeout)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 24, + "closeConnection": false + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "3" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "3" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "transaction is retried after commitTransaction TransientTransactionError (WriteConflict)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 112, + "closeConnection": false + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "3" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "3" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "transaction is retried after commitTransaction TransientTransactionError (SnapshotUnavailable)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 246, + "closeConnection": false + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "3" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "3" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "transaction is retried after commitTransaction TransientTransactionError (NoSuchTransaction)", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "errorCode": 251, + "closeConnection": false + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "3" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "3" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.yml b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.yml new file mode 100644 index 00000000000..fed09e91af7 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-transienttransactionerror.yml @@ -0,0 +1,209 @@ +description: commit-transienttransactionerror + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +# These tests use error codes where the TransientTransactionError label will be +# applied to the error response for commitTransaction. This will cause the +# entire transaction to be retried instead of commitTransaction. +# +# See: https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/db/handle_request_response.cpp +tests: + - + description: transaction is retried after commitTransaction TransientTransactionError (LockTimeout) + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + errorCode: 24 # LockTimeout + closeConnection: false + - &withTransaction + name: withTransaction + object: *session0 + arguments: + callback: + - + name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: &expectEvents + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # second transaction will be causally consistent with the first + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented when retrying the transaction + txnNumber: { $numberLong: "2" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "2" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # third transaction will be causally consistent with the second + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented when retrying the transaction + txnNumber: { $numberLong: "3" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "3" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: &outcome + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - + description: transaction is retried after commitTransaction TransientTransactionError (WriteConflict) + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + errorCode: 112 # WriteConflict + closeConnection: false + - *withTransaction + expectEvents: *expectEvents + outcome: *outcome + - + description: transaction is retried after commitTransaction TransientTransactionError (SnapshotUnavailable) + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + errorCode: 246 # SnapshotUnavailable + closeConnection: false + - *withTransaction + expectEvents: *expectEvents + outcome: *outcome + - + description: transaction is retried after commitTransaction TransientTransactionError (NoSuchTransaction) + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + errorCode: 251 # NoSuchTransaction + closeConnection: false + - *withTransaction + expectEvents: *expectEvents + outcome: *outcome diff --git a/test/spec/transactions-convenient-api/unified/commit-writeconcernerror.json b/test/spec/transactions-convenient-api/unified/commit-writeconcernerror.json new file mode 100644 index 00000000000..a6f6e6bd7fa --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-writeconcernerror.json @@ -0,0 +1,814 @@ +{ + "description": "commit-writeconcernerror", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": false, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "commitTransaction is retried after WriteConcernFailed timeout error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "writeConcernError": { + "code": 64, + "codeName": "WriteConcernFailed", + "errmsg": "waiting for replication timed out", + "errInfo": { + "wtimeout": true + } + } + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "commitTransaction is retried after WriteConcernFailed non-timeout error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "writeConcernError": { + "code": 64, + "codeName": "WriteConcernFailed", + "errmsg": "multiple errors reported" + } + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": "majority", + "wtimeout": 10000 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "commitTransaction is not retried after UnknownReplWriteConcern error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "writeConcernError": { + "code": 79, + "codeName": "UnknownReplWriteConcern", + "errmsg": "No write concern mode named 'foo' found in replica set configuration" + } + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + }, + "expectError": { + "errorCodeName": "UnknownReplWriteConcern", + "errorLabelsOmit": [ + "TransientTransactionError", + "UnknownTransactionCommitResult" + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "commitTransaction is not retried after UnsatisfiableWriteConcern error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "writeConcernError": { + "code": 100, + "codeName": "UnsatisfiableWriteConcern", + "errmsg": "Not enough data-bearing nodes" + } + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + }, + "expectError": { + "errorCodeName": "UnsatisfiableWriteConcern", + "errorLabelsOmit": [ + "TransientTransactionError", + "UnknownTransactionCommitResult" + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "commitTransaction is not retried after MaxTimeMSExpired error", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client0", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "commitTransaction" + ], + "writeConcernError": { + "code": 50, + "codeName": "MaxTimeMSExpired", + "errmsg": "operation exceeded time limit" + } + } + } + } + }, + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + }, + "expectError": { + "errorCodeName": "MaxTimeMSExpired", + "errorLabelsContain": [ + "UnknownTransactionCommitResult" + ], + "errorLabelsOmit": [ + "TransientTransactionError" + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/commit-writeconcernerror.yml b/test/spec/transactions-convenient-api/unified/commit-writeconcernerror.yml new file mode 100644 index 00000000000..44877fa008f --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit-writeconcernerror.yml @@ -0,0 +1,250 @@ +description: commit-writeconcernerror + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: false + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + description: commitTransaction is retried after WriteConcernFailed timeout error + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + # Do not specify closeConnection: false, since that would conflict + # with writeConcernError (see: SERVER-39292) + writeConcernError: + code: 64 + codeName: WriteConcernFailed + errmsg: "waiting for replication timed out" + errInfo: { wtimeout: true } + - &operation + name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: &expectEvents_with_retries + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, wtimeout: 10000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # commitTransaction applies w:majority on retries (SPEC-1185) + writeConcern: { w: majority, wtimeout: 10000 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + # The write operation is still applied despite the write concern error + outcome: &outcome + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - + # This test configures the fail point to return an error with the + # WriteConcernFailed code but without errInfo that would identify it as a + # wtimeout error. This tests that drivers do not assume that all + # WriteConcernFailed errors are due to a replication timeout. + description: commitTransaction is retried after WriteConcernFailed non-timeout error + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [ commitTransaction ] + # Do not specify closeConnection: false, since that would conflict + # with writeConcernError (see: SERVER-39292) + writeConcernError: + code: 64 + codeName: WriteConcernFailed + errmsg: "multiple errors reported" + - *operation + expectEvents: *expectEvents_with_retries + outcome: *outcome + - + description: commitTransaction is not retried after UnknownReplWriteConcern error + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: [ commitTransaction ] + writeConcernError: + code: 79 + codeName: UnknownReplWriteConcern + errmsg: "No write concern mode named 'foo' found in replica set configuration" + - <<: *operation + expectError: + errorCodeName: UnknownReplWriteConcern + errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] + expectEvents: &expectEvents_without_retries + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + # failCommand with writeConcernError still applies the write operation(s) + outcome: *outcome + - + description: commitTransaction is not retried after UnsatisfiableWriteConcern error + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: [ commitTransaction ] + writeConcernError: + code: 100 + codeName: UnsatisfiableWriteConcern + errmsg: "Not enough data-bearing nodes" + - <<: *operation + expectError: + errorCodeName: UnsatisfiableWriteConcern + errorLabelsOmit: ["TransientTransactionError", "UnknownTransactionCommitResult"] + expectEvents: *expectEvents_without_retries + # failCommand with writeConcernError still applies the write operation(s) + outcome: *outcome + - + description: commitTransaction is not retried after MaxTimeMSExpired error + operations: + - name: failPoint + object: testRunner + arguments: + client: *client0 + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: [ commitTransaction ] + writeConcernError: + code: 50 + codeName: MaxTimeMSExpired + errmsg: "operation exceeded time limit" + - <<: *operation + expectError: + errorCodeName: MaxTimeMSExpired + errorLabelsContain: ["UnknownTransactionCommitResult"] + errorLabelsOmit: ["TransientTransactionError"] + expectEvents: *expectEvents_without_retries + # failCommand with writeConcernError still applies the write operation(s) + outcome: *outcome diff --git a/test/spec/transactions-convenient-api/unified/commit.json b/test/spec/transactions-convenient-api/unified/commit.json new file mode 100644 index 00000000000..5684d5ee891 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit.json @@ -0,0 +1,398 @@ +{ + "description": "commit", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": true, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "withTransaction commits after callback returns", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 2 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ] + }, + { + "description": "withTransaction commits after callback returns (second transaction)", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + }, + { + "name": "commitTransaction", + "object": "session0" + }, + { + "name": "startTransaction", + "object": "session0" + }, + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 2 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 2 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "readConcern": { + "afterClusterTime": { + "$$exists": true + } + }, + "txnNumber": { + "$numberLong": "2" + }, + "startTransaction": true, + "autocommit": false, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "2" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/commit.yml b/test/spec/transactions-convenient-api/unified/commit.yml new file mode 100644 index 00000000000..774ddb1b069 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/commit.yml @@ -0,0 +1,199 @@ +description: commit + +schemaVersion: '1.3' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: true + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + description: withTransaction commits after callback returns + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 2 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 2 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 2 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - { _id: 2 } + - + # In this scenario, the callback commits the transaction originally started + # by withTransaction and starts a second transaction before returning. Since + # withTransaction only examines the session's state, it should commit that + # second transaction after the callback returns. + description: withTransaction commits after callback returns (second transaction) + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + - name: commitTransaction + object: *session0 + - name: startTransaction + object: *session0 + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 2 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 2 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 2 } + ordered: true + lsid: { $$sessionLsid: *session0 } + # second transaction will be causally consistent with the first + readConcern: { afterClusterTime: { $$exists: true } } + # txnNumber is incremented for the second transaction + txnNumber: { $numberLong: "2" } + startTransaction: true + autocommit: false + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "2" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - { _id: 2 } diff --git a/test/spec/transactions-convenient-api/unified/transaction-options.json b/test/spec/transactions-convenient-api/unified/transaction-options.json new file mode 100644 index 00000000000..b1a74c5fd14 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/transaction-options.json @@ -0,0 +1,819 @@ +{ + "description": "transaction-options", + "schemaVersion": "1.9", + "runOnRequirements": [ + { + "minServerVersion": "4.0", + "topologies": [ + "replicaset" + ] + }, + { + "minServerVersion": "4.1.8", + "topologies": [ + "sharded", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "useMultipleMongoses": true, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + }, + { + "session": { + "id": "session0", + "client": "client0" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [] + } + ], + "tests": [ + { + "description": "withTransaction and no transaction options set", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "withTransaction inherits transaction options from client", + "operations": [ + { + "object": "testRunner", + "name": "createEntities", + "arguments": { + "entities": [ + { + "client": { + "id": "client1", + "useMultipleMongoses": true, + "uriOptions": { + "readConcernLevel": "local", + "w": 1 + }, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database1", + "client": "client1", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection1", + "database": "database1", + "collectionName": "test" + } + }, + { + "session": { + "id": "session1", + "client": "client1" + } + } + ] + } + }, + { + "name": "withTransaction", + "object": "session1", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection1", + "arguments": { + "session": "session1", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client1", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "level": "local" + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": 1 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "withTransaction inherits transaction options from defaultTransactionOptions", + "operations": [ + { + "object": "testRunner", + "name": "createEntities", + "arguments": { + "entities": [ + { + "session": { + "id": "session1", + "client": "client0", + "sessionOptions": { + "defaultTransactionOptions": { + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "w": 1 + } + } + } + } + } + ] + } + }, + { + "name": "withTransaction", + "object": "session1", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session1", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ] + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": 1 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "withTransaction explicit transaction options", + "operations": [ + { + "name": "withTransaction", + "object": "session0", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session0", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ], + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "w": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session0" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": 1 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "withTransaction explicit transaction options override defaultTransactionOptions", + "operations": [ + { + "object": "testRunner", + "name": "createEntities", + "arguments": { + "entities": [ + { + "session": { + "id": "session1", + "client": "client0", + "sessionOptions": { + "defaultTransactionOptions": { + "readConcern": { + "level": "snapshot" + }, + "writeConcern": { + "w": "majority" + } + } + } + } + } + ] + } + }, + { + "name": "withTransaction", + "object": "session1", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "session": "session1", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ], + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "w": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": 1 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + }, + { + "description": "withTransaction explicit transaction options override client options", + "operations": [ + { + "object": "testRunner", + "name": "createEntities", + "arguments": { + "entities": [ + { + "client": { + "id": "client1", + "useMultipleMongoses": true, + "uriOptions": { + "readConcernLevel": "local", + "w": "majority" + }, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database1", + "client": "client1", + "databaseName": "withTransaction-tests" + } + }, + { + "collection": { + "id": "collection1", + "database": "database1", + "collectionName": "test" + } + }, + { + "session": { + "id": "session1", + "client": "client1" + } + } + ] + } + }, + { + "name": "withTransaction", + "object": "session1", + "arguments": { + "callback": [ + { + "name": "insertOne", + "object": "collection1", + "arguments": { + "session": "session1", + "document": { + "_id": 1 + } + }, + "expectResult": { + "$$unsetOrMatches": { + "insertedId": { + "$$unsetOrMatches": 1 + } + } + } + } + ], + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "w": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client1", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "startTransaction": true, + "autocommit": false, + "readConcern": { + "level": "majority" + }, + "writeConcern": { + "$$exists": false + } + }, + "commandName": "insert", + "databaseName": "withTransaction-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "commitTransaction": 1, + "lsid": { + "$$sessionLsid": "session1" + }, + "txnNumber": { + "$numberLong": "1" + }, + "autocommit": false, + "writeConcern": { + "w": 1 + }, + "readConcern": { + "$$exists": false + }, + "startTransaction": { + "$$exists": false + } + }, + "commandName": "commitTransaction", + "databaseName": "admin" + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "test", + "databaseName": "withTransaction-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ] + } + ] +} diff --git a/test/spec/transactions-convenient-api/unified/transaction-options.yml b/test/spec/transactions-convenient-api/unified/transaction-options.yml new file mode 100644 index 00000000000..fc6674c9e25 --- /dev/null +++ b/test/spec/transactions-convenient-api/unified/transaction-options.yml @@ -0,0 +1,379 @@ +description: transaction-options + +schemaVersion: '1.9' + +runOnRequirements: + - minServerVersion: '4.0' + topologies: [ replicaset ] + - minServerVersion: 4.1.8 + topologies: [ sharded, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + useMultipleMongoses: true + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &databaseName withTransaction-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collectionName test + - session: + id: &session0 session0 + client: *client0 + +initialData: + - collectionName: *collectionName + databaseName: *databaseName + documents: [] + +tests: + - + description: withTransaction and no transaction options set + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + # omitted fields + readConcern: { $$exists: false } + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + writeConcern: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: &outcome + - collectionName: *collectionName + databaseName: *databaseName + documents: + - { _id: 1 } + - + description: withTransaction inherits transaction options from client + operations: + - object: testRunner + name: createEntities + arguments: + entities: + - client: + id: &client1 client1 + useMultipleMongoses: true + uriOptions: + readConcernLevel: local + w: 1 + observeEvents: [ commandStartedEvent ] + - database: + id: &database1 database1 + client: *client1 + databaseName: *databaseName + - collection: + id: &collection1 collection1 + database: *database1 + collectionName: *collectionName + - session: + id: &session1 session1 + client: *client1 + - name: withTransaction + object: *session1 + arguments: + callback: + - name: insertOne + object: *collection1 + arguments: + session: *session1 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: + - client: *client1 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + readConcern: { level: local } + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + autocommit: false + writeConcern: { w: 1 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: *outcome + - + description: withTransaction inherits transaction options from defaultTransactionOptions + operations: + - object: testRunner + name: createEntities + arguments: + entities: + - session: + id: &session1 session1 + client: *client0 + sessionOptions: + defaultTransactionOptions: + readConcern: { level: majority } + writeConcern: { w: 1 } + - name: withTransaction + object: *session1 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session1 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + readConcern: { level: majority } + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + autocommit: false + writeConcern: { w: 1 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: *outcome + - + description: withTransaction explicit transaction options + operations: + - name: withTransaction + object: *session0 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session0 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + readConcern: { level: majority } + writeConcern: { w: 1 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + readConcern: { level: majority } + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session0 } + txnNumber: { $numberLong: "1" } + autocommit: false + writeConcern: { w: 1 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: *outcome + - + description: withTransaction explicit transaction options override defaultTransactionOptions + operations: + - object: testRunner + name: createEntities + arguments: + entities: + - session: + id: &session1 session1 + client: *client0 + sessionOptions: + defaultTransactionOptions: + readConcern: { level: snapshot } + writeConcern: { w: majority } + - name: withTransaction + object: *session1 + arguments: + callback: + - name: insertOne + object: *collection0 + arguments: + session: *session1 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + readConcern: { level: majority } + writeConcern: { w: 1 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + readConcern: { level: majority } + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + autocommit: false + writeConcern: { w: 1 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: *outcome + - + description: withTransaction explicit transaction options override client options + operations: + - object: testRunner + name: createEntities + arguments: + entities: + - client: + id: &client1 client1 + useMultipleMongoses: true + uriOptions: + readConcernLevel: local + w: majority + observeEvents: [ commandStartedEvent ] + - database: + id: &database1 database1 + client: *client1 + databaseName: *databaseName + - collection: + id: &collection1 collection1 + database: *database1 + collectionName: *collectionName + - session: + id: &session1 session1 + client: *client1 + - name: withTransaction + object: *session1 + arguments: + callback: + - name: insertOne + object: *collection1 + arguments: + session: *session1 + document: { _id: 1 } + expectResult: + $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 1 } } + readConcern: { level: majority } + writeConcern: { w: 1 } + expectEvents: + - client: *client1 + events: + - commandStartedEvent: + command: + insert: *collectionName + documents: + - { _id: 1 } + ordered: true + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + startTransaction: true + autocommit: false + readConcern: { level: majority } + # omitted fields + writeConcern: { $$exists: false } + commandName: insert + databaseName: *databaseName + - commandStartedEvent: + command: + commitTransaction: 1 + lsid: { $$sessionLsid: *session1 } + txnNumber: { $numberLong: "1" } + autocommit: false + writeConcern: { w: 1 } + # omitted fields + readConcern: { $$exists: false } + startTransaction: { $$exists: false } + commandName: commitTransaction + databaseName: admin + outcome: *outcome diff --git a/test/tools/unified-spec-runner/match.ts b/test/tools/unified-spec-runner/match.ts index 1098efc1fb1..8393e2047bc 100644 --- a/test/tools/unified-spec-runner/match.ts +++ b/test/tools/unified-spec-runner/match.ts @@ -404,6 +404,7 @@ function failOnMismatchedCount( actual: CommandEvent[] | CmapEvent[] | SdamEvent[], expected: (ExpectedCommandEvent & ExpectedCmapEvent & ExpectedSdamEvent)[] ) { + console.log(actual, expected); const actualNames = actual.map(a => a.constructor.name); const expectedNames = expected.map(e => Object.keys(e)[0]); expect.fail( diff --git a/test/tools/unified-spec-runner/operations.ts b/test/tools/unified-spec-runner/operations.ts index 2b955416fc6..2b993addad0 100644 --- a/test/tools/unified-spec-runner/operations.ts +++ b/test/tools/unified-spec-runner/operations.ts @@ -905,8 +905,13 @@ export async function executeOperationAndCheck( const opFunc = operations.get(operation.name); expect(opFunc, `Unknown operation: ${operation.name}`).to.exist; - if (operation.arguments?.session) { - operation.arguments.session = entities.getEntity('session', operation.arguments.session); + if (operation.arguments && operation.arguments.session) { + // The session could need to be either pulled from the entity map or in the case where + // we've recursively called this function it may already be present and going back to + // the map with an object instead of a string will fail. + if (typeof operation.arguments.session === 'string') { + operation.arguments.session = entities.getEntity('session', operation.arguments.session); + } } let result;