Skip to content

Commit 50627c9

Browse files
committed
CXX-1685 Retryable Reads
1 parent c9b5d31 commit 50627c9

File tree

244 files changed

+31393
-6129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

244 files changed

+31393
-6129
lines changed

data/change_stream/README.rst

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Each YAML file has the following keys:
3333
- ``description``: The name of the test.
3434
- ``minServerVersion``: The minimum server version to run this test against. If not present, assume there is no minimum server version.
3535
- ``maxServerVersion``: Reserved for later use
36-
- ``failPoint``: Reserved for later use
36+
- ``failPoint``(optional): The configureFailPoint command document to run to configure a fail point on the primary server.
3737
- ``target``: The entity on which to run the change stream. Valid values are:
3838

3939
- ``collection``: Watch changes on collection ``database_name.collection_name``
@@ -48,7 +48,7 @@ Each YAML file has the following keys:
4848
- ``database``: Database against which to run the operation
4949
- ``collection``: Collection against which to run the operation
5050
- ``name``: Name of the command to run
51-
- ``arguments``: Object of arguments for the command (ex: document to insert)
51+
- ``arguments`` (optional): Object of arguments for the command (ex: document to insert)
5252

5353
- ``expectations``: Optional list of command-started events in Extended JSON format
5454
- ``result``: Document with ONE of the following fields:
@@ -104,26 +104,26 @@ For each YAML file, for each element in ``tests``:
104104
- Drop the database ``database2_name``
105105
- Create the database ``database_name`` and the collection ``database_name.collection_name``
106106
- Create the database ``database2_name`` and the collection ``database2_name.collection2_name``
107+
- If the the ``failPoint`` field is present, configure the fail point on the primary server. See
108+
`Server Fail Point <../../transactions/tests#server-fail-point>`_ in the
109+
Transactions spec test documentation for more information.
107110

108111
- Create a new MongoClient ``client``
109112
- Begin monitoring all APM events for ``client``. (If the driver uses global listeners, filter out all events that do not originate with ``client``). Filter out any "internal" commands (e.g. ``isMaster``)
110-
- Using ``client``, create a changeStream ``changeStream`` against the specified ``target``. Use ``changeStreamPipeline`` and ``changeStreamOptions`` if they are non-empty
111-
- Using ``globalClient``, run every operation in ``operations`` in serial against the server
112-
- Wait until either:
113-
114-
- An error occurs
115-
- All operations have been successful AND the changeStream has received as many changes as there are in ``result.success``
116-
113+
- Using ``client``, create a changeStream ``changeStream`` against the specified ``target``. Use ``changeStreamPipeline`` and ``changeStreamOptions`` if they are non-empty. Capture any error.
114+
- If there was no error, use ``globalClient`` and run every operation in ``operations`` in serial against the server until all operations have been executed or an error is thrown. Capture any error.
115+
- If there was no error and ``result.error`` is set, iterate ``changeStream`` once and capture any error.
116+
- If there was no error and ``result.success`` is non-empty, iterate ``changeStream`` until it returns as many changes as there are elements in the ``result.success`` array or an error is thrown. Capture any error.
117117
- Close ``changeStream``
118118
- If there was an error:
119119

120120
- Assert that an error was expected for the test.
121-
- Assert that the error MATCHES ``results.error``
121+
- Assert that the error MATCHES ``result.error``
122122

123123
- Else:
124124

125125
- Assert that no error was expected for the test
126-
- Assert that the changes received from ``changeStream`` MATCH the results in ``results.success``
126+
- Assert that the changes received from ``changeStream`` MATCH the results in ``result.success``
127127

128128
- If there are any ``expectations``
129129

@@ -139,19 +139,53 @@ After running all tests
139139
- Drop database ``database_name``
140140
- Drop database ``database2_name``
141141

