Skip to content

Commit 7465329

Browse files
CSHARP-2525: Check only non-unknown server descriptions to determine incompatibility.
1 parent 3919516 commit 7465329

15 files changed

+581
-22
lines changed

src/MongoDB.Driver.Core/Core/Servers/ServerDescription.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,10 @@ public TimeSpan HeartbeatInterval
194194
/// <value>
195195
/// <c>true</c> if this server is compatible with the driver; otherwise, <c>false</c>.
196196
/// </value>
197-
public bool IsCompatibleWithDriver
198-
{
199-
get
200-
{
201-
return _wireVersionRange == null || _wireVersionRange.Overlaps(Cluster.SupportedWireVersionRange);
202-
}
203-
}
197+
public bool IsCompatibleWithDriver =>
198+
_type == ServerType.Unknown ||
199+
_wireVersionRange == null ||
200+
_wireVersionRange.Overlaps(Cluster.SupportedWireVersionRange);
204201

205202
/// <summary>
206203
/// Gets a value indicating whether this instance is a data bearing server.

src/MongoDB.Driver.Core/MongoIncompatibleDriverException.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#endif
2121
using MongoDB.Driver.Core.Clusters;
2222
using MongoDB.Driver.Core.Misc;
23+
using MongoDB.Driver.Core.Servers;
2324

