599 lines
19 KiB
YAML
599 lines
19 KiB
YAML
description: transactions are correctly pinned to connections for load-balanced clusters
|
|
|
|
schemaVersion: '1.3'
|
|
|
|
runOnRequirements:
|
|
- topologies: [ load-balanced ]
|
|
|
|
createEntities:
|
|
- client:
|
|
id: &client0 client0
|
|
useMultipleMongoses: true
|
|
observeEvents:
|
|
# Do not observe commandSucceededEvent or commandFailedEvent because we cannot guarantee success or failure of
|
|
# commands like commitTransaction and abortTransaction in a multi-mongos load-balanced setup.
|
|
- commandStartedEvent
|
|
- connectionReadyEvent
|
|
- connectionClosedEvent
|
|
- connectionCheckedOutEvent
|
|
- connectionCheckedInEvent
|
|
- session:
|
|
id: &session0 session0
|
|
client: *client0
|
|
- database:
|
|
id: &database0 database0
|
|
client: *client0
|
|
databaseName: &database0Name database0Name
|
|
- collection:
|
|
id: &collection0 collection0
|
|
database: *database0
|
|
collectionName: &collection0Name coll0
|
|
|
|
initialData:
|
|
- collectionName: *collection0Name
|
|
databaseName: *database0Name
|
|
documents:
|
|
- { _id: 1 }
|
|
- { _id: 2 }
|
|
- { _id: 3 }
|
|
|
|
_yamlAnchors:
|
|
documents:
|
|
- &insertDocument
|
|
_id: 4
|
|
|
|
tests:
|
|
- description: sessions are reused in LB mode
|
|
operations:
|
|
- &nonTransactionalInsert
|
|
name: insertOne
|
|
object: *collection0
|
|
arguments:
|
|
document: { x: 1 }
|
|
- *nonTransactionalInsert
|
|
- name: assertSameLsidOnLastTwoCommands
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
|
|
- description: all operations go to the same mongos
|
|
operations:
|
|
- &startTransaction
|
|
name: startTransaction
|
|
object: *session0
|
|
- &transactionalInsert
|
|
name: insertOne
|
|
object: *collection0
|
|
arguments:
|
|
document: { x: 1 }
|
|
session: *session0
|
|
- &assertConnectionPinned
|
|
name: assertNumberConnectionsCheckedOut
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
connections: 1
|
|
- *transactionalInsert
|
|
- *transactionalInsert
|
|
- *transactionalInsert
|
|
- *transactionalInsert
|
|
- *transactionalInsert
|
|
- *assertConnectionPinned
|
|
- &commitTransaction
|
|
name: commitTransaction
|
|
object: *session0
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- &insertStarted
|
|
commandStartedEvent:
|
|
commandName: insert
|
|
- *insertStarted
|
|
- *insertStarted
|
|
- *insertStarted
|
|
- *insertStarted
|
|
- *insertStarted
|
|
- &commitStarted
|
|
commandStartedEvent:
|
|
commandName: commitTransaction
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# The connection is never checked back in.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
|
|
- description: transaction can be committed multiple times
|
|
operations:
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- *assertConnectionPinned
|
|
- *commitTransaction
|
|
- *assertConnectionPinned
|
|
- *commitTransaction
|
|
- *commitTransaction
|
|
- *commitTransaction
|
|
- *assertConnectionPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *commitStarted
|
|
- *commitStarted
|
|
- *commitStarted
|
|
- *commitStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
|
|
- description: pinned connection is not released after a non-transient CRUD error
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ insert ]
|
|
errorCode: &nonTransientErrorCode 51 # ManualInterventionRequired
|
|
- *startTransaction
|
|
- name: insertOne
|
|
object: *collection0
|
|
arguments:
|
|
document: { x: 1 }
|
|
session: *session0
|
|
expectError: &nonTransientExpectedError
|
|
errorCode: *nonTransientErrorCode
|
|
errorLabelsOmit: [ TransientTransactionError ]
|
|
- *assertConnectionPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the fail point.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the transactional insert.
|
|
- connectionCheckedOutEvent: {}
|
|
|
|
- description: pinned connection is not released after a non-transient commit error
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ commitTransaction ]
|
|
errorCode: *nonTransientErrorCode
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- name: commitTransaction
|
|
object: *session0
|
|
expectError: *nonTransientExpectedError
|
|
- *assertConnectionPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *commitStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the fail point.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the transactional insert and commit.
|
|
- connectionCheckedOutEvent: {}
|
|
|
|
# Errors during abort are different than errors during commit and CRUD operations because the pinned connection is
|
|
# always released after abort.
|
|
- description: pinned connection is released after a non-transient abort error
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ abortTransaction ]
|
|
errorCode: &nonTransientErrorCode 51 # ManualInterventionRequired
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- &assertConnectionNotPinned
|
|
name: assertNumberConnectionsCheckedOut
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
connections: 0
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- &abortStarted
|
|
commandStartedEvent:
|
|
commandName: abortTransaction
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the fail point.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the transactional insert and abort.
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released after a transient non-network CRUD error
|
|
runOnRequirements:
|
|
- serverless: forbid # (CLOUDP-88216) Serverless does not append error labels to errors triggered by failpoints.
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ insert ]
|
|
errorCode: &transientErrorCode 24 # LockTimeout
|
|
- *startTransaction
|
|
- <<: *transactionalInsert
|
|
expectError: &transientExpectedServerError
|
|
errorCode: *transientErrorCode
|
|
errorLabelsContain: [ TransientTransactionError ]
|
|
- *assertConnectionNotPinned
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *abortStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the failpoint.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the insert.
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for abortTransction.
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released after a transient network CRUD error
|
|
runOnRequirements:
|
|
- serverless: forbid # (CLOUDP-88216) Serverless does not append error labels to errors triggered by failpoints.
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ insert ]
|
|
closeConnection: true
|
|
- *startTransaction
|
|
- <<: *transactionalInsert
|
|
expectError: &transientExpectedNetworkError
|
|
isClientError: true
|
|
errorLabelsContain: [ TransientTransactionError ]
|
|
- *assertConnectionNotPinned
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *abortStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the failpoint.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the insert.
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
- connectionClosedEvent:
|
|
reason: error
|
|
# Events for abortTransaction
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released after a transient non-network commit error
|
|
runOnRequirements:
|
|
- serverless: forbid # (CLOUDP-88216) Serverless does not append error labels to errors triggered by failpoints.
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ commitTransaction ]
|
|
errorCode: *transientErrorCode
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- <<: *commitTransaction
|
|
expectError: *transientExpectedServerError
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *commitStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the failpoint.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the insert.
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for commitTransaction.
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released after a transient network commit error
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ commitTransaction ]
|
|
closeConnection: true
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- <<: *commitTransaction
|
|
# Ignore the result and error because the operation might fail if it targets a new mongos that isn't aware of
|
|
# the transaction or the server-side reaper thread closes the transaction first. We only want to assert that
|
|
# the operation is retried, which is done via monitoring expectations, so the exact result/error is not
|
|
# necessary.
|
|
ignoreResultAndError: true
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *commitStarted
|
|
# The commit will be automatically retried.
|
|
- *commitStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the failpoint.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the insert.
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for the first commitTransaction.
|
|
- connectionCheckedInEvent: {}
|
|
- connectionClosedEvent:
|
|
reason: error
|
|
# Events for the commitTransaction retry.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released after a transient non-network abort error
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ abortTransaction ]
|
|
errorCode: *transientErrorCode
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *abortStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the failpoint.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the insert.
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for abortTransaction.
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released after a transient network abort error
|
|
operations:
|
|
- name: failPoint
|
|
object: testRunner
|
|
arguments:
|
|
client: *client0
|
|
failPoint:
|
|
configureFailPoint: failCommand
|
|
mode: { times: 1 }
|
|
data:
|
|
failCommands: [ abortTransaction ]
|
|
closeConnection: true
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *abortStarted
|
|
# The abort will be automatically retried.
|
|
- *abortStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for setting the failpoint.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the insert.
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for the first abortTransaction.
|
|
- connectionCheckedInEvent: {}
|
|
- connectionClosedEvent:
|
|
reason: error
|
|
# Events for the abortTransaction retry.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is released on successful abort
|
|
operations:
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *abortStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# The insert will create and pin a connection. The abort will use it and then unpin.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: pinned connection is returned when a new transaction is started
|
|
operations:
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- *commitTransaction
|
|
- *assertConnectionPinned
|
|
- *startTransaction
|
|
- *assertConnectionNotPinned # startTransaction will unpin the connection.
|
|
- *transactionalInsert
|
|
- *assertConnectionPinned # The first operation in the new transaction will pin the connection again.
|
|
- *commitTransaction
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *commitStarted
|
|
- *insertStarted
|
|
- *commitStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for the first insert and commit.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for startTransaction.
|
|
- connectionCheckedInEvent: {}
|
|
# Events for the second insert and commit.
|
|
- connectionCheckedOutEvent: {}
|
|
|
|
- description: pinned connection is returned when a non-transaction operation uses the session
|
|
operations:
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- *commitTransaction
|
|
- *assertConnectionPinned
|
|
- *transactionalInsert
|
|
# The insert is a non-transactional operation that uses the session, so it unpins the connection.
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- *commitStarted
|
|
- *insertStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for the first insert and commit.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for the second insert.
|
|
- connectionCheckedInEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
- connectionCheckedInEvent: {}
|
|
|
|
- description: a connection can be shared by a transaction and a cursor
|
|
operations:
|
|
- *startTransaction
|
|
- *transactionalInsert
|
|
- *assertConnectionPinned
|
|
- name: createFindCursor
|
|
object: *collection0
|
|
arguments:
|
|
filter: {}
|
|
batchSize: 2
|
|
session: *session0
|
|
saveResultAsEntity: &cursor0 cursor0
|
|
- *assertConnectionPinned
|
|
- name: close
|
|
object: *cursor0
|
|
- *assertConnectionPinned
|
|
# Abort the transaction to ensure that the connection is unpinned.
|
|
- name: abortTransaction
|
|
object: *session0
|
|
- *assertConnectionNotPinned
|
|
expectEvents:
|
|
- client: *client0
|
|
events:
|
|
- *insertStarted
|
|
- commandStartedEvent:
|
|
commandName: find
|
|
- commandStartedEvent:
|
|
commandName: killCursors
|
|
- *abortStarted
|
|
- client: *client0
|
|
eventType: cmap
|
|
events:
|
|
# Events for the insert, find, and killCursors.
|
|
- connectionReadyEvent: {}
|
|
- connectionCheckedOutEvent: {}
|
|
# Events for abortTransaction.
|
|
- connectionCheckedInEvent: {}
|