Skip to content

Commit 063440c

Browse files
CSHARP-2552: Ensure that getMore right after a resume is retried.
1 parent 6904bc0 commit 063440c

File tree

5 files changed

+154
-14
lines changed

5 files changed

+154
-14
lines changed

tests/MongoDB.Driver.Tests/Specifications/change-streams/ChangeStreamTestRunner.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
using System;
1717
using System.Collections.Generic;
1818
using System.Linq;
19+
using System.Threading;
1920
using FluentAssertions;
2021
using MongoDB.Bson;
2122
using MongoDB.Bson.TestHelpers.JsonDrivenTests;
2223
using MongoDB.Driver.Core;
24+
using MongoDB.Driver.Core.Bindings;
2325
using MongoDB.Driver.Core.Clusters;
26+
using MongoDB.Driver.Core.Clusters.ServerSelectors;
2427
using MongoDB.Driver.Core.Events;
28+
using MongoDB.Driver.Core.TestHelpers;
2529
using MongoDB.Driver.Core.TestHelpers.JsonDrivenTests;
2630
using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
2731
using MongoDB.Driver.TestHelpers;
@@ -50,7 +54,7 @@ public void Run(JsonDrivenTestCase testCase)
5054
private void Run(BsonDocument shared, BsonDocument test)
5155
{
5256
JsonDrivenHelper.EnsureAllFieldsAreValid(shared, "_path", "database_name", "database2_name", "collection_name", "collection2_name", "tests");
53-
JsonDrivenHelper.EnsureAllFieldsAreValid(test, "description", "minServerVersion", "topology", "target", "changeStreamPipeline", "changeStreamOptions", "operations", "expectations", "result", "async");
57+
JsonDrivenHelper.EnsureAllFieldsAreValid(test, "description", "minServerVersion", "topology", "target", "changeStreamPipeline", "changeStreamOptions", "operations", "expectations", "result", "async", "failPoint");
5458

5559
if (test.Contains("minServerVersion"))
5660
{
@@ -76,6 +80,7 @@ private void Run(BsonDocument shared, BsonDocument test)
7680
List<CommandStartedEvent> actualEvents = null;
7781

7882
var eventCapturer = CreateEventCapturer();
83+
using (ConfigureFailPoint(test))
7984
using (var client = CreateDisposableClient(eventCapturer))
8085
{
8186
try
@@ -110,6 +115,20 @@ private void Run(BsonDocument shared, BsonDocument test)
110115
}
111116

112117
// private methods
118+
private FailPoint ConfigureFailPoint(BsonDocument test)
119+
{
120+
if (test.TryGetValue("failPoint", out var failPoint))
121+
{
122+
var cluster = DriverTestConfiguration.Client.Cluster;
123+
var server = cluster.SelectServer(WritableServerSelector.Instance, CancellationToken.None);
124+
var session = NoCoreSession.NewHandle();
125+
var command = failPoint.AsBsonDocument;
126+
return FailPoint.Configure(cluster, session, command);
127+
}
128+
129+
return null;
130+
}
131+
113132
private ClusterType[] MapTopologyToClusterTypes(BsonArray topologies)
114133
{
115134
var clusterTypes = new List<ClusterType>();
@@ -132,7 +151,12 @@ private ChangeStreamOptions ParseChangeStreamOptions(BsonDocument document)
132151

133152
foreach (var element in document)
134153
{
135-
throw new FormatException($"Invalid change stream option: \"{element.Name}\".");
154+
switch (element.Name)
155+
{
156+
case "batchSize": options.BatchSize = element.Value.ToInt32(); break;
157+
default:
158+
throw new FormatException($"Invalid change stream option: \"{element.Name}\".");
159+
}
136160
}
137161

138162
return options;
@@ -304,7 +328,8 @@ private void AssertEvents(List<CommandStartedEvent> actualEvents, List<BsonDocum
304328

305329
if (actualEvents.Count > expectedEvents.Count)
306330
{
307-
throw new Exception($"Unexpected command started event: {actualEvents[n].CommandName}.");
331+
// the tests assume that a number of actual events can be bigger than expected.
332+
// So, skip this asserting
308333
}
309334
}
310335

tests/MongoDB.Driver.Tests/Specifications/change-streams/tests/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ The following tests have not yet been automated, but MUST still be tested. All t
153153

154154
1. ``ChangeStream`` must continuously track the last seen ``resumeToken``
155155
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. ``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``.
157-
4. ``ChangeStream`` will not attempt to resume on any error encountered while executing an ``aggregate`` command.
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.
158158
5. ``ChangeStream`` will not attempt to resume after encountering error code 11601 (Interrupted), 136 (CappedPositionLost), or 237 (CursorKilled) while executing a ``getMore`` command.
159159
6. ``ChangeStream`` will perform server selection before attempting to resume, using initial ``readPreference``
160160
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.

tests/MongoDB.Driver.Tests/Specifications/change-streams/tests/change-streams-errors.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ tests:
4242
cursor: {}
4343
pipeline:
4444
-
45-
$changeStream:
45+
$changeStream: {}
4646
-
4747
$unsupported: foo
4848
command_name: aggregate

tests/MongoDB.Driver.Tests/Specifications/change-streams/tests/change-streams.json

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,121 @@
675675
}
676676
]
677677
}
678+
},
679+
{
680+
"description": "Test consecutive resume",
681+
"minServerVersion": "4.1.7",
682+
"target": "collection",
683+
"topology": [
684+
"replicaset"
685+
],
686+
"changeStreamPipeline": [],
687+
"changeStreamOptions": {
688+
"batchSize": 1
689+
},
690+
"failPoint": {
691+
"configureFailPoint": "failCommand",
692+
"mode": {
693+
"times": 2
694+
},
695+
"data": {
696+
"failCommands": [
697+
"getMore"
698+
],
699+
"closeConnection": true
700+
}
701+
},
702+
"operations": [
703+
{
704+
"database": "change-stream-tests",
705+
"collection": "test",
706+
"name": "insertOne",
707+
"arguments": {
708+
"document": {
709+
"x": 1
710+
}
711+
}
712+
},
713+
{
714+
"database": "change-stream-tests",
715+
"collection": "test",
716+
"name": "insertOne",
717+
"arguments": {
718+
"document": {
719+
"x": 2
720+
}
721+
}
722+
},
723+
{
724+
"database": "change-stream-tests",
725+
"collection": "test",
726+
"name": "insertOne",
727+
"arguments": {
728+
"document": {
729+
"x": 3
730+
}
731+
}
732+
}
733+
],
734+
"expectations": [
735+
{
736+
"command_started_event": {
737+
"command": {
738+
"aggregate": "test",
739+
"cursor": {
740+
"batchSize": 1
741+
},
742+
"pipeline": [
743+
{
744+
"$changeStream": {}
745+
}
746+
]
747+
},
748+
"command_name": "aggregate",
749+
"database_name": "change-stream-tests"
750+
}
751+
}
752+
],
753+
"result": {
754+
"success": [
755+
{
756+
"operationType": "insert",
757+
"ns": {
758+
"db": "change-stream-tests",
759+
"coll": "test"
760+
},
761+
"fullDocument": {
762+
"x": {
763+
"$numberInt": "1"
764+
}
765+
}
766+
},
767+
{
768+
"operationType": "insert",
769+
"ns": {
770+
"db": "change-stream-tests",
771+
"coll": "test"
772+
},
773+
"fullDocument": {
774+
"x": {
775+
"$numberInt": "2"
776+
}
777+
}
778+
},
779+
{
780+
"operationType": "insert",
781+
"ns": {
782+
"db": "change-stream-tests",
783+
"coll": "test"
784+
},
785+
"fullDocument": {
786+
"x": {
787+
"$numberInt": "3"
788+
}
789+
}
790+
}
791+
]
792+
}
678793
}
679794
]
680795
}

