Skip to content

Commit 27af289

Browse files
committed
test(NODE-7418): clarify expected timeout refresh behavior for change streams when CSOT is enabled
1 parent e5a85d0 commit 27af289

2 files changed

Lines changed: 55 additions & 35 deletions

File tree

test/spec/client-side-operations-timeout/change-streams.json

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@
404404
]
405405
},
406406
{
407-
"description": "change stream can be iterated again if previous iteration times out",
407+
"description": "change stream iteration succeeds after a timeout error",
408408
"operations": [
409409
{
410410
"name": "createChangeStream",
@@ -443,6 +443,26 @@
443443
"isTimeoutError": true
444444
}
445445
},
446+
{
447+
"name": "failPoint",
448+
"object": "testRunner",
449+
"arguments": {
450+
"client": "failPointClient",
451+
"failPoint": {
452+
"configureFailPoint": "failCommand",
453+
"mode": {
454+
"times": 1
455+
},
456+
"data": {
457+
"failCommands": [
458+
"aggregate"
459+
],
460+
"blockConnection": true,
461+
"blockTimeMS": 150
462+
}
463+
}
464+
}
465+
},
446466
{
447467
"name": "iterateOnce",
448468
"object": "changeStream"
@@ -496,21 +516,6 @@
496516
}
497517
}
498518
}
499-
},
500-
{
501-
"commandStartedEvent": {
502-
"commandName": "getMore",
503-
"databaseName": "test",
504-
"command": {
505-
"getMore": {
506-
"$$type": [
507-
"int",
508-
"long"
509-
]
510-
},
511-
"collection": "coll"
512-
}
513-
}
514519
}
515520
]
516521
}

test/spec/client-side-operations-timeout/change-streams.yml

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ tests:
8484
command:
8585
aggregate: *collectionName
8686
maxTimeMS: { $$type: ["int", "long"] }
87-
87+
8888
# If maxAwaitTimeMS is not set, timeoutMS should be refreshed for the getMore and the getMore should not have a
8989
# maxTimeMS field. This test requires a high timeout because the server applies a default 1000ms maxAwaitTime. To
9090
# ensure that the driver is refreshing the timeout between commands, the test blocks aggregate and getMore commands
@@ -170,10 +170,8 @@ tests:
170170
collection: *collectionName
171171
maxTimeMS: 1
172172

173-
# The timeout should be applied to the entire resume attempt, not individually to each command. The test creates a
174-
# change stream with timeoutMS=200 which returns an empty initial batch and then sets a fail point to block both
175-
# getMore and aggregate for 120ms each and fail with a resumable error. When the resume attempt happens, the getMore
176-
# and aggregate block for longer than 200ms total, so it times out.
173+
# If a resume is required for a next call on a change stream, the timeout MUST apply to the entirety of the initial
174+
# getMore and all commands sent as part of the resume attempt.
177175
- description: "timeoutMS applies to full resume attempt in a next call"
178176
operations:
179177
- name: createChangeStream
@@ -225,7 +223,14 @@ tests:
225223
aggregate: *collectionName
226224
maxTimeMS: { $$type: ["int", "long"] }
227225

228-
- description: "change stream can be iterated again if previous iteration times out"
226+
# [resumption] If a next call fails with a timeout error, drivers MUST NOT
227+
# invalidate the change stream. The subsequent next call MUST perform a resume
228+
# attempt to establish a new change stream on the server.
229+
#
230+
# [refresh] If a resume is required for a next call on a change stream, the
231+
# timeout MUST apply to the entirety of the initial getMore and all commands
232+
# sent as part of the resume attempt.
233+
- description: "change stream iteration succeeds after a timeout error"
229234
operations:
230235
- name: createChangeStream
231236
object: *collection
@@ -248,14 +253,27 @@ tests:
248253
failCommands: ["getMore"]
249254
blockConnection: true
250255
blockTimeMS: 250
251-
# The original aggregate didn't return any events so this should do a getMore and return a timeout error.
256+
# Iterate until timeout.
252257
- name: iterateUntilDocumentOrError
253258
object: *changeStream
254259
expectError:
255260
isTimeoutError: true
256-
# The previous iteration attempt timed out so this should re-create the change stream. We use iterateOnce rather
257-
# than iterateUntilDocumentOrError because there haven't been any events and we only want to assert that the
258-
# cursor was re-created.
261+
# Block the resume aggregate for 150ms. If the timeout were exhausted from
262+
# the previous call, this would fail immediately. With a fresh 200ms
263+
# timeout, the 150ms delay should be acceptable.
264+
- name: failPoint
265+
object: testRunner
266+
arguments:
267+
client: *failPointClient
268+
failPoint:
269+
configureFailPoint: failCommand
270+
mode: { times: 1 }
271+
data:
272+
failCommands: ["aggregate"]
273+
blockConnection: true
274+
blockTimeMS: 150
275+
# A final iteration should succeed because the timeout is refreshed and
276+
# the change stream was not invalidated.
259277
- name: iterateOnce
260278
object: *changeStream
261279
expectEvents:
@@ -267,27 +285,24 @@ tests:
267285
command:
268286
aggregate: *collectionName
269287
maxTimeMS: { $$type: ["int", "long"] }
270-
# The iterateUntilDocumentOrError operation should send a getMore.
288+
# The first iterateUntilDocumentOrError sends a getMore that times
289+
# out.
271290
- commandStartedEvent:
272291
commandName: getMore
273292
databaseName: *databaseName
274293
command:
275294
getMore: { $$type: ["int", "long"] }
276295
collection: *collectionName
277-
# The iterateOnce operation should re-create the cursor via an aggregate and then send a getMore to iterate
278-
# the new cursor.
296+
# The iterateOnce operation re-creates the cursor via an aggregate
297+
# [resumption]. The aggregate is blocked for 150ms but succeeds
298+
# because the timeout was refreshed to a fresh 200ms, proving the
299+
# timeout is not shared with the previous timed-out call [refresh].
279300
- commandStartedEvent:
280301
commandName: aggregate
281302
databaseName: *databaseName
282303
command:
283304
aggregate: *collectionName
284305
maxTimeMS: { $$type: ["int", "long"] }
285-
- commandStartedEvent:
286-
commandName: getMore
287-
databaseName: *databaseName
288-
command:
289-
getMore: { $$type: ["int", "long"] }
290-
collection: *collectionName
291306

292307
# The timeoutMS value should be refreshed for getMore's. This is a failure test. The createChangeStream operation
293308
# sets timeoutMS=200 and the getMore blocks for 250ms, causing iteration to fail with a timeout error.

0 commit comments

Comments
 (0)