diff --git a/data/load-balancers/cursors.json b/data/load-balancers/cursors.json index d954644776..43e4fbb4f6 100644 --- a/data/load-balancers/cursors.json +++ b/data/load-balancers/cursors.json @@ -1148,6 +1148,81 @@ ] } ] + }, + { + "description": "change streams pin to a connection", + "operations": [ + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [] + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "assertNumberConnectionsCheckedOut", + "object": "testRunner", + "arguments": { + "client": "client0", + "connections": 1 + } + }, + { + "name": "close", + "object": "changeStream0" + }, + { + "name": "assertNumberConnectionsCheckedOut", + "object": "testRunner", + "arguments": { + "client": "client0", + "connections": 0 + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "aggregate" + } + }, + { + "commandSucceededEvent": { + "commandName": "aggregate" + } + }, + { + "commandStartedEvent": { + "commandName": "killCursors" + } + }, + { + "commandSucceededEvent": { + "commandName": "killCursors" + } + } + ] + }, + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionReadyEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCheckedInEvent": {} + } + ] + } + ] } ] } diff --git a/data/load-balancers/cursors.yml b/data/load-balancers/cursors.yml index 34859932b0..0797d0c93a 100644 --- a/data/load-balancers/cursors.yml +++ b/data/load-balancers/cursors.yml @@ -462,3 +462,42 @@ tests: # Events for listIndexes and getMore. - connectionCheckedOutEvent: {} - connectionCheckedInEvent: {} + + - description: change streams pin to a connection + operations: + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + saveResultAsEntity: &changeStream0 changeStream0 + - name: assertNumberConnectionsCheckedOut + object: testRunner + arguments: + client: *client0 + connections: 1 + - name: close + object: *changeStream0 + - name: assertNumberConnectionsCheckedOut + object: testRunner + arguments: + client: *client0 + connections: 0 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: aggregate + - commandSucceededEvent: + commandName: aggregate + - commandStartedEvent: + commandName: killCursors + - commandSucceededEvent: + commandName: killCursors + - client: *client0 + eventType: cmap + events: + # Events for creating the change stream. + - connectionReadyEvent: {} + - connectionCheckedOutEvent: {} + # Events for closing the change stream. + - connectionCheckedInEvent: {} diff --git a/data/load-balancers/sdam-error-handling.json b/data/load-balancers/sdam-error-handling.json index 2222bd49cb..63aabc04db 100644 --- a/data/load-balancers/sdam-error-handling.json +++ b/data/load-balancers/sdam-error-handling.json @@ -96,7 +96,17 @@ { "collectionName": "singleColl", "databaseName": "singleDB", - "documents": [] + "documents": [ + { + "_id": 1 + }, + { + "_id": 2 + }, + { + "_id": 3 + } + ] }, { "collectionName": "multiColl", @@ -372,6 +382,127 @@ ] } ] + }, + { + "description": "stale errors are ignored", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "failPointClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 2 + }, + "data": { + "failCommands": [ + "getMore" + ], + "closeConnection": true + } + } + } + }, + { + "name": "createFindCursor", + "object": "singleColl", + "arguments": { + "filter": {}, + "batchSize": 2 + }, + "saveResultAsEntity": "cursor0" + }, + { + "name": "createFindCursor", + "object": "singleColl", + "arguments": { + "filter": {}, + "batchSize": 2 + }, + "saveResultAsEntity": "cursor1" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "cursor0" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "cursor0" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "cursor0", + "expectError": { + "isClientError": true + } + }, + { + "name": "close", + "object": "cursor0" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "cursor1" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "cursor1" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "cursor1", + "expectError": { + "isClientError": true + } + }, + { + "name": "close", + "object": "cursor1" + } + ], + "expectEvents": [ + { + "client": "singleClient", + "eventType": "cmap", + "events": [ + { + "connectionCreatedEvent": {} + }, + { + "connectionReadyEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "connectionCreatedEvent": {} + }, + { + "connectionReadyEvent": {} + }, + { + "connectionCheckedOutEvent": {} + }, + { + "poolClearedEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionClosedEvent": {} + }, + { + "connectionCheckedInEvent": {} + }, + { + "connectionClosedEvent": {} + } + ] + } + ] } ] } diff --git a/data/load-balancers/sdam-error-handling.yml b/data/load-balancers/sdam-error-handling.yml index f9a8913f47..9ed1b226fb 100644 --- a/data/load-balancers/sdam-error-handling.yml +++ b/data/load-balancers/sdam-error-handling.yml @@ -52,7 +52,10 @@ createEntities: initialData: - collectionName: *singleCollName databaseName: *singleDBName - documents: [] + documents: + - _id: 1 + - _id: 2 + - _id: 3 - collectionName: *multiCollName databaseName: *multiDBName documents: @@ -196,3 +199,72 @@ tests: reason: error - connectionCheckOutFailedEvent: reason: connectionError + + - description: stale errors are ignored + operations: + - name: failPoint + object: testRunner + arguments: + client: *failPointClient + failPoint: + configureFailPoint: failCommand + mode: { times: 2 } + data: + failCommands: [getMore] + closeConnection: true + # Force two connections to be checked out from the pool. + - name: createFindCursor + object: *singleColl + arguments: + filter: {} + batchSize: 2 + saveResultAsEntity: &cursor0 cursor0 + - name: createFindCursor + object: *singleColl + arguments: + filter: {} + batchSize: 2 + saveResultAsEntity: &cursor1 cursor1 + # Iterate cursor0 three times to force a network error. + - name: iterateUntilDocumentOrError + object: *cursor0 + - name: iterateUntilDocumentOrError + object: *cursor0 + - name: iterateUntilDocumentOrError + object: *cursor0 + expectError: + isClientError: true + - name: close + object: *cursor0 + # Iterate cursor1 three times to force a network error. + - name: iterateUntilDocumentOrError + object: *cursor1 + - name: iterateUntilDocumentOrError + object: *cursor1 + - name: iterateUntilDocumentOrError + object: *cursor1 + expectError: + isClientError: true + - name: close + object: *cursor1 + expectEvents: + - client: *singleClient + eventType: cmap + events: + # Events for creating both cursors. + - connectionCreatedEvent: {} + - connectionReadyEvent: {} + - connectionCheckedOutEvent: {} + - connectionCreatedEvent: {} + - connectionReadyEvent: {} + - connectionCheckedOutEvent: {} + # Events for iterating and closing the first cursor. The failed + # getMore should cause a poolClearedEvent to be published. + - poolClearedEvent: {} + - connectionCheckedInEvent: {} + - connectionClosedEvent: {} + # Events for iterating and closing the second cursor. The failed + # getMore should not clear the pool because the connection's + # generation number is stale. + - connectionCheckedInEvent: {} + - connectionClosedEvent: {}