# Assumes the default for transactions is the same as for all ops, tests
# setting the writeConcern to "majority".
runOn:
    -
        minServerVersion: "4.0"
        topology: ["replicaset"]
    -
        minServerVersion: "4.1.8"
        topology: ["sharded"]

database_name: &database_name "transaction-tests"
collection_name: &collection_name "test"

data: &data
  - _id: 0

tests:
  - description: commit with majority
    operations:
      - name: startTransaction
        object: session0
        arguments:
          options:
            writeConcern:
              w: majority
      - name: insertOne
        object: collection
        arguments:
          session: session0
          document:
            _id: 1
        result:
          insertedId: 1
      - &commitTransaction
        name: commitTransaction
        object: session0

    expectations:
      - &insertOneEvent
        command_started_event:
          command:
            insert: *collection_name
            documents:
              - _id: 1
            ordered: true
            <<: &transactionCommandArgs
              lsid: session0
              txnNumber:
                $numberLong: "1"
              startTransaction: true
              autocommit: false
              readConcern:
              writeConcern:
          command_name: insert
          database_name: *database_name
      - command_started_event:
          command:
            commitTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern:
              w: majority
          command_name: commitTransaction
          database_name: admin

    outcome:
      collection:
        data:
          - _id: 0
          - _id: 1

  - description: commit with default

    operations:
      - &startTransaction
        name: startTransaction
        object: session0
      - name: insertOne
        object: collection
        arguments:
          session: session0
          document:
            _id: 1
        result:
          insertedId: 1
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            insert: *collection_name
            documents:
              - _id: 1
            ordered: true
            <<: *transactionCommandArgs
          command_name: insert
          database_name: *database_name
      - &commitWithDefaultWCEvent
        command_started_event:
          command:
            commitTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern:
          command_name: commitTransaction
          database_name: admin

    outcome:
      collection:
        data:
          - _id: 0
          - _id: 1

  - description: abort with majority

    operations:
      - name: startTransaction
        object: session0
        arguments:
          options:
            writeConcern:
              w: majority
      - 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
            <<: *transactionCommandArgs
          command_name: insert
          database_name: *database_name
      - command_started_event:
          command:
            abortTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern:
              w: majority
          command_name: abortTransaction
          database_name: admin

    outcome:
      collection:
        data: *data

  - description: abort with default

    operations:
      - name: startTransaction
        object: session0
      - 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
            <<: *transactionCommandArgs
          command_name: insert
          database_name: *database_name
      - command_started_event:
          command:
            abortTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern:
          command_name: abortTransaction
          database_name: admin

    outcome:
      collection:
        data: *data

  - description: start with unacknowledged write concern

    operations:
      - name: startTransaction
        object: session0
        arguments:
          options:
            writeConcern:
              w: 0
        result:
          # Client-side error.
          errorContains: transactions do not support unacknowledged write concern

  - description: start with implicit unacknowledged write concern

    clientOptions:
      w: 0

    operations:
      - name: startTransaction
        object: session0
        result:
          # Client-side error.
          errorContains: transactions do not support unacknowledged write concern

  - description: unacknowledged write concern coll insertOne

    operations:
      - *startTransaction
      - name: insertOne
        <<: &collection_w0
          object: collection
          collectionOptions:
            writeConcern: { w: 0 }
        arguments:
          session: session0
          document:
            _id: 1
        result:
          insertedId: 1
      - *commitTransaction

    expectations:
      - *insertOneEvent
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - _id: 0
          - _id: 1

  - description: unacknowledged write concern coll insertMany

    operations:
      - *startTransaction
      - name: insertMany
        <<: *collection_w0
        arguments:
          session: session0
          documents:
            - _id: 1
            - _id: 2
        result:
          insertedIds: {0: 1, 1: 2}
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            insert: *collection_name
            documents:
              - _id: 1
              - _id: 2
            ordered: true
            <<: *transactionCommandArgs
          command_name: insert
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - _id: 0
          - _id: 1
          - _id: 2

  - description: unacknowledged write concern coll bulkWrite

    operations:
      - *startTransaction
      - name: bulkWrite
        <<: *collection_w0
        arguments:
          session: session0
          requests:
            - name: insertOne
              arguments:
                document: {_id: 1}
        result:
          deletedCount: 0
          insertedCount: 1
          insertedIds: {0: 1}
          matchedCount: 0
          modifiedCount: 0
          upsertedCount: 0
          upsertedIds: {}
      - *commitTransaction

    expectations:
      - *insertOneEvent
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - _id: 0
          - _id: 1


  - description: unacknowledged write concern coll deleteOne

    operations:
      - *startTransaction
      - name: deleteOne
        <<: *collection_w0
        arguments:
          session: session0
          filter:
            _id: 0
        result:
          deletedCount: 1
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            delete: *collection_name
            deletes:
              - q: {_id: 0}
                limit: 1
            ordered: true
            <<: *transactionCommandArgs
          command_name: delete
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data: []

  - description: unacknowledged write concern coll deleteMany

    operations:
      - *startTransaction
      - name: deleteMany
        <<: *collection_w0
        arguments:
          session: session0
          filter:
            _id: 0
        result:
          deletedCount: 1
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            delete: *collection_name
            deletes:
              - q: {_id: 0}
                limit: 0
            ordered: true
            <<: *transactionCommandArgs
          command_name: delete
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data: []

  - description: unacknowledged write concern coll updateOne

    operations:
      - *startTransaction
      - name: updateOne
        <<: *collection_w0
        arguments:
          session: session0
          filter: {_id: 0}
          update:
            $inc: {x: 1}
          upsert: true
        result:
          matchedCount: 1
          modifiedCount: 1
          upsertedCount: 0
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            update: *collection_name
            updates:
              - q: {_id: 0}
                u: {$inc: {x: 1}}
                upsert: true
            ordered: true
            <<: *transactionCommandArgs
          command_name: update
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - {_id: 0, x: 1}

  - description: unacknowledged write concern coll updateMany

    operations:
      - *startTransaction
      - name: updateMany
        <<: *collection_w0
        arguments:
          session: session0
          filter: {_id: 0}
          update:
            $inc: {x: 1}
          upsert: true
        result:
          matchedCount: 1
          modifiedCount: 1
          upsertedCount: 0
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            update: *collection_name
            updates:
              - q: {_id: 0}
                u: {$inc: {x: 1}}
                multi: true
                upsert: true
            ordered: true
            <<: *transactionCommandArgs
          command_name: update
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - {_id: 0, x: 1}

  - description: unacknowledged write concern coll findOneAndDelete

    operations:
      - *startTransaction
      - name: findOneAndDelete
        <<: *collection_w0
        arguments:
          session: session0
          filter: {_id: 0}
        result: {_id: 0}
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            findAndModify: *collection_name
            query: {_id: 0}
            remove: True
            <<: *transactionCommandArgs
          command_name: findAndModify
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data: []

  - description: unacknowledged write concern coll findOneAndReplace

    operations:
      - *startTransaction
      - name: findOneAndReplace
        <<: *collection_w0
        arguments:
          session: session0
          filter: {_id: 0}
          replacement: {x: 1}
          returnDocument: Before
        result: {_id: 0}
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            findAndModify: *collection_name
            query: {_id: 0}
            update: {x: 1}
            new: false
            <<: *transactionCommandArgs
          command_name: findAndModify
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - {_id: 0, x: 1}

  - description: unacknowledged write concern coll findOneAndUpdate

    operations:
      - *startTransaction
      - name: findOneAndUpdate
        <<: *collection_w0
        arguments:
          session: session0
          filter: {_id: 0}
          update:
            $inc: {x: 1}
          returnDocument: Before
        result: {_id: 0}
      - *commitTransaction

    expectations:
      - command_started_event:
          command:
            findAndModify: *collection_name
            query: {_id: 0}
            update: {$inc: {x: 1}}
            new: false
            <<: *transactionCommandArgs
          command_name: findAndModify
          database_name: *database_name
      - *commitWithDefaultWCEvent

    outcome:
      collection:
        data:
          - {_id: 0, x: 1}
