Skip to content

Commit c1a066e

Browse files
CSHARP-2569: Require retryable writes network error tests to run on mongos 4.2+.
1 parent 9a1d776 commit c1a066e

Some content is hidden

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

45 files changed

+781
-183
lines changed

tests/MongoDB.Driver.Tests/Specifications/retryable-writes/BulkWriteTest.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ protected override void ExecuteSync(IMongoCollection<BsonDocument> collection)
6565

6666
protected override void VerifyResult(BsonDocument result)
6767
{
68-
var expectedResult = ParseResult(result);
68+
var expectedResult = ParseResult(result, out var expectedInsertedIds);
69+
foreach (var insertedId in expectedInsertedIds)
70+
{
71+
var insertModel = (InsertOneModel<BsonDocument>)_result.ProcessedRequests[insertedId.Key];
72+
insertModel.Document["_id"].Should().Be(insertedId.Value);
73+
}
6974
_result.DeletedCount.Should().Be(expectedResult.DeletedCount);
7075
_result.InsertedCount.Should().Be(expectedResult.InsertedCount);
7176
_result.MatchedCount.Should().Be(expectedResult.MatchedCount);
@@ -180,12 +185,15 @@ private BulkWriteOptions ParseOptions(BsonDocument options)
180185
return result;
181186
}
182187

