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