summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaMont Nelson <lamont.nelson@mongodb.com>2020-08-06 03:36:37 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-14 22:15:06 +0000
commit75f7184eafa78006a698cda4c4adfb57f1290047 (patch)
treeb4db9db5b1ca8fdc5c869a3e6a6e143c3407a49d
parent999c821df183f2e8d0b2fdc6cef09070434278b7 (diff)
downloadmongo-75f7184eafa78006a698cda4c4adfb57f1290047.tar.gz
SERVER-50170 fix max staleness read preference parameter for server selection
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json74
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Incompatible.json36
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json88
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.json20
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest.json88
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest2.json88
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json21
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json64
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json84
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Secondary.json111
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json63
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json111
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json36
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json74
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Incompatible.json36
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json88
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json76
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json37
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json37
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json35
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest.json88
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest2.json88
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json84
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json64
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json36
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json63
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json138
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json96
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json138
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json96
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json36
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/Incompatible.json36
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/SmallMaxStaleness.json76
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/Incompatible.json24
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/SmallMaxStaleness.json52
-rw-r--r--src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Unknown/SmallMaxStaleness.json19
-rw-r--r--src/mongo/client/sdam/server_selection_json_test_runner.cpp277
-rw-r--r--src/mongo/client/sdam/server_selector.cpp52
-rw-r--r--src/mongo/client/sdam/server_selector.h24
-rw-r--r--src/mongo/client/sdam/server_selector_test.cpp25
-rw-r--r--src/mongo/client/sdam/topology_description.cpp27
-rw-r--r--src/mongo/client/sdam/topology_description.h13
-rw-r--r--src/mongo/client/sdam/topology_manager.cpp6
-rw-r--r--src/mongo/client/sdam/topology_manager_test.cpp40
44 files changed, 2769 insertions, 96 deletions
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json
new file mode 100644
index 00000000000..1e3dd0bfd94
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json
@@ -0,0 +1,74 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest"
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Incompatible.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Incompatible.json
new file mode 100644
index 00000000000..7f9fa764c7c
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Incompatible.json
@@ -0,0 +1,36 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 120
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json
new file mode 100644
index 00000000000..e1abef2844b
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.json
@@ -0,0 +1,88 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 1,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 25002,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 25001,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 1,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 25002,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 1,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.json
new file mode 100644
index 00000000000..28e5e2aa4a5
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.json
@@ -0,0 +1,20 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Unknown"
+ },
+ {
+ "address": "b:27017",
+ "type": "Unknown"
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 1
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest.json
new file mode 100644
index 00000000000..53549e64317
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest.json
@@ -0,0 +1,88 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "c:27017",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "type": "RSSecondary",
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest2.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest2.json
new file mode 100644
index 00000000000..e2768c7fb8a
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Nearest2.json
@@ -0,0 +1,88 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "c:27017",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "type": "RSSecondary",
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json
new file mode 100644
index 00000000000..5905fcbc605
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/NoKnownServers.json
@@ -0,0 +1,21 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Unknown"
+ },
+ {
+ "address": "b:27017",
+ "type": "Unknown"
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 90
+ },
+ "suitable_servers": [],
+ "in_latency_window": []
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json
new file mode 100644
index 00000000000..8c6be6886a7
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.json
@@ -0,0 +1,64 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "PrimaryPreferred",
+ "maxStalenessSeconds": 90
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json
new file mode 100644
index 00000000000..26007c026ee
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json
@@ -0,0 +1,84 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "PrimaryPreferred",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ },
+ {
+ "data_center": "tokyo"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Secondary.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Secondary.json
new file mode 100644
index 00000000000..7d5eb58f4da
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/Secondary.json
@@ -0,0 +1,111 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "tags": {
+ "data_center": "tokyo"
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "d:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Secondary",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json
new file mode 100644
index 00000000000..df0bb5d77f0
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.json
@@ -0,0 +1,63 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "SecondaryPreferred",
+ "maxStalenessSeconds": 120
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json
new file mode 100644
index 00000000000..1ac3ea0aed9
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json
@@ -0,0 +1,111 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "tags": {
+ "data_center": "tokyo"
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "d:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "SecondaryPreferred",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json
new file mode 100644
index 00000000000..cb5dc5175a9
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json
@@ -0,0 +1,36 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetNoPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 0
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json
new file mode 100644
index 00000000000..ed18d5837ec
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json
@@ -0,0 +1,74 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest"
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Incompatible.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Incompatible.json
new file mode 100644
index 00000000000..d27ea11202c
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Incompatible.json
@@ -0,0 +1,36 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 120
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json
new file mode 100644
index 00000000000..bbd8238e8a9
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.json
@@ -0,0 +1,88 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 1,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 125001,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 125001,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 1,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 125001,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 125001,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json
new file mode 100644
index 00000000000..cb05f52aa26
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.json
@@ -0,0 +1,76 @@
+{
+ "heartbeatFrequencyMS": 120000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 130
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json
new file mode 100644
index 00000000000..be169a3dcb6
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.json
@@ -0,0 +1,37 @@
+{
+ "heartbeatFrequencyMS": 120000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 129
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json
new file mode 100644
index 00000000000..173f5742a20
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json
@@ -0,0 +1,37 @@
+{
+ "heartbeatFrequencyMS": 500,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 89
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json
new file mode 100644
index 00000000000..eee34627831
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json
@@ -0,0 +1,35 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "maxStalenessSeconds": 120
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest.json
new file mode 100644
index 00000000000..753fb82ca32
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest.json
@@ -0,0 +1,88 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "c:27017",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "type": "RSSecondary",
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest2.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest2.json
new file mode 100644
index 00000000000..6233c0815aa
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest2.json
@@ -0,0 +1,88 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "c:27017",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "type": "RSSecondary",
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json
new file mode 100644
index 00000000000..9a1cd3bb124
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Nearest_tags.json
@@ -0,0 +1,84 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ },
+ {
+ "data_center": "tokyo"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json
new file mode 100644
index 00000000000..107ae2755e2
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.json
@@ -0,0 +1,64 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "PrimaryPreferred",
+ "maxStalenessSeconds": 150
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json
new file mode 100644
index 00000000000..a6681f6a130
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json
@@ -0,0 +1,36 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "PrimaryPreferred",
+ "maxStalenessSeconds": 150
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json
new file mode 100644
index 00000000000..5f8a21f15c9
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.json
@@ -0,0 +1,63 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "SecondaryPreferred",
+ "maxStalenessSeconds": 120
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json
new file mode 100644
index 00000000000..09ce6d6bd0a
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json
@@ -0,0 +1,138 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 1,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "d:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "e:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "SecondaryPreferred",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 1,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json
new file mode 100644
index 00000000000..3700c30453e
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json
@@ -0,0 +1,96 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "SecondaryPreferred",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ },
+ {
+ "data_center": "tokyo"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json
new file mode 100644
index 00000000000..f117159f64d
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags.json
@@ -0,0 +1,138 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 1,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "d:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "e:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Secondary",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 1,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1000001"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json
new file mode 100644
index 00000000000..b739c6141bf
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.json
@@ -0,0 +1,96 @@
+{
+ "heartbeatFrequencyMS": 25000,
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "125002"
+ }
+ },
+ "maxWireVersion": 5
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ },
+ {
+ "address": "c:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "nyc"
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Secondary",
+ "maxStalenessSeconds": 150,
+ "tag_sets": [
+ {
+ "data_center": "nyc"
+ },
+ {
+ "data_center": "tokyo"
+ }
+ ]
+ },
+ "suitable_servers": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ },
+ "maxWireVersion": 5,
+ "tags": {
+ "data_center": "tokyo"
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json
new file mode 100644
index 00000000000..f17aa93a3fb
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json
@@ -0,0 +1,36 @@
+{
+ "topology_description": {
+ "type": "ReplicaSetWithPrimary",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "RSPrimary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "2"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "RSSecondary",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 0
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/Incompatible.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/Incompatible.json
new file mode 100644
index 00000000000..c261383f4a6
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/Incompatible.json
@@ -0,0 +1,36 @@
+{
+ "topology_description": {
+ "type": "Sharded",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 120
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/SmallMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/SmallMaxStaleness.json
new file mode 100644
index 00000000000..27b9f1c12fd
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Sharded/SmallMaxStaleness.json
@@ -0,0 +1,76 @@
+{
+ "heartbeatFrequencyMS": 10000,
+ "topology_description": {
+ "type": "Sharded",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 1
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ },
+ {
+ "address": "b:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 50,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "Mongos",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/Incompatible.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/Incompatible.json
new file mode 100644
index 00000000000..b37fec7c1ac
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/Incompatible.json
@@ -0,0 +1,24 @@
+{
+ "topology_description": {
+ "type": "Single",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Standalone",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 4,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 120
+ },
+ "error": true
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/SmallMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/SmallMaxStaleness.json
new file mode 100644
index 00000000000..c6b10231b87
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Single/SmallMaxStaleness.json
@@ -0,0 +1,52 @@
+{
+ "heartbeatFrequencyMS": 10000,
+ "topology_description": {
+ "type": "Single",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Standalone",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 1
+ },
+ "suitable_servers": [
+ {
+ "address": "a:27017",
+ "type": "Standalone",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ],
+ "in_latency_window": [
+ {
+ "address": "a:27017",
+ "type": "Standalone",
+ "avg_rtt_ms": 5,
+ "lastUpdateTime": 0,
+ "maxWireVersion": 5,
+ "lastWrite": {
+ "lastWriteDate": {
+ "$numberLong": "1"
+ }
+ }
+ }
+ ]
+}
diff --git a/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Unknown/SmallMaxStaleness.json b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Unknown/SmallMaxStaleness.json
new file mode 100644
index 00000000000..bf6174b8e4d
--- /dev/null
+++ b/src/mongo/client/sdam/json_tests/server_selection_tests/max_staleness/Unknown/SmallMaxStaleness.json
@@ -0,0 +1,19 @@
+{
+ "heartbeatFrequencyMS": 10000,
+ "topology_description": {
+ "type": "Unknown",
+ "servers": [
+ {
+ "address": "a:27017",
+ "type": "Unknown",
+ "maxWireVersion": 5
+ }
+ ]
+ },
+ "read_preference": {
+ "mode": "Nearest",
+ "maxStalenessSeconds": 1
+ },
+ "suitable_servers": [],
+ "in_latency_window": []
+}
diff --git a/src/mongo/client/sdam/server_selection_json_test_runner.cpp b/src/mongo/client/sdam/server_selection_json_test_runner.cpp
index 665a577a966..ad689de6881 100644
--- a/src/mongo/client/sdam/server_selection_json_test_runner.cpp
+++ b/src/mongo/client/sdam/server_selection_json_test_runner.cpp
@@ -99,6 +99,10 @@ public:
virtual TestCaseResult execute() = 0;
virtual const std::string& FilePath() const = 0;
+
+ virtual bool errorIsExpected() {
+ return false;
+ }
};
/**
@@ -207,21 +211,46 @@ private:
class JsonServerSelectionTestCase : public JsonTestCase {
public:
JsonServerSelectionTestCase(fs::path testFilePath) {
- parseTest(testFilePath);
+ try {
+ parseTest(testFilePath);
+ } catch (const DBException& ex) {
+ _parseError = TestCaseResult{{std::make_pair("error while parsing", ex.toString())},
+ testFilePath.string()};
+ }
}
~JsonServerSelectionTestCase() = default;
TestCaseResult execute() {
LOGV2(4333504, "### Running Test ###", "testFilePath"_attr = _testFilePath);
-
- SdamServerSelector serverSelector(
- SdamConfiguration(std::vector<HostAndPort>{HostAndPort("foo:1234")}));
- auto selectedServers = serverSelector.selectServers(_topologyDescription, _readPreference);
+ if (_parseError)
+ return *_parseError;
TestCaseResult result{{}, _testFilePath};
- validateServersInLatencyWindow(&result, selectedServers);
- if (!result.Success()) {
+ try {
+ SdamServerSelector serverSelector(
+ SdamConfiguration(std::vector<HostAndPort>{HostAndPort("foo:1234")}));
+ auto selectedServers =
+ serverSelector.selectServers(_topologyDescription, _readPreference);
+
+ std::vector<std::string> selectedHosts;
+ if (selectedServers) {
+ std::transform((*selectedServers).begin(),
+ (*selectedServers).end(),
+ std::back_inserter(selectedHosts),
+ [](const ServerDescriptionPtr& server) {
+ return server->getAddress().toString();
+ });
+ }
+ LOGV2(5017006, "Servers selected", "servers"_attr = selectedHosts);
+
+ validateServersInLatencyWindow(&result, selectedServers);
+ } catch (const DBException& ex) {
+ auto errorDescription = std::make_pair("exception", ex.toString());
+ result.errorDescriptions.push_back(errorDescription);
+ }
+
+ if (!result.Success() && !_errorExpected) {
LOGV2(4333505, "Test failed", "testFilePath"_attr = _testFilePath);
}
@@ -232,6 +261,10 @@ public:
return _testFilePath;
}
+ bool errorIsExpected() {
+ return _errorExpected;
+ }
+
private:
void parseTest(fs::path testFilePath) {
_testFilePath = testFilePath.string();
@@ -243,33 +276,90 @@ private:
_jsonTest = fromjson(json.str());
}
+ // Do this first to save the state
+ if (_jsonTest.hasField("error")) {
+ LOGV2(5017004, "Expecting test case to generate an error.");
+ _errorExpected = _jsonTest.getBoolField("error");
+ }
+
// The json tests pass in capitalized keywords for mode, but the server only accepts
// lowercased keywords. Also, change the key "tags_set" to "tags".
+ // This can throw for test cases that have invalid read preferences.
auto readPrefObj = _jsonTest.getObjectField("read_preference");
std::string mode = readPrefObj.getStringField("mode");
mode[0] = std::tolower(mode[0]);
auto tagSetsObj = readPrefObj["tag_sets"];
auto tags = tagSetsObj ? BSONArray(readPrefObj["tag_sets"].Obj()) : BSONArray();
- BSONObj readPref = BSON("mode" << mode << "tags" << tags);
- _readPreference = uassertStatusOK(ReadPreferenceSetting::fromInnerBSON(readPref));
- // Parse the TopologyDescription and inLatencyWindow objects
auto topologyDescriptionObj = _jsonTest.getObjectField("topology_description");
+ TopologyType initType =
+ uassertStatusOK(parseTopologyType(topologyDescriptionObj.getStringField("type")));
+ boost::optional<std::string> setName = boost::none;
+ if (initType == TopologyType::kReplicaSetNoPrimary || initType == TopologyType::kSingle)
+ setName = "replset";
+
+ int maxStalenessSeconds = 0;
+ if (readPrefObj.hasField("maxStalenessSeconds")) {
+ maxStalenessSeconds = readPrefObj.getIntField("maxStalenessSeconds");
+ }
+
+ BSONObj readPref =
+ BSON("mode" << mode << "tags" << tags << "maxStalenessSeconds" << maxStalenessSeconds);
+ auto stalenessParseResult = ReadPreferenceSetting::fromInnerBSON(readPref);
+ if (!_errorExpected &&
+ stalenessParseResult.getStatus().code() == ErrorCodes::MaxStalenessOutOfRange &&
+ (initType == TopologyType::kUnknown || initType == TopologyType::kSingle ||
+ initType == TopologyType::kSharded)) {
+ // Drivers tests expect no error for invalid maxStaleness values for Unknown, Single,
+ // and Sharded topology types. The server code doesn't allow read preferences to be
+ // created for invalid values for maxStaleness, so ignore it.
+ readPref = BSON("mode" << mode << "tags" << tags << "maxStalenessSeconds" << 0);
+ stalenessParseResult = ReadPreferenceSetting::fromInnerBSON(readPref);
+ } else if (_errorExpected && maxStalenessSeconds == 0 &&
+ readPrefObj.hasField("maxStalenessSeconds")) {
+ // Generate an error to pass test cases that set max staleness to zero since the server
+ // interprets this as no maxStaleness is specified.
+ uassert(ErrorCodes::MaxStalenessOutOfRange, "max staleness should be >= 0", false);
+ }
+ _readPreference = uassertStatusOK(stalenessParseResult);
+ LOGV2(5017007, "Read Preference", "value"_attr = _readPreference);
+
+ if (_jsonTest.hasField("heartbeatFrequencyMS")) {
+ sdamHeartBeatFrequencyMs = _jsonTest.getIntField("heartbeatFrequencyMS");
+ LOGV2(5017003, "Set heartbeatFrequencyMs", "value"_attr = sdamHeartBeatFrequencyMs);
+ }
std::vector<ServerDescriptionPtr> serverDescriptions;
std::vector<HostAndPort> serverAddresses;
const std::vector<BSONElement>& bsonServers = topologyDescriptionObj["servers"].Array();
+
for (auto bsonServer : bsonServers) {
auto server = bsonServer.Obj();
+ int maxWireVersion = 9;
+ if (server.hasField("maxWireVersion")) {
+ maxWireVersion = server["maxWireVersion"].numberInt();
+ }
+
auto serverType = uassertStatusOK(parseServerType(server.getStringField("type")));
auto serverDescription = ServerDescriptionBuilder()
.withAddress(HostAndPort(server.getStringField("address")))
.withType(serverType)
.withRtt(Milliseconds(server["avg_rtt_ms"].numberInt()))
- .withMinWireVersion(8)
- .withMaxWireVersion(9);
+ .withMinWireVersion(5)
+ .withMaxWireVersion(maxWireVersion);
+
+ if (server.hasField("lastWrite")) {
+ auto lastWriteDate =
+ server.getObjectField("lastWrite").getIntField("lastWriteDate");
+ serverDescription.withLastWriteDate(Date_t::fromMillisSinceEpoch(lastWriteDate));
+ }
+
+ if (server.hasField("lastUpdateTime")) {
+ auto lastUpdateTime = server.getIntField("lastUpdateTime");
+ serverDescription.withLastUpdateTime(Date_t::fromMillisSinceEpoch(lastUpdateTime));
+ }
auto tagsObj = server.getObjectField("tags");
const auto keys = tagsObj.getFieldNames<std::set<std::string>>();
@@ -278,14 +368,12 @@ private:
}
serverDescriptions.push_back(serverDescription.instance());
+ LOGV2(5017002,
+ "Server Description",
+ "description"_attr = serverDescriptions.back()->toBson());
serverAddresses.push_back(HostAndPort(server.getStringField("address")));
}
- TopologyType initType =
- uassertStatusOK(parseTopologyType(topologyDescriptionObj.getStringField("type")));
- boost::optional<std::string> setName = boost::none;
- if (initType == TopologyType::kReplicaSetNoPrimary || initType == TopologyType::kSingle)
- setName = "replset";
boost::optional<std::vector<HostAndPort>> seedList = boost::none;
if (serverAddresses.size() > 0)
@@ -299,15 +387,18 @@ private:
setName);
_topologyDescription = std::make_shared<TopologyDescription>(config);
- const std::vector<BSONElement>& bsonLatencyWindow = _jsonTest["in_latency_window"].Array();
- for (const auto& serverDescription : serverDescriptions) {
- _topologyDescription->installServerDescription(serverDescription);
-
- for (auto bsonServer : bsonLatencyWindow) {
- auto server = bsonServer.Obj();
- if (serverDescription->getAddress() ==
- HostAndPort(server.getStringField("address"))) {
- _inLatencyWindow.push_back(serverDescription);
+ if (_jsonTest.hasField("in_latency_window")) {
+ const std::vector<BSONElement>& bsonLatencyWindow =
+ _jsonTest["in_latency_window"].Array();
+ for (const auto& serverDescription : serverDescriptions) {
+ _topologyDescription->installServerDescription(serverDescription);
+
+ for (auto bsonServer : bsonLatencyWindow) {
+ auto server = bsonServer.Obj();
+ if (serverDescription->getAddress() ==
+ HostAndPort(server.getStringField("address"))) {
+ _inLatencyWindow.push_back(serverDescription);
+ }
}
}
}
@@ -316,50 +407,38 @@ private:
void validateServersInLatencyWindow(
TestCaseResult* result,
boost::optional<std::vector<ServerDescriptionPtr>> selectedServers) {
- if (!selectedServers && _inLatencyWindow.size() > 0) {
+ // Compare the server addresses of each server in the selectedServers and
+ // _inLatencyWindow vectors. We do not need to compare the entire server description
+ // because we only need to make sure that the correct server was chosen and are not
+ // manipulating the ServerDescriptions at all.
+ std::vector<HostAndPort> selectedHostAndPorts;
+ std::vector<HostAndPort> expectedHostAndPorts;
+
+ auto extractHost = [](const ServerDescriptionPtr& s) { return s->getAddress(); };
+ if (selectedServers) {
+ std::transform(selectedServers->begin(),
+ selectedServers->end(),
+ std::back_inserter(selectedHostAndPorts),
+ extractHost);
+ }
+ std::transform(_inLatencyWindow.begin(),
+ _inLatencyWindow.end(),
+ std::back_inserter(expectedHostAndPorts),
+ extractHost);
+
+ std::sort(selectedHostAndPorts.begin(), selectedHostAndPorts.end());
+ std::sort(expectedHostAndPorts.begin(), expectedHostAndPorts.end());
+ if (!std::equal(selectedHostAndPorts.begin(),
+ selectedHostAndPorts.end(),
+ expectedHostAndPorts.begin(),
+ expectedHostAndPorts.end())) {
std::stringstream errorMessage;
- errorMessage << "did not select any servers, but expected '" << _inLatencyWindow.size()
+ errorMessage << "selected servers with addresses '" << selectedHostAndPorts
+ << "' server(s), but expected '" << expectedHostAndPorts
<< "' to be selected.";
auto errorDescription = std::make_pair("servers in latency window", errorMessage.str());
result->errorDescriptions.push_back(errorDescription);
- } else if (selectedServers && selectedServers->size() != _inLatencyWindow.size()) {
- std::stringstream errorMessage;
- errorMessage << "selected '" << selectedServers->size() << "' server(s), but expected '"
- << _inLatencyWindow.size() << "' to be selected.";
- auto errorDescription = std::make_pair("servers in latency window", errorMessage.str());
- result->errorDescriptions.push_back(errorDescription);
- } else {
- // Compare the server addresses of each server in the selectedServers and
- // _inLatencyWindow vectors. We do not need to compare the entire server description
- // because we only need to make sure that the correct server was chosen and are not
- // manipulating the ServerDescriptions at all.
- std::vector<HostAndPort> selectedHostAndPortes;
- std::vector<HostAndPort> expectedHostAndPortes;
-
- auto selectedServersIt = selectedServers->begin();
- for (auto expectedServersIt = _inLatencyWindow.begin();
- expectedServersIt != _inLatencyWindow.end();
- ++expectedServersIt) {
- selectedHostAndPortes.push_back((*selectedServersIt)->getAddress());
- expectedHostAndPortes.push_back((*expectedServersIt)->getAddress());
-
- selectedServersIt++;
- }
-
- std::sort(selectedHostAndPortes.begin(), selectedHostAndPortes.end());
- std::sort(expectedHostAndPortes.begin(), expectedHostAndPortes.end());
- if (!std::equal(selectedHostAndPortes.begin(),
- selectedHostAndPortes.end(),
- expectedHostAndPortes.begin())) {
- std::stringstream errorMessage;
- errorMessage << "selected servers with addresses '" << selectedHostAndPortes
- << "' server(s), but expected '" << expectedHostAndPortes
- << "' to be selected.";
- auto errorDescription =
- std::make_pair("servers in latency window", errorMessage.str());
- result->errorDescriptions.push_back(errorDescription);
- return;
- }
+ return;
}
}
@@ -368,6 +447,8 @@ private:
TopologyDescriptionPtr _topologyDescription;
ReadPreferenceSetting _readPreference;
std::vector<ServerDescriptionPtr> _inLatencyWindow;
+ boost::optional<TestCaseResult> _parseError;
+ bool _errorExpected = false;
};
/**
@@ -382,29 +463,60 @@ public:
std::vector<JsonTestCase::TestCaseResult> results;
const auto testFiles = getTestFiles();
for (auto jsonTest : testFiles) {
- auto testCase = [jsonTest]() -> std::unique_ptr<JsonTestCase> {
- if (jsonTest.string().find("/rtt/")) {
- return std::make_unique<JsonRttTestCase>(jsonTest);
- }
- return std::make_unique<JsonServerSelectionTestCase>(jsonTest);
- }();
+ int restoreHeartBeatFrequencyMs = sdamHeartBeatFrequencyMs;
+ std::unique_ptr<JsonTestCase> testCase;
try {
+ testCase = [jsonTest]() -> std::unique_ptr<JsonTestCase> {
+ if (jsonTest.string().find("/rtt/") != std::string::npos ||
+ jsonTest.string().find("\\rtt\\") != std::string::npos) {
+ return std::make_unique<JsonRttTestCase>(jsonTest);
+ }
+ return std::make_unique<JsonServerSelectionTestCase>(jsonTest);
+ }();
LOGV2(
4333508, "### Executing Test ###", "testFilePath"_attr = testCase->FilePath());
- results.push_back(testCase->execute());
+ auto executionResult = testCase->execute();
+ if (testCase->errorIsExpected() && executionResult.Success()) {
+ auto errorDescription =
+ std::make_pair("failure expected", "Expected test to fail, but it didn't");
+ executionResult.errorDescriptions.push_back(errorDescription);
+ } else if (testCase->errorIsExpected() && !executionResult.Success()) {
+ // clear the errors, so that it's treated as a success
+ executionResult.errorDescriptions.clear();
+ }
+ results.push_back(executionResult);
} catch (const DBException& ex) {
- std::stringstream error;
- error << "Exception while executing " << jsonTest.string() << ": " << ex.toString();
- std::string errorStr = error.str();
- results.push_back(JsonTestCase::TestCaseResult{
- {std::make_pair("exception", errorStr)}, jsonTest.string()});
- std::cerr << errorStr;
+ if (!testCase || !testCase->errorIsExpected()) {
+ std::stringstream error;
+ error << "Exception while executing " << jsonTest.string() << ": "
+ << ex.toString();
+ std::string errorStr = error.str();
+ results.push_back(JsonTestCase::TestCaseResult{
+ {std::make_pair("exception", errorStr)}, jsonTest.string()});
+ std::cerr << errorStr;
+ }
}
+
+ // use default value of sdamHeartBeatFrequencyMs unless the test explicitly sets it.
+ sdamHeartBeatFrequencyMs = restoreHeartBeatFrequencyMs;
}
return results;
}
+ std::string collectErrorStr(const std::vector<JsonTestCase::TestErrors>& errors) {
+ std::string result;
+ for (size_t i = 0; i < errors.size(); ++i) {
+ auto error = errors[i];
+ result = result + error.first + " - " + error.second;
+ if (i != errors.size() - 1) {
+ result += "; ";
+ }
+ }
+ return result;
+ }
+
+
int report(std::vector<JsonTestCase::TestCaseResult> results) {
int numTestCases = results.size();
int numSuccess = 0;
@@ -417,12 +529,15 @@ public:
LOGV2(4333509, "### Failed Test Results ###");
}
- for (const auto result : results) {
+ for (const auto& result : results) {
auto file = result.file;
if (result.Success()) {
++numSuccess;
} else {
- LOGV2(4333510, "### Failed Test File ###", "testFilePath"_attr = file);
+ LOGV2(4333510,
+ "### Failed Test File ###",
+ "testFilePath"_attr = file,
+ "errors"_attr = collectErrorStr(result.errorDescriptions));
++numFailed;
}
}
diff --git a/src/mongo/client/sdam/server_selector.cpp b/src/mongo/client/sdam/server_selector.cpp
index 2c2e5a7409b..5fd51644005 100644
--- a/src/mongo/client/sdam/server_selector.cpp
+++ b/src/mongo/client/sdam/server_selector.cpp
@@ -32,6 +32,7 @@
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kNetwork
#include "mongo/client/sdam/topology_description.h"
+#include "mongo/db/wire_version.h"
#include "mongo/logv2/log.h"
#include "mongo/platform/random.h"
#include "mongo/util/fail_point.h"
@@ -76,9 +77,13 @@ void SdamServerSelector::_getCandidateServers(std::vector<ServerDescriptionPtr>*
}
switch (criteria.pref) {
- case ReadPreference::Nearest:
- *result = topologyDescription->findServers(nearestFilter(criteria));
+ case ReadPreference::Nearest: {
+ auto filter = (topologyDescription->getType() != TopologyType::kSharded)
+ ? nearestFilter(criteria)
+ : shardedFilter(criteria);
+ *result = topologyDescription->findServers(filter);
break;
+ }
case ReadPreference::SecondaryOnly:
*result = topologyDescription->findServers(secondaryFilter(criteria));
@@ -134,6 +139,15 @@ void SdamServerSelector::_getCandidateServers(std::vector<ServerDescriptionPtr>*
boost::optional<std::vector<ServerDescriptionPtr>> SdamServerSelector::selectServers(
const TopologyDescriptionPtr topologyDescription, const ReadPreferenceSetting& criteria) {
+ ReadPreferenceSetting effectiveCriteria = [&criteria](TopologyType topologyType) {
+ if (topologyType != TopologyType::kSharded) {
+ return criteria;
+ } else {
+ // Topology type Sharded should ignore read preference fields
+ return ReadPreferenceSetting(ReadPreference::Nearest);
+ };
+ }(topologyDescription->getType());
+
// If the topology wire version is invalid, raise an error
if (!topologyDescription->isWireVersionCompatible()) {
@@ -141,6 +155,11 @@ boost::optional<std::vector<ServerDescriptionPtr>> SdamServerSelector::selectSer
*topologyDescription->getWireVersionCompatibleError());
}
+ if (criteria.maxStalenessSeconds.count()) {
+ _verifyMaxstalenessLowerBound(topologyDescription, effectiveCriteria.maxStalenessSeconds);
+ _verifyMaxstalenessWireVersions(topologyDescription, effectiveCriteria.maxStalenessSeconds);
+ }
+
if (topologyDescription->getType() == TopologyType::kUnknown) {
return boost::none;
}
@@ -153,7 +172,7 @@ boost::optional<std::vector<ServerDescriptionPtr>> SdamServerSelector::selectSer
}
std::vector<ServerDescriptionPtr> results;
- _getCandidateServers(&results, topologyDescription, criteria);
+ _getCandidateServers(&results, topologyDescription, effectiveCriteria);
if (results.size()) {
if (MONGO_unlikely(sdamServerSelectorIgnoreLatencyWindow.shouldFail())) {
@@ -253,6 +272,33 @@ bool SdamServerSelector::recencyFilter(const ReadPreferenceSetting& readPref,
return result;
}
+void SdamServerSelector::_verifyMaxstalenessLowerBound(TopologyDescriptionPtr topologyDescription,
+ Seconds maxStalenessSeconds) {
+ static const auto kIdleWritePeriodMs = Milliseconds{10000};
+ auto topologyType = topologyDescription->getType();
+ if (topologyType == TopologyType::kReplicaSetWithPrimary ||
+ topologyType == TopologyType::kReplicaSetNoPrimary) {
+ const auto lowerBoundMs =
+ sdamHeartBeatFrequencyMs + durationCount<Milliseconds>(kIdleWritePeriodMs);
+
+ if (durationCount<Milliseconds>(maxStalenessSeconds) < lowerBoundMs) {
+ // using if to avoid creating the string if there's no error
+ std::stringstream ss;
+ ss << "Parameter maxStalenessSeconds cannot be less than "
+ << durationCount<Seconds>(Milliseconds{lowerBoundMs});
+ uassert(ErrorCodes::MaxStalenessOutOfRange, ss.str(), false);
+ }
+ }
+}
+
+void SdamServerSelector::_verifyMaxstalenessWireVersions(TopologyDescriptionPtr topologyDescription,
+ Seconds maxStalenessSeconds) {
+ for (auto& server : topologyDescription->getServers()) {
+ uassert(ErrorCodes::IncompatibleServerVersion,
+ "Incompatible wire version",
+ server->getMaxWireVersion() >= WireVersion::COMMANDS_ACCEPT_WRITE_CONCERN);
+ }
+}
void LatencyWindow::filterServers(std::vector<ServerDescriptionPtr>* servers) {
servers->erase(std::remove_if(servers->begin(),
diff --git a/src/mongo/client/sdam/server_selector.h b/src/mongo/client/sdam/server_selector.h
index 73fc26dcda5..8ce09ce43f8 100644
--- a/src/mongo/client/sdam/server_selector.h
+++ b/src/mongo/client/sdam/server_selector.h
@@ -111,10 +111,12 @@ private:
? *primaryDescription->getLastWriteDate()
: Date_t::min();
- auto result = (serverDescription->getLastUpdateTime() - lastWriteDate) -
- (primaryDescription->getLastUpdateTime() - primaryLastWriteDate) +
- _config.getHeartBeatFrequency();
- return duration_cast<Milliseconds>(result);
+ auto result = durationCount<Milliseconds>(
+ (serverDescription->getLastUpdateTime() - lastWriteDate)) -
+ durationCount<Milliseconds>(
+ (primaryDescription->getLastUpdateTime() - primaryLastWriteDate)) +
+ durationCount<Milliseconds>(_config.getHeartBeatFrequency());
+ return Milliseconds{result};
} else if (topologyDescription->getType() == TopologyType::kReplicaSetNoPrimary) {
// SMax.lastWriteDate - S.lastWriteDate + heartbeatFrequencyMS
Date_t maxLastWriteDate = Date_t::min();
@@ -132,14 +134,20 @@ private:
}
}
- auto result = (maxLastWriteDate - lastWriteDate) + _config.getHeartBeatFrequency();
- return duration_cast<Milliseconds>(result);
+ auto result = durationCount<Milliseconds>(maxLastWriteDate - lastWriteDate) +
+ durationCount<Milliseconds>(_config.getHeartBeatFrequency());
+ return Milliseconds{result};
} else {
// Not a replica set
return Milliseconds(0);
}
}
+ void _verifyMaxstalenessLowerBound(TopologyDescriptionPtr topologyDescription,
+ Seconds maxStalenessSeconds);
+ void _verifyMaxstalenessWireVersions(TopologyDescriptionPtr topologyDescription,
+ Seconds maxStalenessSeconds);
+
bool recencyFilter(const ReadPreferenceSetting& readPref, const ServerDescriptionPtr& s);
// A SelectionFilter is a higher order function used to filter out servers from the current
@@ -170,6 +178,10 @@ private:
};
};
+ const SelectionFilter shardedFilter = [this](const ReadPreferenceSetting& readPref) {
+ return [&](const ServerDescriptionPtr& s) { return s->getType() == ServerType::kMongos; };
+ };
+
SdamConfiguration _config;
mutable PseudoRandom _random;
};
diff --git a/src/mongo/client/sdam/server_selector_test.cpp b/src/mongo/client/sdam/server_selector_test.cpp
index b774f64b17c..80a06a92513 100644
--- a/src/mongo/client/sdam/server_selector_test.cpp
+++ b/src/mongo/client/sdam/server_selector_test.cpp
@@ -183,6 +183,31 @@ TEST_F(ServerSelectorTestFixture, ShouldReturnNoneIfTopologyUnknown) {
ASSERT_EQ(boost::none, selector.selectServers(topologyDescription, ReadPreferenceSetting()));
}
+TEST_F(ServerSelectorTestFixture, ShouldBeAbleToSelectWithMaxStalenessFromClonedTopology) {
+ TopologyStateMachine stateMachine(sdamConfiguration);
+ auto topologyDescription = std::make_shared<TopologyDescription>(sdamConfiguration);
+ auto primary = ServerDescriptionBuilder()
+ .withAddress(HostAndPort("s0"))
+ .withType(ServerType::kRSPrimary)
+ .withLastUpdateTime(Date_t::now())
+ .withLastWriteDate(Date_t::now())
+ .withRtt(Milliseconds{1})
+ .withSetName("set")
+ .withHost(HostAndPort("s0"))
+ .withMinWireVersion(WireVersion::SUPPORTS_OP_MSG)
+ .withMaxWireVersion(WireVersion::LATEST_WIRE_VERSION)
+ .instance();
+ stateMachine.onServerDescription(*topologyDescription, primary);
+ topologyDescription = TopologyDescription::clone(topologyDescription);
+
+ const auto ninetySeconds = Seconds(90);
+ const auto readPref =
+ ReadPreferenceSetting(ReadPreference::Nearest, TagSets::emptySet, ninetySeconds);
+ auto result = selector.selectServers(topologyDescription, readPref);
+ ASSERT(result);
+ ASSERT_EQ(primary->getAddress(), (*result)[0]->getAddress());
+}
+
TEST_F(ServerSelectorTestFixture, ShouldSelectRandomlyWhenMultipleOptionsAreAvailable) {
TopologyStateMachine stateMachine(sdamConfiguration);
auto topologyDescription = std::make_shared<TopologyDescription>(sdamConfiguration);
diff --git a/src/mongo/client/sdam/topology_description.cpp b/src/mongo/client/sdam/topology_description.cpp
index edf504f651b..2c576557a94 100644
--- a/src/mongo/client/sdam/topology_description.cpp
+++ b/src/mongo/client/sdam/topology_description.cpp
@@ -48,6 +48,19 @@ TopologyDescription::TopologyDescription(SdamConfiguration config)
}
}
+TopologyDescriptionPtr TopologyDescription::create(SdamConfiguration config) {
+ auto result = std::make_shared<TopologyDescription>(config);
+ TopologyDescription::associateServerDescriptions(result);
+ return result;
+}
+
+TopologyDescriptionPtr TopologyDescription::clone(TopologyDescriptionPtr source) {
+ invariant(source);
+ auto result = std::make_shared<TopologyDescription>(*source);
+ TopologyDescription::associateServerDescriptions(result);
+ return result;
+}
+
const UUID& TopologyDescription::getId() const {
return _id;
}
@@ -116,21 +129,22 @@ boost::optional<ServerDescriptionPtr> TopologyDescription::installServerDescript
// ServerDescription if the new topologyVersion is >= the old.
invariant(_servers.size() == 1);
previousDescription = _servers[0];
- _servers[0] = std::shared_ptr<ServerDescription>(newServerDescription);
+ _servers[0] = newServerDescription;
} else {
for (auto it = _servers.begin(); it != _servers.end(); ++it) {
const auto& currentDescription = *it;
if (currentDescription->getAddress() == newServerDescription->getAddress()) {
previousDescription = *it;
- *it = std::shared_ptr<ServerDescription>(newServerDescription);
+ *it = newServerDescription;
break;
}
}
if (!previousDescription) {
- _servers.push_back(std::shared_ptr<ServerDescription>(newServerDescription));
+ _servers.push_back(newServerDescription);
}
}
+
newServerDescription->_topologyDescription = shared_from_this();
checkWireCompatibilityVersions();
calculateLogicalSessionTimeout();
@@ -272,6 +286,13 @@ std::string TopologyDescription::toString() {
return toBSON().toString();
}
+void TopologyDescription::associateServerDescriptions(
+ const TopologyDescriptionPtr& topologyDescription) {
+ auto& servers = topologyDescription->_servers;
+ for (auto& server : servers) {
+ server->_topologyDescription = topologyDescription;
+ }
+}
boost::optional<ServerDescriptionPtr> TopologyDescription::getPrimary() {
if (getType() != TopologyType::kReplicaSetWithPrimary) {
diff --git a/src/mongo/client/sdam/topology_description.h b/src/mongo/client/sdam/topology_description.h
index b17e99e0bd8..2c1d75dc43c 100644
--- a/src/mongo/client/sdam/topology_description.h
+++ b/src/mongo/client/sdam/topology_description.h
@@ -52,6 +52,17 @@ public:
*/
TopologyDescription(SdamConfiguration config);
+ /**
+ * Factory function to create TopologyDescriptions.
+ */
+ static TopologyDescriptionPtr create(SdamConfiguration config);
+
+ /**
+ * Copy the given TopologyDescription and set the topologyDescription of all contained server
+ * descriptions to point to this instance.
+ */
+ static TopologyDescriptionPtr clone(TopologyDescriptionPtr source);
+
const UUID& getId() const;
TopologyType getType() const;
const boost::optional<std::string>& getSetName() const;
@@ -133,6 +144,8 @@ private:
*/
void calculateLogicalSessionTimeout();
+ static void associateServerDescriptions(const TopologyDescriptionPtr& topologyDescription);
+
// unique id for this topology
UUID _id = UUID::gen();
diff --git a/src/mongo/client/sdam/topology_manager.cpp b/src/mongo/client/sdam/topology_manager.cpp
index f991ea00155..2c5125b1a14 100644
--- a/src/mongo/client/sdam/topology_manager.cpp
+++ b/src/mongo/client/sdam/topology_manager.cpp
@@ -67,7 +67,7 @@ TopologyManager::TopologyManager(SdamConfiguration config,
TopologyEventsPublisherPtr eventsPublisher)
: _config(std::move(config)),
_clockSource(clockSource),
- _topologyDescription(std::make_shared<TopologyDescription>(_config)),
+ _topologyDescription(TopologyDescription::create(_config)),
_topologyStateMachine(std::make_unique<TopologyStateMachine>(_config)),
_topologyEventsPublisher(eventsPublisher) {}
@@ -101,7 +101,7 @@ bool TopologyManager::onServerDescription(const IsMasterOutcome& isMasterOutcome
_clockSource, isMasterOutcome, lastRTT, newTopologyVersion);
auto oldTopologyDescription = _topologyDescription;
- _topologyDescription = std::make_shared<TopologyDescription>(*oldTopologyDescription);
+ _topologyDescription = TopologyDescription::clone(oldTopologyDescription);
// if we are equal to the old description, just install the new description without
// performing any actions on the state machine.
@@ -131,7 +131,7 @@ void TopologyManager::onServerRTTUpdated(HostAndPort hostAndPort, IsMasterRTT rt
auto newServerDescription = (*oldServerDescription)->cloneWithRTT(rtt);
auto oldTopologyDescription = _topologyDescription;
- _topologyDescription = std::make_shared<TopologyDescription>(*_topologyDescription);
+ _topologyDescription = TopologyDescription::clone(oldTopologyDescription);
_topologyDescription->installServerDescription(newServerDescription);
_publishTopologyDescriptionChanged(oldTopologyDescription, _topologyDescription);
diff --git a/src/mongo/client/sdam/topology_manager_test.cpp b/src/mongo/client/sdam/topology_manager_test.cpp
index 2b65fda9d07..3ffe76fb0b5 100644
--- a/src/mongo/client/sdam/topology_manager_test.cpp
+++ b/src/mongo/client/sdam/topology_manager_test.cpp
@@ -47,6 +47,8 @@ protected:
static inline const auto kSetName = std::string("mySetName");
static inline const std::vector<HostAndPort> kOneServer{HostAndPort("foo:1234")};
+ static inline const std::vector<HostAndPort> kThreeServers{
+ HostAndPort("foo:1234"), HostAndPort("bar:1234"), HostAndPort("baz:1234")};
static BSONObjBuilder okBuilder() {
return std::move(BSONObjBuilder().append("ok", 1));
@@ -59,6 +61,17 @@ protected:
okBuilder().append("topologyVersion", TopologyVersion(OID::max(), 0).toBSON()).obj();
static inline const auto kBsonTopologyVersionHigh =
okBuilder().append("topologyVersion", TopologyVersion(OID::max(), 1).toBSON()).obj();
+ static inline const auto kBsonRsPrimary = okBuilder()
+ .append("ismaster", true)
+ .append("setName", kSetName)
+ .append("minWireVersion", 2)
+ .append("maxWireVersion", 10)
+ .appendArray("hosts",
+ BSON_ARRAY("foo:1234"
+ << "bar:1234"
+ << "baz:1234"))
+
+ .obj();
};
TEST_F(TopologyManagerTestFixture, ShouldUpdateTopologyVersionOnSuccess) {
@@ -91,6 +104,33 @@ TEST_F(TopologyManagerTestFixture, ShouldUpdateTopologyVersionOnSuccess) {
kBsonTopologyVersionHigh.getObjectField("topologyVersion"));
}
+TEST_F(TopologyManagerTestFixture,
+ ShouldUpdateServerDescriptionsTopologyDescriptionPtrWhenTopologyDescriptionIsInstalled) {
+ auto checkServerTopologyDescriptionMatches = [](TopologyDescriptionPtr topologyDescription) {
+ auto rawTopologyDescPtr = topologyDescription.get();
+ for (auto server : topologyDescription->getServers()) {
+ auto rawServerTopologyDescPtr = (*server->getTopologyDescription()).get();
+ ASSERT(server->getTopologyDescription());
+ ASSERT(rawServerTopologyDescPtr == rawTopologyDescPtr);
+ }
+ };
+
+ auto config = SdamConfiguration(kThreeServers);
+ TopologyManager topologyManager(config, clockSource);
+ checkServerTopologyDescriptionMatches(topologyManager.getTopologyDescription());
+
+ auto topologyDescription = topologyManager.getTopologyDescription();
+ auto firstServer = *topologyDescription->getServers()[0];
+ auto host = firstServer.getAddress();
+ auto isMasterOutcome =
+ IsMasterOutcome(host, kBsonRsPrimary, duration_cast<IsMasterRTT>(mongo::Milliseconds{40}));
+ topologyManager.onServerDescription(isMasterOutcome);
+ checkServerTopologyDescriptionMatches(topologyManager.getTopologyDescription());
+
+ topologyManager.onServerRTTUpdated(host, Milliseconds{40});
+ checkServerTopologyDescriptionMatches(topologyManager.getTopologyDescription());
+}
+
TEST_F(TopologyManagerTestFixture, ShouldUpdateTopologyVersionOnErrorIfSent) {
auto config = SdamConfiguration(kOneServer);
TopologyManager topologyManager(config, clockSource);