183-
private BulkWriteResult<BsonDocument> ParseResult(BsonDocument result)
188+
private BulkWriteResult<BsonDocument> ParseResult(BsonDocument result, out Dictionary<int, int> expectedInsertedIds)
184189
{
185190
VerifyFields(result, "deletedCount", "insertedCount", "insertedIds", "matchedCount", "modifiedCount", "upsertedCount", "upsertedIds");
186191

187192
var deletedCount = result["deletedCount"].ToInt64();
188-
var insertedCount = result["insertedIds"].AsBsonDocument.ElementCount; // TODO: anything to verify besides count?
193+
var insertedCount = result["insertedCount"].ToInt64();
194+
expectedInsertedIds = result["insertedIds"]
195+
.AsBsonDocument
196+
.ToDictionary(k => Convert.ToInt32(k.Name), v => v.Value.ToInt32());
189197
var matchedCount = result["matchedCount"].ToInt64();
190198
var modifiedCount = result["modifiedCount"].ToInt64();
191199
var processedRequests = new List<WriteModel<BsonDocument>>(_requests);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* Copyright 2019-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using FluentAssertions;
18+
using MongoDB.Bson;
19+
20+
namespace MongoDB.Driver.Tests.Specifications.retryable_writes
21+
{
22+
public class DeleteManyTest : RetryableWriteTestBase
23+
{
24+
// private fields
25+
private FilterDefinition<BsonDocument> _filter;
26+
private DeleteResult _result;
27+
28+
// public methods
29+
public override void Initialize(BsonDocument operation)
30+
{
31+
VerifyFields(operation, "name", "arguments");
32+
33+
foreach (var argument in operation["arguments"].AsBsonDocument)
34+
{
35+
switch (argument.Name)
36+
{
37+
case "filter":
38+
_filter = argument.Value.AsBsonDocument;
39+
break;
40+
41+
default:
42+
throw new ArgumentException($"Unexpected argument: {argument.Name}.");
43+
}
44+
}
45+
}
46+
47+
// protected methods
48+
protected override void ExecuteAsync(IMongoCollection<BsonDocument> collection)
49+
{
50+
_result = collection.DeleteManyAsync(_filter).GetAwaiter().GetResult();
51+
}
52+
53+
protected override void ExecuteSync(IMongoCollection<BsonDocument> collection)
54+
{
55+
_result = collection.DeleteMany(_filter);
56+
}
57+
58+
protected override void VerifyResult(BsonDocument result)
59+
{
60+
var expectedResult = ParseResult(result);
61+
_result.DeletedCount.Should().Be(expectedResult.DeletedCount);
62+
}
63+
64+
// private methods
65+
private DeleteResult ParseResult(BsonDocument result)
66+
{
67+
VerifyFields(result, "deletedCount");
68+
var deletedCount = result["deletedCount"].ToInt64();
69+
return new DeleteResult.Acknowledged(deletedCount);
70+
}
71+
}
72+
}

tests/MongoDB.Driver.Tests/Specifications/retryable-writes/RetryableWriteTestRunner.cs

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@
1919
using System.IO;
2020
using System.Linq;
2121
using System.Reflection;
22-
using System.Threading;
2322
using MongoDB.Bson;
24-
using MongoDB.Bson.TestHelpers.XunitExtensions;
25-
using MongoDB.Driver.Core.Clusters;
2623
using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
24+
using MongoDB.Driver.TestHelpers;
2725
using Xunit;
2826
using Xunit.Abstractions;
2927

@@ -44,7 +42,7 @@ public void RunTestDefinition(TestCase testCase)
4442
var async = testCase.Async;
4543

4644
VerifyServerRequirements(definition);
47-
VerifyFields(definition, "path", "data", "minServerVersion", "maxServerVersion", "tests");
45+
VerifyFields(definition, "path", "data", "runOn", "tests");
4846

4947
InitializeCollection(definition);
5048
RunTest(test, async);
@@ -53,23 +51,14 @@ public void RunTestDefinition(TestCase testCase)
5351
// private methods
5452
private void VerifyServerRequirements(BsonDocument definition)
5553
{
56-
RequireServer.Check().ClusterType(ClusterType.ReplicaSet);
57-
58-
if (CoreTestConfiguration.GetStorageEngine() == "mmapv1")
59-
{
60-
throw new SkipException("Test skipped because mmapv1 does not support retryable writes.");
61-
}
62-
63-
BsonValue minServerVersion;
64-
if (definition.TryGetValue("minServerVersion", out minServerVersion))
54+
if (definition.TryGetValue("runOn", out var runOn))
6555
{
66-
RequireServer.Check().VersionGreaterThanOrEqualTo(minServerVersion.AsString);
56+
RequireServer.Check().RunOn(runOn.AsBsonArray);
6757
}
6858

69-
BsonValue maxServerVersion;
70-
if (definition.TryGetValue("maxServerVersion", out maxServerVersion))
59+
if (CoreTestConfiguration.GetStorageEngine() == "mmapv1")
7160
{
72-
RequireServer.Check().VersionLessThanOrEqualTo(maxServerVersion.AsString);
61+
throw new SkipException("Test skipped because mmapv1 does not support retryable writes.");
7362
}
7463
}
7564

@@ -96,35 +85,41 @@ private void InitializeCollection(BsonDocument definition)
9685

9786
private void RunTest(BsonDocument test, bool async)
9887
{
99-
VerifyFields(test, "description", "clientOptions", "failPoint", "operation", "outcome");
100-
var clientOptions = (BsonDocument)test.GetValue("clientOptions", null);
88+
VerifyFields(test, "description", "clientOptions", "failPoint", "operation", "outcome", "useMultipleMongoses");
10189
var failPoint = (BsonDocument)test.GetValue("failPoint", null);
10290
var operation = test["operation"].AsBsonDocument;
10391
var outcome = test["outcome"].AsBsonDocument;
10492

105-
var client = CreateClient(clientOptions);
106-
var database = client.GetDatabase(_databaseName);
107-
var collection = database.GetCollection<BsonDocument>(_collectionName);
108-
var executableTest = CreateExecutableTest(operation);
109-
110-
using (ConfigureFailPoint(client, failPoint))
93+
using (var client = CreateDisposableClient(test))
11194
{
112-
executableTest.Execute(collection, async);
113-
}
95+
var database = client.GetDatabase(_databaseName);
96+
var collection = database.GetCollection<BsonDocument>(_collectionName);
97+
var executableTest = CreateExecutableTest(operation);
98+
99+
using (ConfigureFailPoint(client, failPoint))
100+
{
101+
executableTest.Execute(collection, async);
102+
}
114103

115-
executableTest.VerifyOutcome(collection, outcome);
104+
executableTest.VerifyOutcome(collection, outcome);
105+
}
116106
}
117107

118-
private IMongoClient CreateClient(BsonDocument clientOptions)
108+
private DisposableMongoClient CreateDisposableClient(BsonDocument test)
119109
{
120-
var clientSettings = ParseClientOptions(clientOptions);
121-
return new MongoClient(clientSettings);
110+
var useMultipleShardRouters = test.GetValue("useMultipleMongoses", false).AsBoolean;
111+
var clientOptions = (BsonDocument)test.GetValue("clientOptions", null);
112+
113+
return DriverTestConfiguration.CreateDisposableClient(
114+
settings =>
115+
{
116+
ParseClientOptions(settings, clientOptions);
117+
},
118+
useMultipleShardRouters);
122119
}
123120

