Skip to content

Commit 5f7f4f8

Browse files
committed
CSHARP-4108: Inherited comment causes OperationFailure on MongoDB <4.4.0 (#766)
1 parent cb379d5 commit 5f7f4f8

File tree

9 files changed

+663
-43
lines changed

9 files changed

+663
-43
lines changed

src/MongoDB.Driver.Core/Core/Misc/Feature.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public class Feature
6969
private static readonly Feature __findAndModifyWriteConcern = new Feature("FindAndModifyWriteConcern", WireVersion.Server32);
7070
private static readonly Feature __findCommand = new Feature("FindCommand", WireVersion.Server32);
7171
private static readonly Feature __geoNearCommand = new Feature("GeoNearCommand", WireVersion.Zero, WireVersion.Server42);
72+
private static readonly Feature __getMoreComment = new Feature("GetMoreComment", WireVersion.Server44);
7273
private static readonly Feature __groupCommand = new Feature("GroupCommand", WireVersion.Zero, WireVersion.Server42);
7374
private static readonly Feature __hedgedReads = new Feature("HedgedReads", WireVersion.Server44);
7475
private static readonly Feature __hiddenIndex = new Feature("HiddenIndex", WireVersion.Server44);
@@ -368,6 +369,11 @@ public class Feature
368369
/// </summary>
369370
public static Feature GeoNearCommand => __geoNearCommand;
370371

372+
/// <summary>
373+
/// Gets the getMore comment feature.
374+
/// </summary>
375+
public static Feature GetMoreComment => __getMoreComment;
376+
371377
/// <summary>
372378
/// Gets the group command feature.
373379
/// </summary>

src/MongoDB.Driver.Core/Core/Operations/AsyncCursor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,15 @@ private CursorBatch<TDocument> CreateCursorBatch(BsonDocument result)
327327
}
328328
}
329329

