runOn:
    -
        minServerVersion: "4.3.1"
        topology: ["replicaset", "sharded"]

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

data: []

tests:
  - description: commitTransaction does not retry error without RetryableWriteError label
    clientOptions:
      retryWrites: false
    failPoint:
      configureFailPoint: failCommand
      mode: { times: 1 }
      data:
          failCommands: ["commitTransaction"]
          errorCode: 11600 # InterruptedAtShutdown, normally a retryable error code
          errorLabels: []  # Override server behavior: do not send RetryableWriteError label with retryable code
    operations:
      - name: startTransaction
        object: session0
      - name: insertOne
        object: collection
        arguments:
          session: session0
          document:
            _id: 1
        result:
          insertedId: 1
      - name: commitTransaction
        object: session0
        result:
          errorLabelsOmit: ["RetryableWriteError", "TransientTransactionError"]
    expectations:
      - command_started_event:
          command:
            insert: *collection_name
            documents:
              - _id: 1
            ordered: true
            readConcern:
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction: true
            autocommit: false
            writeConcern:
          command_name: insert
          database_name: *database_name
      - command_started_event:
          command:
            commitTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern:
          command_name: commitTransaction
          database_name: admin
    outcome: # Driver does not retry commit because there was no RetryableWriteError label on response
      collection:
        data: []

  - description: commitTransaction retries once with RetryableWriteError from server
    clientOptions:
      retryWrites: false
    failPoint:
      configureFailPoint: failCommand
      mode: { times: 1 }
      data:
          failCommands: ["commitTransaction"]
          errorCode: 112 # WriteConflict, not a retryable error code
          errorLabels: ["RetryableWriteError"] # Override server behavior: send RetryableWriteError label with non-retryable error code
    operations:
      - name: startTransaction
        object: session0
      - name: insertOne
        object: collection
        arguments:
          session: session0
          document:
            _id: 1
        result:
          insertedId: 1
      - name: commitTransaction
        object: session0
    expectations:
      - command_started_event:
          command:
            insert: *collection_name
            documents:
              - _id: 1
            ordered: true
            readConcern:
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction: true
            autocommit: false
            writeConcern:
          command_name: insert
          database_name: *database_name
      - command_started_event:
          command:
            commitTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern:
          command_name: commitTransaction
          database_name: admin
      - command_started_event:
          command:
            commitTransaction: 1
            lsid: session0
            txnNumber:
              $numberLong: "1"
            startTransaction:
            autocommit: false
            writeConcern: { w: majority, wtimeout: 10000 }
          command_name: commitTransaction
          database_name: admin
    outcome: # Driver retries commit and it succeeds
      collection:
        data:
          - _id: 1
