Skip to content

Commit 73a3f4e

Browse files
CSHARP-2040: Test Driver Wire Version Overlap logic.
1 parent 4fc6a30 commit 73a3f4e

12 files changed

+427
-56
lines changed

tests/MongoDB.Driver.Core.Tests/Specifications/server-discovery-and-monitoring/TestRunner.cs

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@
1414
*/
1515

1616
using System;
17-
using System.Collections;
1817
using System.Collections.Generic;
19-
using System.IO;
2018
using System.Linq;
21-
using System.Reflection;
2219
using System.Threading;
2320
using FluentAssertions;
2421
using MongoDB.Bson;
2522
using MongoDB.Bson.TestHelpers;
23+
using MongoDB.Bson.TestHelpers.JsonDrivenTests;
2624
using MongoDB.Driver.Core.Clusters;
2725
using MongoDB.Driver.Core.Configuration;
2826
using MongoDB.Driver.Core.Connections;
@@ -43,9 +41,11 @@ public class TestRunner
4341

4442
[Theory]
4543
[ClassData(typeof(TestCaseFactory))]
46-
public void RunTestDefinition(BsonDocument definition)
44+
public void RunTestDefinition(JsonDrivenTestCase testCase)
4745
{
48-
VerifyFields(definition, "description", "path", "phases", "uri");
46+
var definition = testCase.Test;
47+
48+
JsonDrivenHelper.EnsureAllFieldsAreValid(definition, "description", "_path", "phases", "uri");
4949

5050
_cluster = BuildCluster(definition);
5151
_cluster.Initialize();
@@ -59,7 +59,7 @@ public void RunTestDefinition(BsonDocument definition)
5959

6060
private void ApplyPhase(BsonDocument phase)
6161
{
62-
VerifyFields(phase, "outcome", "responses");
62+
JsonDrivenHelper.EnsureAllFieldsAreValid(phase, "outcome", "responses");
6363

6464
var responses = phase["responses"].AsBsonArray;
6565
foreach (BsonArray response in responses)
@@ -80,7 +80,7 @@ private void ApplyResponse(BsonArray response)
8080

8181
var address = response[0].AsString;
8282
var isMasterDocument = response[1].AsBsonDocument;
83-
VerifyFields(isMasterDocument, "arbiterOnly", "arbiters", "electionId", "hidden", "hosts", "ismaster", "isreplicaset", "logicalSessionTimeoutMinutes", "maxWireVersion", "me", "minWireVersion", "msg", "ok", "passive", "passives", "primary", "secondary", "setName", "setVersion");
83+
JsonDrivenHelper.EnsureAllFieldsAreValid(isMasterDocument, "arbiterOnly", "arbiters", "electionId", "hidden", "hosts", "ismaster", "isreplicaset", "logicalSessionTimeoutMinutes", "maxWireVersion", "me", "minWireVersion", "msg", "ok", "passive", "passives", "primary", "secondary", "setName", "setVersion");
8484

8585
var endPoint = EndPointHelper.Parse(address);
8686
var isMasterResult = new IsMasterResult(isMasterDocument);
@@ -99,17 +99,6 @@ private void ApplyResponse(BsonArray response)
9999
SpinWait.SpinUntil(() => !object.ReferenceEquals(_cluster.Description, currentClusterDescription), 100); // sometimes returns false and that's OK
100100
}
101101

102-
private void VerifyFields(BsonDocument document, params string[] expectedNames)
103-
{
104-
foreach (var name in document.Names)
105-
{
106-
if (!expectedNames.Contains(name))
107-
{
108-
throw new FormatException($"Invalid field: \"{name}\".");
109-
}
110-
}
111-
}
112-
113102
private void VerifyTopology(ICluster cluster, string expectedType)
114103
{
115104
switch (expectedType)
@@ -141,7 +130,7 @@ private void VerifyTopology(ICluster cluster, string expectedType)
141130

142131
private void VerifyOutcome(BsonDocument outcome)
143132
{
144-
VerifyFields(outcome, "compatible", "logicalSessionTimeoutMinutes", "servers", "setName", "topologyType");
133+
JsonDrivenHelper.EnsureAllFieldsAreValid(outcome, "compatible", "logicalSessionTimeoutMinutes", "servers", "setName", "topologyType");
145134

146135
var expectedTopologyType = (string)outcome["topologyType"];
147136
VerifyTopology(_cluster, expectedTopologyType);
@@ -194,7 +183,7 @@ private void VerifyOutcome(BsonDocument outcome)
194183

195184
private void VerifyServerDescription(ServerDescription actualDescription, BsonDocument expectedDescription)
196185
{
197-
VerifyFields(expectedDescription, "electionId", "setName", "setVersion", "type");
186+
JsonDrivenHelper.EnsureAllFieldsAreValid(expectedDescription, "electionId", "setName", "setVersion", "type");
198187

199188
var expectedType = (string)expectedDescription["type"];
200189
switch (expectedType)
@@ -282,37 +271,19 @@ private ICluster BuildCluster(BsonDocument definition)
282271
.CreateCluster();
283272
}
284273

285-
private class TestCaseFactory : IEnumerable<object[]>
274+
private class TestCaseFactory : JsonDrivenTestCaseFactory
286275
{
287-
public IEnumerator<object[]> GetEnumerator()
288-
{
289-
const string prefix = "MongoDB.Driver.Core.Tests.Specifications.server_discovery_and_monitoring.tests.";
290-
const string monitoringPrefix = "MongoDB.Driver.Core.Tests.Specifications.server_discovery_and_monitoring.tests.monitoring.";
291-
var executingAssembly = typeof(TestCaseFactory).GetTypeInfo().Assembly;
292-
var enumerable = executingAssembly
293-
.GetManifestResourceNames()
294-
.Where(path => path.StartsWith(prefix) && path.EndsWith(".json"))
295-
.Where(path => !path.StartsWith(monitoringPrefix))
296-
.Select(path => ReadDefinition(path))
297-
.Select(definition => new object[] { definition });
298-
return enumerable.GetEnumerator();
299-
}
276+
private readonly string __ignoredTestFolder = "MongoDB.Driver.Core.Tests.Specifications.server_discovery_and_monitoring.tests.monitoring.";
300277

301-
IEnumerator IEnumerable.GetEnumerator()
302-
{
303-
return GetEnumerator();
304-
}
278+
protected override string PathPrefix => "MongoDB.Driver.Core.Tests.Specifications.server_discovery_and_monitoring.tests.";
305279

306-
private static BsonDocument ReadDefinition(string path)
280+
protected override IEnumerable<JsonDrivenTestCase> CreateTestCases(BsonDocument document)
307281
{
308-
var executingAssembly = typeof(TestCaseFactory).GetTypeInfo().Assembly;
309-
using (var definitionStream = executingAssembly.GetManifestResourceStream(path))
310-
using (var definitionStringReader = new StreamReader(definitionStream))
282+
var path = document["_path"].ToString();
283+
if (!path.StartsWith(__ignoredTestFolder))
311284
{
312-
var definitionString = definitionStringReader.ReadToEnd();
313-
var definition = BsonDocument.Parse(definitionString);
314-
definition.InsertAt(0, new BsonElement("path", path));
315-
return definition;
285+
var name = GetTestCaseName(document, document, 0);
286+
yield return new JsonDrivenTestCase(name, document, document);
316287
}
317288
}
318289
}

tests/MongoDB.Driver.Core.Tests/Specifications/server-discovery-and-monitoring/tests/README.rst

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,8 @@ Server Discovery And Monitoring Spec.
99
Version
1010
-------
1111

12-
Files in the "specifications" repository have no version scheme.
13-
They are not tied to a MongoDB server version,
14-
and it is our intention that each specification moves from "draft" to "final"
15-
with no further versions; it is superseded by a future spec, not revised.
16-
17-
However, implementers must have stable sets of tests to target.
18-
As test files evolve they will be occasionally tagged like
19-
"server-discovery-tests-2014-09-10", until the spec is final.
12+
Files in the "specifications" repository have no version scheme. They are not
13+
tied to a MongoDB server version.
2014

2115
Format
2216
------
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"description": "Primary becomes ghost",
3+
"uri": "mongodb://a/?replicaSet=rs",
4+
"phases": [
5+
{
6+
"responses": [
7+
[
8+
"a:27017",
9+
{
10+
"ok": 1,
11+
"ismaster": true,
12+
"hosts": [
13+
"a:27017"
14+
],
15+
"setName": "rs",
16+
"minWireVersion": 0,
17+
"maxWireVersion": 6
18+
}
19+
]
20+
],
21+
"outcome": {
22+
"servers": {
23+
"a:27017": {
24+
"type": "RSPrimary",
25+
"setName": "rs"
26+
}
27+
},
28+
"topologyType": "ReplicaSetWithPrimary",
29+
"logicalSessionTimeoutMinutes": null,
30+
"setName": "rs"
31+
}
32+
},
33+
{
34+
"responses": [
35+
[
36+
"a:27017",
37+
{
38+
"ok": 1,
39+
"ismaster": false,
40+
"isreplicaset": true,
41+
"minWireVersion": 0,
42+
"maxWireVersion": 6
43+
}
44+
]
45+
],
46+
"outcome": {
47+
"servers": {
48+
"a:27017": {
49+
"type": "RSGhost",
50+
"setName": null
51+
}
52+
},
53+
"topologyType": "ReplicaSetNoPrimary",
54+
"logicalSessionTimeoutMinutes": null,
55+
"setName": "rs"
56+
}
57+
}
58+
]
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
description: "Primary becomes ghost"
2+
3+
uri: "mongodb://a/?replicaSet=rs"
4+
5+
phases: [
6+
7+
{
8+
responses: [
9+
10+
["a:27017", {
11+
12+
ok: 1,
13+
ismaster: true,
14+
hosts: ["a:27017"],
15+
setName: "rs",
16+
minWireVersion: 0,
17+
maxWireVersion: 6
18+
}]
19+
],
20+
21+
outcome: {
22+
23+
servers: {
24+
25+
"a:27017": {
26+
27+
type: "RSPrimary",
28+
setName: "rs"
29+
}
30+
},
31+
topologyType: "ReplicaSetWithPrimary",
32+
logicalSessionTimeoutMinutes: null,
33+
setName: "rs"
34+
}
35+
},
36+
37+
{
38+
responses: [
39+
["a:27017", {
40+
ok: 1,
41+
ismaster: false,
42+
isreplicaset: true,
43+
minWireVersion: 0,
44+
maxWireVersion: 6
45+
}]
46+
],
47+
48+
outcome: {
49+
50+
servers: {
51+
52+
"a:27017": {
53+
54+
type: "RSGhost",
55+
setName:
56+
}
57+
},
58+
topologyType: "ReplicaSetNoPrimary",
59+
logicalSessionTimeoutMinutes: null,
60+
setName: "rs"
61+
}
62+
}
63+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"description": "Primary becomes mongos",
3+
"uri": "mongodb://a/?replicaSet=rs",
4+
"phases": [
5+
{
6+
"responses": [
7+
[
8+
"a:27017",
9+
{
10+
"ok": 1,
11+
"ismaster": true,
12+
"hosts": [
13+
"a:27017"
14+
],
15+
"setName": "rs",
16+
"minWireVersion": 0,
17+
"maxWireVersion": 6
18+
}
19+
]
20+
],
21+
"outcome": {
22+
"servers": {
23+
"a:27017": {
24+
"type": "RSPrimary",
25+
"setName": "rs"
26+
}
27+
},
28+
"topologyType": "ReplicaSetWithPrimary",
29+
"logicalSessionTimeoutMinutes": null,
30+
"setName": "rs"
31+
}
32+
},
33+
{
34+
"responses": [
35+
[
36+
"a:27017",
37+
{
38+
"ok": 1,
39+
"ismaster": true,
40+
"msg": "isdbgrid",
41+
"minWireVersion": 0,
42+
"maxWireVersion": 6
43+
}
44+
]
45+
],
46+
"outcome": {
47+
"servers": {},
48+
"topologyType": "ReplicaSetNoPrimary",
49+
"logicalSessionTimeoutMinutes": null,
50+
"setName": "rs"
51+
}
52+
}
53+
]
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
description: "Primary becomes mongos"
2+
3+
uri: "mongodb://a/?replicaSet=rs"
4+
5+
phases: [
6+
7+
{
8+
responses: [
9+
10+
["a:27017", {
11+
12+
ok: 1,
13+
ismaster: true,
14+
hosts: ["a:27017"],
15+
setName: "rs",
16+
minWireVersion: 0,
17+
maxWireVersion: 6
18+
}]
19+
],
20+
21+
outcome: {
22+
23+
servers: {
24+
25+
"a:27017": {
26+
27+
type: "RSPrimary",
28+
setName: "rs"
29+
}
30+
},
31+
topologyType: "ReplicaSetWithPrimary",
32+
logicalSessionTimeoutMinutes: null,
33+
setName: "rs"
34+
}
35+
},
36+
37+
{
38+
responses: [
39+
["a:27017", {
40+
ok: 1,
41+
ismaster: true,
42+
msg: "isdbgrid",
43+
minWireVersion: 0,
44+
maxWireVersion: 6
45+
}]
46+
],
47+
48+
outcome: {
49+
50+
servers: {},
51+
topologyType: "ReplicaSetNoPrimary",
52+
logicalSessionTimeoutMinutes: null,
53+
setName: "rs"
54+
}
55+
}
56+
]

tests/MongoDB.Driver.Core.Tests/Specifications/server-discovery-and-monitoring/tests/rs/primary_mismatched_me.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
],
2929
"ismaster": true,
3030
"ok": 1,
31-
"setName": "rs"
31+
"setName": "rs",
32+
"minWireVersion": 0,
33+
"maxWireVersion": 6
3234
}
3335
]
3436
]

0 commit comments

Comments
 (0)