330-
private BsonDocument CreateGetMoreCommand()
330+
private BsonDocument CreateGetMoreCommand(ConnectionDescription connectionDescription)
331331
{
332332
var command = new BsonDocument
333333
{
334334
{ "getMore", _cursorId },
335335
{ "collection", _collectionNamespace.CollectionName },
336336
{ "batchSize", () => CalculateGetMoreNumberToReturn(), _batchSize > 0 || _limit > 0 },
337337
{ "maxTimeMS", () => MaxTimeHelper.ToMaxTimeMS(_maxTime.Value), _maxTime.HasValue },
338-
{ "comment", _comment, _comment != null },
338+
{ "comment", _comment, _comment != null && Feature.GetMoreComment.IsSupported(connectionDescription.MaxWireVersion) },
339339
};
340340

341341
return command;
@@ -354,7 +354,7 @@ private BsonDocument CreateKillCursorsCommand()
354354

355355
private CursorBatch<TDocument> ExecuteGetMoreCommand(IChannelHandle channel, CancellationToken cancellationToken)
356356
{
357-
var command = CreateGetMoreCommand();
357+
var command = CreateGetMoreCommand(channel.ConnectionDescription);
358358
BsonDocument result;
359359
try
360360
{
@@ -382,7 +382,7 @@ private CursorBatch<TDocument> ExecuteGetMoreCommand(IChannelHandle channel, Can
382382

383383
private async Task<CursorBatch<TDocument>> ExecuteGetMoreCommandAsync(IChannelHandle channel, CancellationToken cancellationToken)
384384
{
385-
var command = CreateGetMoreCommand();
385+
var command = CreateGetMoreCommand(channel.ConnectionDescription);
386386
BsonDocument result;
387387
try
388388
{

tests/MongoDB.Driver.Core.Tests/Core/Operations/AsyncCursorTests.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ public void CreateGetMoreCommand_should_return_expected_result()
268268
{
269269
var subject = CreateSubject();
270270

271-
var result = subject.CreateGetMoreCommand();
271+
var result = subject.CreateGetMoreCommand(CreateConnectionDescriptionSupportingSession());
272272

273273
result.Should().Be("{ getMore : 0, collection : \"test\" }");
274274
}
@@ -278,7 +278,27 @@ public void CreateGetMoreCommand_should_return_expected_result_when_batchSize_is
278278
{
279279
var subject = CreateSubject(batchSize: 2);
280280

281-
var result = subject.CreateGetMoreCommand();
281+
var result = subject.CreateGetMoreCommand(CreateConnectionDescriptionSupportingSession());
282+
283+
result.Should().Be("{ getMore : 0, collection : \"test\", batchSize : 2 }");
284+
}
285+
286+
[Fact]
287+
public void CreateGetMoreCommand_should_include_comment_on_4_4_server_version()
288+
{
289+
var subject = CreateSubject(batchSize: 2, comment: "comment");
290+
291+
var result = subject.CreateGetMoreCommand(CreateConnectionDescriptionSupportingSession(WireVersion.Server44));
292+
293+
result.Should().Be("{ getMore : 0, collection : \"test\", batchSize : 2, comment: \"comment\" }");
294+
}
295+
296+
[Fact]
297+
public void CreateGetMoreCommand_should_not_include_comment_on_pre_4_4_server_versions()
298+
{
299+
var subject = CreateSubject(batchSize: 2, comment: "comment");
300+
301+
var result = subject.CreateGetMoreCommand(CreateConnectionDescriptionSupportingSession(WireVersion.Server42));
282302

283303
result.Should().Be("{ getMore : 0, collection : \"test\", batchSize : 2 }");
284304
}
@@ -288,7 +308,7 @@ public void CreateGetMoreCommand_should_return_expected_result_when_maxTime_is_p
288308
{
289309
var subject = CreateSubject(maxTime: TimeSpan.FromSeconds(2));
290310

291-
var result = subject.CreateGetMoreCommand();
311+
var result = subject.CreateGetMoreCommand(CreateConnectionDescriptionSupportingSession());
292312

293313
result.Should().Be("{ getMore : 0, collection : \"test\", maxTimeMS : 2000 }");
294314
}
@@ -492,12 +512,13 @@ private AsyncCursor<BsonDocument> CreateSubject(
492512
Optional<long> cursorId = default(Optional<long>),
493513
Optional<int?> batchSize = default(Optional<int?>),
494514
Optional<int?> limit = default(Optional<int?>),
495-
Optional<TimeSpan?> maxTime = default(Optional<TimeSpan?>))
515+
Optional<TimeSpan?> maxTime = default(Optional<TimeSpan?>),
516+
Optional<string> comment = default(Optional<string>))
496517
{
497518
return new AsyncCursor<BsonDocument>(
498519
channelSource.WithDefault(new Mock<IChannelSource>().Object),
499520
collectionNamespace.WithDefault(new CollectionNamespace("test", "test")),
500-
comment: null,
521+
comment: comment.WithDefault(null),
501522
firstBatch.WithDefault(new List<BsonDocument>()),
502523
cursorId.WithDefault(0),
503524
batchSize.WithDefault(null),
@@ -760,7 +781,7 @@ public static class AsyncCursorReflector
760781
public static IBsonSerializer<BsonDocument> _serializer(this AsyncCursor<BsonDocument> obj) => (IBsonSerializer<BsonDocument>)Reflector.GetFieldValue(obj, nameof(_serializer));
761782

762783
// private methods
763-
public static BsonDocument CreateGetMoreCommand(this AsyncCursor<BsonDocument> obj) => (BsonDocument)Reflector.Invoke(obj, nameof(CreateGetMoreCommand));
784+
public static BsonDocument CreateGetMoreCommand(this AsyncCursor<BsonDocument> obj, ConnectionDescription connectionDescription) => (BsonDocument)Reflector.Invoke(obj, nameof(CreateGetMoreCommand), connectionDescription);
764785
public static BsonDocument CreateKillCursorsCommand(this AsyncCursor<BsonDocument> obj) => (BsonDocument)Reflector.Invoke(obj, nameof(CreateKillCursorsCommand));
765786
}
766787
}

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

Lines changed: 94 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@
167167
"description": "Test with document comment - pre 4.4",
168168
"runOnRequirements": [
169169
{
170-
"minServerVersion": "3.6.0",
171170
"maxServerVersion": "4.2.99"
172171
}
173172
],
@@ -211,11 +210,6 @@
211210
},
212211
{
213212
"description": "Test with string comment",
214-
"runOnRequirements": [
215-
{
216-
"minServerVersion": "3.6.0"
217-
}
218-
],
219213
"operations": [
220214
{
221215
"name": "createChangeStream",
@@ -254,7 +248,97 @@
254248
{
255249
"minServerVersion": "4.4.0",
256250
"topologies": [
257-
"single",
251+
"replicaset"
252+
]
253+
}
254+
],
255+
"operations": [
256+
{
257+
"name": "createChangeStream",
258+
"object": "collection0",
259+
"arguments": {
260+
"pipeline": [],
261+
"comment": {
262+
"key": "value"
263+
}
264+
},
265+
"saveResultAsEntity": "changeStream0"
266+
},
267+
{
268+
"name": "insertOne",
269+
"object": "collection0",
270+
"arguments": {
271+
"document": {
272+
"_id": 1,
273+
"a": 1
274+
}
275+
}
276+
},
277+
{
278+
"name": "iterateUntilDocumentOrError",
279+
"object": "changeStream0"
280+
}
281+
],
282+
"expectEvents": [
283+
{
284+
"client": "client0",
285+
"events": [
286+
{
287+
"commandStartedEvent": {
288+
"command": {
289+
"aggregate": "collection0",
290+
"pipeline": [
291+
{
292+
"$changeStream": {}
293+
}
294+
],
295+
"comment": {
296+
"key": "value"
297+
}
298+
}
299+
}
300+
},
301+
{
302+
"commandStartedEvent": {
303+
"command": {
304+
"insert": "collection0",
305+
"documents": [
306+
{
307+
"_id": 1,
308+
"a": 1
309+
}
310+
]
311+
}
312+
}
313+
},
314+
{
315+
"commandStartedEvent": {
316+
"command": {
317+
"getMore": {
318+
"$$type": [
319+
"int",
320+
"long"
321+
]
322+
},
323+
"collection": "collection0",
324+
"comment": {
325+
"key": "value"
326+
}
327+
},
328+
"commandName": "getMore",
329+
"databaseName": "database0"
330+
}
331+
}
332+
]
333+
}
334+
]
335+
},
336+
{
337+
"description": "Test that comment is not set on getMore - pre 4.4",
338+
"runOnRequirements": [
339+
{
340+
"maxServerVersion": "4.3.99",
341+
"topologies": [
258342
"replicaset"
259343
]
260344
}
@@ -324,7 +408,9 @@
324408
]
325409
},
326410
"collection": "collection0",
327-
"comment": "comment"
411+
"comment": {
412+
"$$exists": false
413+
}
328414
},
329415
"commandName": "getMore",
330416
"databaseName": "database0"

0 commit comments

Comments
 (0)