diff --git a/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts b/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts index a1b0791026..8411e626b9 100644 --- a/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts +++ b/test/integration/client-side-operations-timeout/client_side_operations_timeout.spec.test.ts @@ -18,7 +18,10 @@ const skippedTests = { 'timeoutMS is refreshed for getMore - failure': 'TODO(DRIVERS-2965): see modified test in unified-csot-node-specs', 'timeoutMS applies to full resume attempt in a next call': 'TODO(DRIVERS-3006)', - 'timeoutMS is refreshed for getMore if maxAwaitTimeMS is set': 'TODO(DRIVERS-3018)' + 'timeoutMS is refreshed for getMore if maxAwaitTimeMS is set': 'TODO(DRIVERS-3018)', + 'error on aggregate if maxAwaitTimeMS is greater than timeoutMS': 'TODO(NODE-7297)', + 'error on aggregate if maxAwaitTimeMS is equal to timeoutMS': 'TODO(NODE-7297)', + 'apply remaining timeoutMS if less than maxAwaitTimeMS': 'TODO(NODE-7297)' }; describe('CSOT spec tests', function () { diff --git a/test/spec/client-side-operations-timeout/tailable-awaitData.json b/test/spec/client-side-operations-timeout/tailable-awaitData.json index 535fb69243..80e95ca906 100644 --- a/test/spec/client-side-operations-timeout/tailable-awaitData.json +++ b/test/spec/client-side-operations-timeout/tailable-awaitData.json @@ -3,7 +3,8 @@ "schemaVersion": "1.9", "runOnRequirements": [ { - "minServerVersion": "4.4" + "minServerVersion": "4.4", + "serverless": "forbid" } ], "createEntities": [ @@ -77,7 +78,7 @@ ] }, { - "description": "error if maxAwaitTimeMS is greater than timeoutMS", + "description": "error on find if maxAwaitTimeMS is greater than timeoutMS", "operations": [ { "name": "find", @@ -89,13 +90,50 @@ "maxAwaitTimeMS": 10 }, "expectError": { - "isClientError": true + "isClientError": true, + "isTimeoutError": false + } + } + ] + }, + { + "description": "error on aggregate if maxAwaitTimeMS is greater than timeoutMS", + "operations": [ + { + "name": "aggregate", + "object": "collection", + "arguments": { + "pipeline": [], + "timeoutMS": 5, + "maxAwaitTimeMS": 10 + }, + "expectError": { + "isClientError": true, + "isTimeoutError": false } } ] }, { - "description": "error if maxAwaitTimeMS is equal to timeoutMS", + "description": "error on watch if maxAwaitTimeMS is greater than timeoutMS", + "operations": [ + { + "name": "createChangeStream", + "object": "collection", + "arguments": { + "pipeline": [], + "timeoutMS": 5, + "maxAwaitTimeMS": 10 + }, + "expectError": { + "isClientError": true, + "isTimeoutError": false + } + } + ] + }, + { + "description": "error on find if maxAwaitTimeMS is equal to timeoutMS", "operations": [ { "name": "find", @@ -107,7 +145,44 @@ "maxAwaitTimeMS": 5 }, "expectError": { - "isClientError": true + "isClientError": true, + "isTimeoutError": false + } + } + ] + }, + { + "description": "error on aggregate if maxAwaitTimeMS is equal to timeoutMS", + "operations": [ + { + "name": "aggregate", + "object": "collection", + "arguments": { + "pipeline": [], + "timeoutMS": 5, + "maxAwaitTimeMS": 5 + }, + "expectError": { + "isClientError": true, + "isTimeoutError": false + } + } + ] + }, + { + "description": "error on watch if maxAwaitTimeMS is equal to timeoutMS", + "operations": [ + { + "name": "createChangeStream", + "object": "collection", + "arguments": { + "pipeline": [], + "timeoutMS": 5, + "maxAwaitTimeMS": 5 + }, + "expectError": { + "isClientError": true, + "isTimeoutError": false } } ] @@ -417,6 +492,141 @@ ] } ] + }, + { + "description": "apply remaining timeoutMS if less than maxAwaitTimeMS", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "failPointClient", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "getMore" + ], + "blockConnection": true, + "blockTimeMS": 30 + } + } + } + }, + { + "name": "createFindCursor", + "object": "collection", + "arguments": { + "filter": { + "_id": 1 + }, + "cursorType": "tailableAwait", + "batchSize": 1, + "maxAwaitTimeMS": 100, + "timeoutMS": 200 + }, + "saveResultAsEntity": "tailableCursor" + }, + { + "name": "iterateOnce", + "object": "tailableCursor" + }, + { + "name": "iterateUntilDocumentOrError", + "object": "tailableCursor", + "expectError": { + "isTimeoutError": true + } + } + ], + "expectEvents": [ + { + "client": "client", + "ignoreExtraEvents": true, + "events": [ + { + "commandStartedEvent": { + "commandName": "find", + "databaseName": "test" + } + }, + { + "commandStartedEvent": { + "commandName": "getMore", + "databaseName": "test", + "command": { + "maxTimeMS": { + "$$lte": 100 + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "getMore", + "databaseName": "test", + "command": { + "maxTimeMS": { + "$$lte": 70 + } + } + } + } + ] + } + ] + }, + { + "description": "apply maxAwaitTimeMS if less than remaining timeout", + "operations": [ + { + "name": "createFindCursor", + "object": "collection", + "arguments": { + "filter": {}, + "cursorType": "tailableAwait", + "batchSize": 1, + "maxAwaitTimeMS": 100, + "timeoutMS": 200 + }, + "saveResultAsEntity": "tailableCursor" + }, + { + "name": "iterateOnce", + "object": "tailableCursor" + }, + { + "name": "iterateOnce", + "object": "tailableCursor" + } + ], + "expectEvents": [ + { + "client": "client", + "events": [ + { + "commandStartedEvent": { + "commandName": "find", + "databaseName": "test" + } + }, + { + "commandStartedEvent": { + "commandName": "getMore", + "databaseName": "test", + "command": { + "maxTimeMS": { + "$$lte": 100 + } + } + } + } + ] + } + ] } ] } diff --git a/test/spec/client-side-operations-timeout/tailable-awaitData.yml b/test/spec/client-side-operations-timeout/tailable-awaitData.yml index 52b9b3b456..f374dbf4d6 100644 --- a/test/spec/client-side-operations-timeout/tailable-awaitData.yml +++ b/test/spec/client-side-operations-timeout/tailable-awaitData.yml @@ -4,6 +4,7 @@ schemaVersion: "1.9" runOnRequirements: - minServerVersion: "4.4" + serverless: forbid # Capped collections are not allowed for serverless. createEntities: - client: @@ -47,7 +48,7 @@ tests: expectError: isClientError: true - - description: "error if maxAwaitTimeMS is greater than timeoutMS" + - description: "error on find if maxAwaitTimeMS is greater than timeoutMS" operations: - name: find object: *collection @@ -58,8 +59,33 @@ tests: maxAwaitTimeMS: 10 expectError: isClientError: true + isTimeoutError: false - - description: "error if maxAwaitTimeMS is equal to timeoutMS" + - description: "error on aggregate if maxAwaitTimeMS is greater than timeoutMS" + operations: + - name: aggregate + object: *collection + arguments: + pipeline: [] + timeoutMS: 5 + maxAwaitTimeMS: 10 + expectError: + isClientError: true + isTimeoutError: false + + - description: "error on watch if maxAwaitTimeMS is greater than timeoutMS" + operations: + - name: createChangeStream + object: *collection + arguments: + pipeline: [] + timeoutMS: 5 + maxAwaitTimeMS: 10 + expectError: + isClientError: true + isTimeoutError: false + + - description: "error on find if maxAwaitTimeMS is equal to timeoutMS" operations: - name: find object: *collection @@ -70,6 +96,31 @@ tests: maxAwaitTimeMS: 5 expectError: isClientError: true + isTimeoutError: false + + - description: "error on aggregate if maxAwaitTimeMS is equal to timeoutMS" + operations: + - name: aggregate + object: *collection + arguments: + pipeline: [] + timeoutMS: 5 + maxAwaitTimeMS: 5 + expectError: + isClientError: true + isTimeoutError: false + + - description: "error on watch if maxAwaitTimeMS is equal to timeoutMS" + operations: + - name: createChangeStream + object: *collection + arguments: + pipeline: [] + timeoutMS: 5 + maxAwaitTimeMS: 5 + expectError: + isClientError: true + isTimeoutError: false - description: "timeoutMS applied to find" operations: @@ -102,7 +153,7 @@ tests: tailable: true awaitData: true maxTimeMS: { $$exists: true } - + # If maxAwaitTimeMS is not set, timeoutMS should be refreshed for the getMore and the getMore should not have a # maxTimeMS field. - description: "timeoutMS is refreshed for getMore if maxAwaitTimeMS is not set" @@ -245,3 +296,77 @@ tests: command: getMore: { $$type: ["int", "long"] } collection: *collectionName + + - description: "apply remaining timeoutMS if less than maxAwaitTimeMS" + operations: + - name: failPoint + object: testRunner + arguments: + client: *failPointClient + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: ["getMore"] + blockConnection: true + blockTimeMS: 30 + - name: createFindCursor + object: *collection + arguments: + filter: { _id: 1 } + cursorType: tailableAwait + batchSize: 1 + maxAwaitTimeMS: 100 + timeoutMS: 200 + saveResultAsEntity: &tailableCursor tailableCursor + - name: iterateOnce + object: *tailableCursor + - name: iterateUntilDocumentOrError + object: *tailableCursor + expectError: + isTimeoutError: true + expectEvents: + - client: *client + ignoreExtraEvents: true + events: + - commandStartedEvent: + commandName: find + databaseName: *databaseName + - commandStartedEvent: + commandName: getMore + databaseName: *databaseName + command: + maxTimeMS: { $$lte: 100 } + - commandStartedEvent: + commandName: getMore + databaseName: *databaseName + command: + maxTimeMS: { $$lte: 70 } + + - description: "apply maxAwaitTimeMS if less than remaining timeout" + operations: + - name: createFindCursor + object: *collection + arguments: + filter: {} + cursorType: tailableAwait + batchSize: 1 + maxAwaitTimeMS: 100 + timeoutMS: 200 + saveResultAsEntity: &tailableCursor tailableCursor + # Iterate twice to force a getMore. + - name: iterateOnce + object: *tailableCursor + - name: iterateOnce + object: *tailableCursor + expectEvents: + - client: *client + events: + - commandStartedEvent: + commandName: find + databaseName: *databaseName + - commandStartedEvent: + commandName: getMore + databaseName: *databaseName + command: + maxTimeMS: { $$lte: 100 }