tests/MongoDB.Driver.Tests/Specifications/change-streams/tests/change-streams.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ tests:
2727
cursor: {}
2828
pipeline:
2929
-
30-
$changeStream:
30+
$changeStream: {}
3131
command_name: aggregate
3232
database_name: *database_name
3333
result:
@@ -109,7 +109,7 @@ tests:
109109
cursor: {}
110110
pipeline:
111111
-
112-
$changeStream:
112+
$changeStream: {}
113113
command_name: aggregate
114114
database_name: *database_name
115115
result:
@@ -156,7 +156,7 @@ tests:
156156
cursor: {}
157157
pipeline:
158158
-
159-
$changeStream:
159+
$changeStream: {}
160160
-
161161
$match:
162162
"fullDocument.z":
@@ -212,7 +212,7 @@ tests:
212212
cursor: {}
213213
pipeline:
214214
-
215-
$changeStream:
215+
$changeStream: {}
216216
command_name: aggregate
217217
database_name: *database_name
218218
result:
@@ -352,7 +352,7 @@ tests:
352352
cursor: {}
353353
pipeline:
354354
-
355-
$changeStream:
355+
$changeStream: {}
356356
command_name: aggregate
357357
database_name: *database_name
358358
result:
@@ -410,7 +410,7 @@ tests:
410410
cursor: {}
411411
pipeline:
412412
-
413-
$changeStream:
413+
$changeStream: {}
414414
command_name: aggregate
415415
database_name: *database_name
416416
result:
@@ -446,7 +446,7 @@ tests:
446446
cursor: {}
447447
pipeline:
448448
-
449-
$changeStream:
449+
$changeStream: {}
450450
command_name: aggregate
451451
database_name: *database_name
452452
result:
@@ -504,7 +504,7 @@ tests:
504504
cursor: {batchSize: 1}
505505
pipeline:
506506
-
507-
$changeStream:
507+
$changeStream: {}
508508
command_name: aggregate
509509
database_name: *database_name
510510
result:

0 commit comments

Comments
 (0)