2425
namespace MongoDB.Driver
2526
{
@@ -35,8 +36,7 @@ public class MongoIncompatibleDriverException : MongoClientException
3536
// static methods
3637
internal static void ThrowIfNotSupported(ClusterDescription description)
3738
{
38-
var isIncompatible = description.Servers
39-
.Any(sd => sd.WireVersionRange != null && !sd.WireVersionRange.Overlaps(Cluster.SupportedWireVersionRange));
39+
var isIncompatible = description.Servers.Any(IsServerIncompatible);
4040

4141
if (isIncompatible)
4242
{
@@ -46,8 +46,7 @@ internal static void ThrowIfNotSupported(ClusterDescription description)
4646

4747
private static string FormatMessage(ClusterDescription description)
4848
{
49-
var incompatibleServer = description.Servers
50-
.FirstOrDefault(sd => sd.WireVersionRange != null && !sd.WireVersionRange.Overlaps(Cluster.SupportedWireVersionRange));
49+
var incompatibleServer = description.Servers.FirstOrDefault(IsServerIncompatible);
5150

5251
if (incompatibleServer == null)
5352
{
@@ -63,6 +62,14 @@ private static string FormatMessage(ClusterDescription description)
6362
return $"Server at {EndPointHelper.ToString(incompatibleServer.EndPoint)} requires wire version {incompatibleServer.WireVersionRange.Min},"
6463
+ $" but this version of the driver only supports up to {Cluster.SupportedWireVersionRange.Max}.";
6564
}
65+
66+
private static bool IsServerIncompatible(ServerDescription description)
67+
{
68+
return
69+
description.Type != ServerType.Unknown &&
70+
description.WireVersionRange != null &&
71+
!description.WireVersionRange.Overlaps(Cluster.SupportedWireVersionRange);
72+
}
6673
#endregion
6774

6875
// constructors

tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterDescriptionTests.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public void IsCompatibleWithDriver_should_return_expected_result(int[] wireRange
135135
var serverId = new ServerId(clusterId, endPoint);
136136
var wireRange = wireRanges[i];
137137
var wireVersionRange = wireRange == 0 ? new Range<int>(0, 0) : wireRange == 1 ? new Range<int>(2, 6) : null;
138-
var server = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange);
138+
var server = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange, type: ServerType.Standalone);
139139
subject = subject.WithServerDescription(server);
140140
}
141141

@@ -144,6 +144,40 @@ public void IsCompatibleWithDriver_should_return_expected_result(int[] wireRange
144144
result.Should().Be(expectedResult);
145145
}
146146

147+
[Theory]
148+
[InlineData(new int[0])]
149+
[InlineData(new int[] { 0 })]
150+
[InlineData(new int[] { 1 })]
151+
[InlineData(new int[] { 2 })]
152+
[InlineData(new int[] { 0, 0 })]
153+
[InlineData(new int[] { 0, 1 })]
154+
[InlineData(new int[] { 0, 2 })]
155+
[InlineData(new int[] { 1, 0 })]
156+
[InlineData(new int[] { 1, 1 })]
157+
[InlineData(new int[] { 1, 2 })]
158+
[InlineData(new int[] { 2, 0 })]
159+
[InlineData(new int[] { 2, 1 })]
160+
[InlineData(new int[] { 2, 2 })]
161+
public void IsCompatibleWithDriver_should_return_true_if_server_unknown(int[] wireRanges)
162+
{
163+
var clusterId = new ClusterId(1);
164+
var connectionMode = ClusterConnectionMode.Automatic;
165+
var subject = ClusterDescription.CreateInitial(clusterId, connectionMode);
166+
for (var i = 0; i < wireRanges.Length; i++)
167+
{
168+
var endPoint = new DnsEndPoint("localhost", i);
169+
var serverId = new ServerId(clusterId, endPoint);
170+
var wireRange = wireRanges[i];
171+
var wireVersionRange = wireRange == 0 ? new Range<int>(0, 0) : wireRange == 1 ? new Range<int>(2, 6) : null;
172+
var server = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange, type: ServerType.Unknown);
173+
subject = subject.WithServerDescription(server);
174+
}
175+
176+
var result = subject.IsCompatibleWithDriver;
177+
178+
result.Should().BeTrue();
179+
}
180+
147181
[Fact]
148182
public void LogicalSessionTimeout_should_return_expected_result_with_0_servers()
149183
{

tests/MongoDB.Driver.Core.Tests/Core/Servers/ServerDescriptionTests.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@
1818
using FluentAssertions;
1919
using MongoDB.Bson;
2020
using MongoDB.Driver.Core.Clusters;
21-
using MongoDB.Driver.Core.Connections;
2221
using MongoDB.Driver.Core.Misc;
23-
using MongoDB.Driver.Core.Servers;
2422
using Xunit;
2523

2624
namespace MongoDB.Driver.Core.Servers
2725
{
28-
class ServerDescriptionTests
26+
public class ServerDescriptionTests
2927
{
3028
#region static
3129
// static fields
@@ -187,8 +185,17 @@ public void Equals_should_return_false_when_any_field_is_not_equal(string notEqu
187185
[Fact]
188186
public void Equals_should_return_true_when_all_fields_are_equal()
189187
{
190-
ServerDescription subject = new ServerDescription(__serverId, __endPoint);
191-
ServerDescription serverDescription2 = new ServerDescription(__serverId, __endPoint);
188+
var lastUpdateTimestamp = DateTime.UtcNow;
189+
ServerDescription subject = new ServerDescription(
190+
__serverId,
191+
__endPoint,
192+
type: ServerType.Standalone,
193+
lastUpdateTimestamp: lastUpdateTimestamp);
194+
ServerDescription serverDescription2 = new ServerDescription(
195+
__serverId,
196+
__endPoint,
197+
type: ServerType.Standalone,
198+
lastUpdateTimestamp: lastUpdateTimestamp);
192199
subject.Equals(serverDescription2).Should().BeTrue();
193200
subject.Equals((object)serverDescription2).Should().BeTrue();
194201
subject.GetHashCode().Should().Be(serverDescription2.GetHashCode());
@@ -206,15 +213,15 @@ public void Equals_should_return_true_when_all_fields_are_equal()
206213
[InlineData(new[] { 2, 7 }, true)]
207214
[InlineData(new[] { 6, 6 }, true)]
208215
[InlineData(new[] { 6, 7 }, true)]
209-
[InlineData(new[] { 7, 7 }, false)]
210-
[InlineData(new[] { 7, 8 }, false)]
216+
[InlineData(new[] { 7, 7 }, true)]
217+
[InlineData(new[] { 7, 8 }, true)]
211218
public void IsCompatibleWithDriver_should_return_expected_result(int[] minMaxWireVersions, bool expectedResult)
212219
{
213220
var clusterId = new ClusterId(1);
214221
var endPoint = new DnsEndPoint("localhost", 27017);
215222
var serverId = new ServerId(clusterId, endPoint);
216223
var wireVersionRange = minMaxWireVersions == null ? null : new Range<int>(minMaxWireVersions[0], minMaxWireVersions[1]);
217-
var subject = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange);
224+
var subject = new ServerDescription(serverId, endPoint, wireVersionRange: wireVersionRange, type: ServerType.Standalone);
218225

219226
var result = subject.IsCompatibleWithDriver;
220227

@@ -373,7 +380,7 @@ public void With_should_return_same_instance_when_all_fields_are_equal()
373380
version: version,
374381
wireVersionRange: wireVersionRange);
375382

376-
result.Should().BeSameAs(subject);
383+
result.ShouldBeEquivalentTo(subject);
377384
}
378385
}
379386
}

tests/MongoDB.Driver.Core.Tests/MongoIncompatibleDriverExceptionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public MongoIncompatibleDriverExceptionTests()
3737
var clusterType = ClusterType.Standalone;
3838
var endPoint = new DnsEndPoint("localhost", 27017);
3939
var serverId = new ServerId(clusterId, endPoint);
40-
var server = new ServerDescription(serverId, endPoint, wireVersionRange: new Range<int>(0, 0));
40+
var server = new ServerDescription(serverId, endPoint, wireVersionRange: new Range<int>(0, 0), type: ServerType.Standalone);
4141
var servers = new[] { server };
4242
_clusterDescription = new ClusterDescription(clusterId, connectionMode, clusterType, servers);
4343
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"description": "Replica set member and an unknown server",
3+
"uri": "mongodb://a,b/?replicaSet=rs",
4+
"phases": [
5+
{
6+
"responses": [
7+
[
8+
"a:27017",
9+
{
10+
"ok": 1,
11+
"ismaster": true,
12+
"setName": "rs",
13+
"hosts": [
14+
"a:27017",
15+
"b:27017"
16+
],
17+
"minWireVersion": 0,
18+
"maxWireVersion": 6
19+
}
20+
]
21+
],
22+
"outcome": {
23+
"servers": {
24+
"a:27017": {
25+
"type": "RSPrimary",
26+
"setName": "rs"
27+
},
28+
"b:27017": {
29+
"type": "Unknown"
30+
}
31+
},
32+
"topologyType": "ReplicaSetWithPrimary",
33+
"setName": "rs",
34+
"logicalSessionTimeoutMinutes": null,
35+
"compatible": true
36+
}
37+
}
38+
]
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
description: "Replica set member and an unknown server"
2+
uri: "mongodb://a,b/?replicaSet=rs"
3+
phases: [
4+
{
5+
responses: [
6+
["a:27017", {
7+
ok: 1,
8+
ismaster: true,
9+
setName: "rs",
10+
hosts: ["a:27017", "b:27017"],
11+
minWireVersion: 0,
12+
maxWireVersion: 6
13+
}],
14+
],
15+
outcome: {
16+
servers: {
17+
"a:27017": {
18+
type: "RSPrimary",
19+
setName: "rs"
20+
},
21+
"b:27017": {
22+
type: "Unknown",
23+
}
24+
},
25+
topologyType: "ReplicaSetWithPrimary",
26+
setName: "rs",
27+
logicalSessionTimeoutMinutes: null,
28+
compatible: true
29+
}
30+
}
31+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"description": "Incompatible arbiter",
3+
"uri": "mongodb://a,b/?replicaSet=rs",
4+
"phases": [
5+
{
6+
"responses": [
7+
[
8+
"a:27017",
9+
{
10+
"ok": 1,
11+
"ismaster": true,
12+
"setName": "rs",
13+
"hosts": [
14+
"a:27017",
15+
"b:27017"
16+
],
17+
"minWireVersion": 0,
18+
"maxWireVersion": 6
19+
}
20+
],
21+
[
22+
"b:27017",
23+
{
24+
"ok": 1,
25+
"arbiterOnly": true,
26+
"setName": "rs",
27+
"hosts": [
28+
"a:27017",
29+
"b:27017"
30+
],
31+
"minWireVersion": 0,
32+
"maxWireVersion": 1
33+
}
34+
]
35+
],
36+
"outcome": {
37+
"servers": {
38+
"a:27017": {
39+
"type": "RSPrimary",
40+
"setName": "rs"
41+
},
42+
"b:27017": {
43+
"type": "RSArbiter",
44+
"setName": "rs"
45+
}
46+
},
47+
"topologyType": "ReplicaSetWithPrimary",
48+
"setName": "rs",
49+
"logicalSessionTimeoutMinutes": null,
50+
"compatible": false
51+
}
52+
}
53+
]
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
description: "Incompatible arbiter"
2+
uri: "mongodb://a,b/?replicaSet=rs"
3+
phases:
4+
- responses:
5+
-
6+
- "a:27017"
7+
- ok: 1
8+
ismaster: true
9+
setName: "rs"
10+
hosts: ["a:27017", "b:27017"]
11+
minWireVersion: 0
12+
maxWireVersion: 6
13+
-
14+
- "b:27017"
15+
- ok: 1
16+
arbiterOnly: true
17+
setName: "rs"
18+
hosts: ["a:27017", "b:27017"]
19+
minWireVersion: 0
20+
maxWireVersion: 1
21+
outcome:
22+
servers:
23+
"a:27017":
24+
type: "RSPrimary"
25+
setName: "rs"
26+
"b:27017":
27+
type: "RSArbiter"
28+
setName: "rs"
29+
topologyType: "ReplicaSetWithPrimary"
30+
setName: "rs"
31+
logicalSessionTimeoutMinutes: ~
32+
compatible: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"description": "Incompatible ghost",
3+
"uri": "mongodb://a,b/?replicaSet=rs",
4+
"phases": [
5+
{
6+
"responses": [
7+
[
8+
"a:27017",
9+
{
10+
"ok": 1,
11+
"ismaster": true,
12+
"setName": "rs",
13+
"hosts": [
14+
"a:27017",
15+
"b:27017"
16+
],
17+
"minWireVersion": 0,
18+
"maxWireVersion": 6
19+
}
20+
],
21+
[
22+
"b:27017",
23+
{
24+
"ok": 1,
25+
"isreplicaset": true,
26+
"minWireVersion": 0,
27+
"maxWireVersion": 1
28+
}
29+
]
30+
],
31+
"outcome": {
32+
"servers": {
33+
"a:27017": {
34+
"type": "RSPrimary",
35+
"setName": "rs"
36+
},
37+
"b:27017": {
38+
"type": "RSGhost",
39+
"setName": null
40+
}
41+
},
42+
"topologyType": "ReplicaSetWithPrimary",
43+
"setName": "rs",
44+
"logicalSessionTimeoutMinutes": null,
45+
"compatible": false
46+
}
47+
}
48+
]
49+
}

0 commit comments

Comments
 (0)