124-
private MongoClientSettings ParseClientOptions(BsonDocument clientOptions)
121+
private void ParseClientOptions(MongoClientSettings settings, BsonDocument clientOptions)
125122
{
126-
var settings = DriverTestConfiguration.Client.Settings.Clone();
127-
128123
if (clientOptions == null)
129124
{
130125
settings.RetryWrites = true;
@@ -147,8 +142,6 @@ private MongoClientSettings ParseClientOptions(BsonDocument clientOptions)
147142
}
148143
}
149144
}
150-
151-
return settings;
152145
}
153146

154147
private IRetryableWriteTest CreateExecutableTest(BsonDocument operation)
@@ -160,13 +153,15 @@ private IRetryableWriteTest CreateExecutableTest(BsonDocument operation)
160153
{
161154
case "bulkWrite": executableTest = new BulkWriteTest(); break;
162155
case "deleteOne": executableTest = new DeleteOneTest(); break;
156+
case "deleteMany": executableTest = new DeleteManyTest(); break;
163157
case "findOneAndDelete": executableTest = new FindOneAndDeleteTest(); break;
164158
case "findOneAndReplace": executableTest = new FindOneAndReplaceTest(); break;
165159
case "findOneAndUpdate": executableTest = new FindOneAndUpdateTest(); break;
166160
case "insertOne": executableTest = new InsertOneTest(); break;
167161
case "insertMany": executableTest = new InsertManyTest(); break;
168162
case "replaceOne": executableTest = new ReplaceOneTest(); break;
169163
case "updateOne": executableTest = new UpdateOneTest(); break;
164+
case "updateMany": executableTest = new UpdateManyTest(); break;
170165
default: throw new ArgumentException($"Unexpected operation name: {operationName}.");
171166
}
172167
executableTest.Initialize(operation);
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* Copyright 2019-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System;
17+
using FluentAssertions;
18+
using MongoDB.Bson;
19+
20+
namespace MongoDB.Driver.Tests.Specifications.retryable_writes
21+
{
22+
public class UpdateManyTest : RetryableWriteTestBase
23+
{
24+
private FilterDefinition<BsonDocument> _filter;
25+
private UpdateDefinition<BsonDocument> _update;
26+
private readonly UpdateOptions _options = new UpdateOptions();
27+
private UpdateResult _result;
28+
29+
// public methods
30+
public override void Initialize(BsonDocument operation)
31+
{
32+
VerifyFields(operation, "name", "arguments");
33+
34+
foreach (var argument in operation["arguments"].AsBsonDocument)
35+
{
36+
switch (argument.Name)
37+
{
38+
case "filter":
39+
_filter = argument.Value.AsBsonDocument;
40+
break;
41+
42+
case "update":
43+
_update = argument.Value.AsBsonDocument;
44+
break;
45+
46+
case "upsert":
47+
_options.IsUpsert = argument.Value.ToBoolean();
48+
break;
49+
50+
default:
51+
throw new ArgumentException($"Unexpected argument: {argument.Name}.");
52+
}
53+
}
54+
}
55+
56+
// protected methods
57+
protected override void ExecuteAsync(IMongoCollection<BsonDocument> collection)
58+
{
59+
_result = collection.UpdateManyAsync(_filter, _update, _options).GetAwaiter().GetResult();
60+
}
61+
62+
protected override void ExecuteSync(IMongoCollection<BsonDocument> collection)
63+
{
64+
_result = collection.UpdateMany(_filter, _update, _options);
65+
}
66+
67+
protected override void VerifyResult(BsonDocument result)
68+
{
69+
var expectedResult = ParseResult(result);
70+
_result.MatchedCount.Should().Be(expectedResult.MatchedCount);
71+
_result.ModifiedCount.Should().Be(expectedResult.ModifiedCount);
72+
_result.UpsertedId.Should().Be(expectedResult.UpsertedId);
73+
}
74+
75+
// private methods
76+
private UpdateResult ParseResult(BsonDocument result)
77+
{
78+
VerifyFields(result, "matchedCount", "modifiedCount", "upsertedCount", "upsertedId");
79+
80+
var matchedCount = result["matchedCount"].ToInt64();
81+
var modifiedCount = result["modifiedCount"].ToInt64();
82+
var upsertedCount = result["upsertedCount"].ToInt32();
83+
var upsertedId = result.GetValue("upsertedId", null);
84+
upsertedCount.Should().Be(upsertedId == null ? 0 : 1);
85+
86+
return new UpdateResult.Acknowledged(matchedCount, modifiedCount, upsertedId);
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)