142+
Iterating the Change Stream
143+
---------------------------
144+
145+
Although synchronous drivers must provide a [non-blocking mode of iteration](../change-streams.rst#not-blocking-on-iteration), asynchronous drivers may not have such a mechanism. Those drivers with only a blocking mode of iteration should be careful not to iterate the change stream unnecessarily, as doing so could cause the test runner to block indefinitely. For this reason, the test runner procedure above advises drivers to take a conservative approach to iteration.
146+
147+
If the test expects an error and one was not thrown by either creating the change stream or executing the test's operations, iterating the change stream once allows for an error to be thrown by a ``getMore`` command. If the test does not expect any error, the change stream should be iterated only until it returns as many result documents as are expected by the test.
142148

143149
Prose Tests
144150
===========
145151

146-
The following tests have not yet been automated, but MUST still be tested
147-
148-
#. ``ChangeStream`` must continuously track the last seen ``resumeToken``
149-
#. ``ChangeStream`` will throw an exception if the server response is missing the resume token
150-
#. ``ChangeStream`` will automatically resume one time on a resumable error (including `not master`) with the initial pipeline and options, except for the addition/update of a ``resumeToken``.
151-
#. ``ChangeStream`` will not attempt to resume on any error encountered while executing an ``aggregate`` command.
152-
#. ``ChangeStream`` will not attempt to resume after encountering error code 11601 (Interrupted), 136 (CappedPositionLost), or 237 (CursorKilled) while executing a ``getMore`` command.
153-
#. ``ChangeStream`` will perform server selection before attempting to resume, using initial ``readPreference``
154-
#. Ensure that a cursor returned from an aggregate command with a cursor id and an initial empty batch is not closed on the driver side.
155-
#. The ``killCursors`` command sent during the "Resume Process" must not be allowed to throw an exception.
156-
#. ``$changeStream`` stage for ``ChangeStream`` against a server ``>=4.0`` that has not received any results yet MUST include a ``startAtOperationTime`` option when resuming a changestream.
157-
#. ``ChangeStream`` will resume after a ``killCursors`` command is issued for its child cursor.
152+
The following tests have not yet been automated, but MUST still be tested. All tests SHOULD be run on both replica sets and sharded clusters unless otherwise specified:
153+
154+
1. ``ChangeStream`` must continuously track the last seen ``resumeToken``
155+
2. ``ChangeStream`` will throw an exception if the server response is missing the resume token (if wire version is < 8, this is a driver-side error; for 8+, this is a server-side error)
156+
3. After receiving a ``resumeToken``, ``ChangeStream`` will automatically resume one time on a resumable error with the initial pipeline and options, except for the addition/update of a ``resumeToken``.
157+
4. ``ChangeStream`` will not attempt to resume on any error encountered while executing an ``aggregate`` command. Note that retryable reads may retry ``aggregate`` commands. Drivers should be careful to distinguish retries from resume attempts. Alternatively, drivers may specify `retryReads=false` or avoid using a [retryable error](../../retryable-reads/retryable-reads.rst#retryable-error) for this test.
158+
5. ``ChangeStream`` will not attempt to resume after encountering error code 11601 (Interrupted), 136 (CappedPositionLost), or 237 (CursorKilled) while executing a ``getMore`` command.
159+
6. ``ChangeStream`` will perform server selection before attempting to resume, using initial ``readPreference``
160+
7. Ensure that a cursor returned from an aggregate command with a cursor id and an initial empty batch is not closed on the driver side.
161+
8. The ``killCursors`` command sent during the "Resume Process" must not be allowed to throw an exception.
162+
9. ``$changeStream`` stage for ``ChangeStream`` against a server ``>=4.0`` and ``<4.0.7`` that has not received any results yet MUST include a ``startAtOperationTime`` option when resuming a change stream.
163+
10. ``ChangeStream`` will resume after a ``killCursors`` command is issued for its child cursor.
164+
11. - For a ``ChangeStream`` under these conditions:
165+
- Running against a server ``>=4.0.7``.
166+
- The batch is empty or has been iterated to the last document.
167+
- Expected result:
168+
- ``getResumeToken`` must return the ``postBatchResumeToken`` from the current command response.
169+
12. - For a ``ChangeStream`` under these conditions:
170+
- Running against a server ``<4.0.7``.
171+
- The batch is empty or has been iterated to the last document.
172+
- Expected result:
173+
- ``getResumeToken`` must return the ``_id`` of the last document returned if one exists.
174+
- ``getResumeToken`` must return ``resumeAfter`` from the initial aggregate if the option was specified.
175+
- If ``resumeAfter`` was not specified, the ``getResumeToken`` result must be empty.
176+
13. - For a ``ChangeStream`` under these conditions:
177+
- The batch is not empty.
178+
- The batch has been iterated up to but not including the last element.
179+
- Expected result:
180+
- ``getResumeToken`` must return the ``_id`` of the previous document returned.
181+
14. - For a ``ChangeStream`` under these conditions:
182+
- The batch is not empty.
183+
- The batch hasn’t been iterated at all.
184+
- Only the initial ``aggregate`` command has been executed.
185+
- Expected result:
186+
- ``getResumeToken`` must return ``startAfter`` from the initial aggregate if the option was specified.
187+
- ``getResumeToken`` must return ``resumeAfter`` from the initial aggregate if the option was specified.
188+
- If neither the ``startAfter`` nor ``resumeAfter`` options were specified, the ``getResumeToken`` result must be empty.
189+
- Note that this test cannot be run against sharded topologies because in that case the initial ``aggregate`` command only establishes cursors on the shards and always returns an empty ``firstBatch``.
190+
17. ``$changeStream`` stage for ``ChangeStream`` started with ``startAfter`` against a server ``>=4.1.1`` that has not received any results yet MUST include a ``startAfter`` option and MUST NOT include a ``resumeAfter`` option when resuming a change stream.
191+
18. ``$changeStream`` stage for ``ChangeStream`` started with ``startAfter`` against a server ``>=4.1.1`` that has received at least one result MUST include a ``resumeAfter`` option and MUST NOT include a ``startAfter`` option when resuming a change stream.

data/change_stream/change-streams-errors.json

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@
5454
"cursor": {},
5555
"pipeline": [
5656
{
57-
"$changeStream": {
58-
"fullDocument": "default"
59-
}
57+
"$changeStream": {}
6058
},
6159
{
6260
"$unsupported": "foo"
@@ -73,6 +71,43 @@
7371
"code": 40324
7472
}
7573
}
74+
},
75+
{
76+
"description": "Change Stream should error when _id is projected out",
77+
"minServerVersion": "4.1.11",
78+
"target": "collection",
79+
"topology": [
80+
"replicaset",
81+
"sharded"
82+
],
83+
"changeStreamPipeline": [
84+
{
85+
"$project": {
86+
"_id": 0
87+
}
88+
}
89+
],
90+
"changeStreamOptions": {},
91+
"operations": [
92+
{
93+
"database": "change-stream-tests",
94+
"collection": "test",
95+
"name": "insertOne",
96+
"arguments": {
97+
"document": {
98+
"z": 3
99+
}
100+
}
101+
}
102+
],
103+
"result": {
104+
"error": {
105+
"code": 280,
106+
"errorLabels": [
107+
"NonResumableChangeStreamError"
108+
]
109+
}
110+
}
76111
}
77112
]
78113
}

data/change_stream/change-streams-errors.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,34 @@ tests:
4242
cursor: {}
4343
pipeline:
4444
-
45-
$changeStream:
46-
fullDocument: default
45+
$changeStream: {}
4746
-
4847
$unsupported: foo
4948
command_name: aggregate
5049
database_name: *database_name
5150
result:
5251
error:
53-
code: 40324
52+
code: 40324
53+
-
54+
description: Change Stream should error when _id is projected out
55+
minServerVersion: "4.1.11"
56+
target: collection
57+
topology:
58+
- replicaset
59+
- sharded
60+
changeStreamPipeline:
61+
-
62+
$project: { _id: 0 }
63+
changeStreamOptions: {}
64+
operations:
65+
-
66+
database: *database_name
67+
collection: *collection_name
68+
name: insertOne
69+
arguments:
70+
document:
71+
z: 3
72+
result:
73+
error:
74+
code: 280
75+
errorLabels: [ "NonResumableChangeStreamError" ]

0 commit comments

Comments
 (0)