diff --git a/test/discovery_and_monitoring/rs/compatible_unknown.json b/test/discovery_and_monitoring/rs/compatible_unknown.json new file mode 100644 index 000000000..1105da876 --- /dev/null +++ b/test/discovery_and_monitoring/rs/compatible_unknown.json @@ -0,0 +1,39 @@ +{ + "description": "Replica set member and an unknown server", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "b:27017": { + "type": "Unknown" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "setName": "rs", + "logicalSessionTimeoutMinutes": null, + "compatible": true + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/equal_electionids.json b/test/discovery_and_monitoring/rs/equal_electionids.json index 8a5aa8cd6..f8d20b350 100644 --- a/test/discovery_and_monitoring/rs/equal_electionids.json +++ b/test/discovery_and_monitoring/rs/equal_electionids.json @@ -60,7 +60,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } } ] diff --git a/test/discovery_and_monitoring/rs/incompatible_arbiter.json b/test/discovery_and_monitoring/rs/incompatible_arbiter.json new file mode 100644 index 000000000..aa582208d --- /dev/null +++ b/test/discovery_and_monitoring/rs/incompatible_arbiter.json @@ -0,0 +1,54 @@ +{ + "description": "Incompatible arbiter", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 6 + } + ], + [ + "b:27017", + { + "ok": 1, + "arbiterOnly": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 1 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "b:27017": { + "type": "RSArbiter", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "setName": "rs", + "logicalSessionTimeoutMinutes": null, + "compatible": false + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/incompatible_ghost.json b/test/discovery_and_monitoring/rs/incompatible_ghost.json new file mode 100644 index 000000000..088159c3a --- /dev/null +++ b/test/discovery_and_monitoring/rs/incompatible_ghost.json @@ -0,0 +1,49 @@ +{ + "description": "Incompatible ghost", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 6 + } + ], + [ + "b:27017", + { + "ok": 1, + "isreplicaset": true, + "minWireVersion": 0, + "maxWireVersion": 1 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "b:27017": { + "type": "RSGhost", + "setName": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "setName": "rs", + "logicalSessionTimeoutMinutes": null, + "compatible": false + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/incompatible_other.json b/test/discovery_and_monitoring/rs/incompatible_other.json new file mode 100644 index 000000000..b65d674b4 --- /dev/null +++ b/test/discovery_and_monitoring/rs/incompatible_other.json @@ -0,0 +1,54 @@ +{ + "description": "Incompatible other", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 6 + } + ], + [ + "b:27017", + { + "ok": 1, + "hidden": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 1 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "b:27017": { + "type": "RSOther", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "setName": "rs", + "logicalSessionTimeoutMinutes": null, + "compatible": false + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/new_primary_new_electionid.json b/test/discovery_and_monitoring/rs/new_primary_new_electionid.json index cd6c37cef..67f314b1e 100644 --- a/test/discovery_and_monitoring/rs/new_primary_new_electionid.json +++ b/test/discovery_and_monitoring/rs/new_primary_new_electionid.json @@ -41,7 +41,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -83,7 +87,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -125,7 +133,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } } ] diff --git a/test/discovery_and_monitoring/rs/new_primary_new_setversion.json b/test/discovery_and_monitoring/rs/new_primary_new_setversion.json index c5828171d..c1ec50c84 100644 --- a/test/discovery_and_monitoring/rs/new_primary_new_setversion.json +++ b/test/discovery_and_monitoring/rs/new_primary_new_setversion.json @@ -41,7 +41,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -83,7 +87,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -125,7 +133,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } } ] diff --git a/test/discovery_and_monitoring/rs/null_election_id.json b/test/discovery_and_monitoring/rs/null_election_id.json index d4348df44..3de0a74e4 100644 --- a/test/discovery_and_monitoring/rs/null_election_id.json +++ b/test/discovery_and_monitoring/rs/null_election_id.json @@ -42,7 +42,8 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1 } }, { @@ -90,7 +91,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -133,7 +138,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -179,7 +188,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } } ] diff --git a/test/discovery_and_monitoring/rs/primary_becomes_ghost.json b/test/discovery_and_monitoring/rs/primary_becomes_ghost.json new file mode 100644 index 000000000..897120f1f --- /dev/null +++ b/test/discovery_and_monitoring/rs/primary_becomes_ghost.json @@ -0,0 +1,59 @@ +{ + "description": "Primary becomes ghost", + "uri": "mongodb://a/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "hosts": [ + "a:27017" + ], + "setName": "rs", + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": false, + "isreplicaset": true, + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSGhost", + "setName": null + } + }, + "topologyType": "ReplicaSetNoPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/primary_becomes_mongos.json b/test/discovery_and_monitoring/rs/primary_becomes_mongos.json new file mode 100644 index 000000000..8d4967b7d --- /dev/null +++ b/test/discovery_and_monitoring/rs/primary_becomes_mongos.json @@ -0,0 +1,54 @@ +{ + "description": "Primary becomes mongos", + "uri": "mongodb://a/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "hosts": [ + "a:27017" + ], + "setName": "rs", + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "msg": "isdbgrid", + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": {}, + "topologyType": "ReplicaSetNoPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/primary_disconnect_electionid.json b/test/discovery_and_monitoring/rs/primary_disconnect_electionid.json index e81f29908..59c8faf18 100644 --- a/test/discovery_and_monitoring/rs/primary_disconnect_electionid.json +++ b/test/discovery_and_monitoring/rs/primary_disconnect_electionid.json @@ -59,7 +59,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -84,7 +88,11 @@ }, "topologyType": "ReplicaSetNoPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -123,7 +131,11 @@ }, "topologyType": "ReplicaSetNoPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -165,7 +177,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000003" + } } }, { @@ -203,7 +219,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000003" + } } } ] diff --git a/test/discovery_and_monitoring/rs/primary_disconnect_setversion.json b/test/discovery_and_monitoring/rs/primary_disconnect_setversion.json index d0e55c545..beb023e4f 100644 --- a/test/discovery_and_monitoring/rs/primary_disconnect_setversion.json +++ b/test/discovery_and_monitoring/rs/primary_disconnect_setversion.json @@ -59,7 +59,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -84,7 +88,11 @@ }, "topologyType": "ReplicaSetNoPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -123,7 +131,11 @@ }, "topologyType": "ReplicaSetNoPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -165,7 +177,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } }, { @@ -203,7 +219,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000002" + } } } ] diff --git a/test/discovery_and_monitoring/rs/primary_mismatched_me_not_removed.json b/test/discovery_and_monitoring/rs/primary_mismatched_me_not_removed.json new file mode 100644 index 000000000..a9e01987c --- /dev/null +++ b/test/discovery_and_monitoring/rs/primary_mismatched_me_not_removed.json @@ -0,0 +1,77 @@ +{ + "description": "Primary mismatched me is not removed", + "uri": "mongodb://localhost:27017,localhost:27018/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "localhost:27017", + { + "ok": 1, + "hosts": [ + "localhost:27017", + "localhost:27018" + ], + "ismaster": true, + "setName": "rs", + "primary": "localhost:27017", + "me": "a:27017", + "minWireVersion": 0, + "maxWireVersion": 7 + } + ] + ], + "outcome": { + "servers": { + "localhost:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "localhost:27018": { + "type": "Unknown", + "setName": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "localhost:27018", + { + "ok": 1, + "hosts": [ + "localhost:27017", + "localhost:27018" + ], + "ismaster": false, + "secondary": true, + "setName": "rs", + "primary": "localhost:27017", + "me": "localhost:27018", + "minWireVersion": 0, + "maxWireVersion": 7 + } + ] + ], + "outcome": { + "servers": { + "localhost:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "localhost:27018": { + "type": "RSSecondary", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/repeated.json b/test/discovery_and_monitoring/rs/repeated.json new file mode 100644 index 000000000..392d48579 --- /dev/null +++ b/test/discovery_and_monitoring/rs/repeated.json @@ -0,0 +1,140 @@ +{ + "description": "Repeated ismaster response must be processed", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": false, + "secondary": true, + "hidden": true, + "hosts": [ + "a:27017", + "c:27017" + ], + "setName": "rs", + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSOther", + "setName": "rs" + }, + "b:27017": { + "type": "Unknown" + }, + "c:27017": { + "type": "Unknown" + } + }, + "topologyType": "ReplicaSetNoPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "c:27017", + { + "ok": 1, + "ismaster": true, + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSOther", + "setName": "rs" + }, + "b:27017": { + "type": "Unknown" + } + }, + "topologyType": "ReplicaSetNoPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": false, + "secondary": true, + "hidden": true, + "hosts": [ + "a:27017", + "c:27017" + ], + "setName": "rs", + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSOther", + "setName": "rs" + }, + "b:27017": { + "type": "Unknown" + }, + "c:27017": { + "type": "Unknown" + } + }, + "topologyType": "ReplicaSetNoPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "c:27017", + { + "ok": 1, + "ismaster": true, + "hosts": [ + "a:27017", + "c:27017" + ], + "setName": "rs", + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSOther", + "setName": "rs" + }, + "c:27017": { + "type": "RSPrimary", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/secondary_ignore_ok_0.json b/test/discovery_and_monitoring/rs/secondary_ignore_ok_0.json new file mode 100644 index 000000000..6d3033eee --- /dev/null +++ b/test/discovery_and_monitoring/rs/secondary_ignore_ok_0.json @@ -0,0 +1,81 @@ +{ + "description": "New primary", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 6 + } + ], + [ + "b:27017", + { + "ok": 1, + "ismaster": false, + "secondary": true, + "setName": "rs", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs" + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + }, + { + "responses": [ + [ + "b:27017", + { + "ok": 0, + "minWireVersion": 0, + "maxWireVersion": 6 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs" + }, + "b:27017": { + "type": "Unknown", + "setName": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs" + } + } + ] +} diff --git a/test/discovery_and_monitoring/rs/setversion_without_electionid.json b/test/discovery_and_monitoring/rs/setversion_without_electionid.json index dbd9765d2..0500c6d15 100644 --- a/test/discovery_and_monitoring/rs/setversion_without_electionid.json +++ b/test/discovery_and_monitoring/rs/setversion_without_electionid.json @@ -36,7 +36,8 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2 } }, { @@ -73,7 +74,8 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2 } } ] diff --git a/test/discovery_and_monitoring/rs/use_setversion_without_electionid.json b/test/discovery_and_monitoring/rs/use_setversion_without_electionid.json index 19e1727bf..16225d6b8 100644 --- a/test/discovery_and_monitoring/rs/use_setversion_without_electionid.json +++ b/test/discovery_and_monitoring/rs/use_setversion_without_electionid.json @@ -41,7 +41,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -77,7 +81,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } }, { @@ -116,7 +124,11 @@ }, "topologyType": "ReplicaSetWithPrimary", "logicalSessionTimeoutMinutes": null, - "setName": "rs" + "setName": "rs", + "maxSetVersion": 2, + "maxElectionId": { + "$oid": "000000000000000000000001" + } } } ] diff --git a/test/sdam_monitoring/replica_set_with_no_primary.json b/test/sdam_monitoring/replica_set_with_no_primary.json index 2f398a85f..33010d49f 100644 --- a/test/sdam_monitoring/replica_set_with_no_primary.json +++ b/test/sdam_monitoring/replica_set_with_no_primary.json @@ -14,7 +14,8 @@ "setVersion": 1, "primary": "b:27017", "hosts": [ - "a:27017", "b:27017" + "a:27017", + "b:27017" ], "minWireVersion": 0, "maxWireVersion": 4 @@ -83,7 +84,8 @@ "address": "a:27017", "arbiters": [], "hosts": [ - "a:27017", "b:27017" + "a:27017", + "b:27017" ], "passives": [], "primary": "b:27017", @@ -122,7 +124,8 @@ "address": "a:27017", "arbiters": [], "hosts": [ - "a:27017", "b:27017" + "a:27017", + "b:27017" ], "passives": [], "primary": "b:27017", @@ -134,7 +137,7 @@ "arbiters": [], "hosts": [], "passives": [], - "type": "Unknown" + "type": "PossiblePrimary" } ] } diff --git a/test/sdam_monitoring/replica_set_with_primary.json b/test/sdam_monitoring/replica_set_with_primary.json index 6c0d8819d..04caeba65 100644 --- a/test/sdam_monitoring/replica_set_with_primary.json +++ b/test/sdam_monitoring/replica_set_with_primary.json @@ -13,7 +13,8 @@ "setVersion": 1, "primary": "a:27017", "hosts": [ - "a:27017", "b:27017" + "a:27017", + "b:27017" ], "minWireVersion": 0, "maxWireVersion": 4 @@ -82,7 +83,8 @@ "address": "a:27017", "arbiters": [], "hosts": [ - "a:27017", "b:27017" + "a:27017", + "b:27017" ], "passives": [], "primary": "a:27017", diff --git a/test/sdam_monitoring/replica_set_with_removal.json b/test/sdam_monitoring/replica_set_with_removal.json index a14456cdb..3cad92d6b 100644 --- a/test/sdam_monitoring/replica_set_with_removal.json +++ b/test/sdam_monitoring/replica_set_with_removal.json @@ -3,30 +3,7 @@ "uri": "mongodb://a,b/", "phases": [ { - "responses": [ - [ - "a:27017", - { - "ok": 1, - "ismaster": true, - "setName": "rs", - "setVersion": 1, - "primary": "a:27017", - "hosts": [ - "a:27017" - ], - "minWireVersion": 0, - "maxWireVersion": 4 - } - ], - [ - "b:27017", - { - "ok": 1, - "ismaster": true - } - ] - ], + "responses": [], "outcome": { "events": [ { @@ -73,7 +50,37 @@ "topologyId": "42", "address": "b:27017" } - }, + } + ] + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "setVersion": 1, + "primary": "a:27017", + "hosts": [ + "a:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 4 + } + ], + [ + "b:27017", + { + "ok": 1, + "ismaster": true + } + ] + ], + "outcome": { + "events": [ { "server_description_changed_event": { "topologyId": "42", diff --git a/test/sdam_monitoring/required_replica_set.json b/test/sdam_monitoring/required_replica_set.json index 0afe0d1a4..0f64bde11 100644 --- a/test/sdam_monitoring/required_replica_set.json +++ b/test/sdam_monitoring/required_replica_set.json @@ -1,149 +1,151 @@ { - "description": "Monitoring a topology that is required to be a replica set", - "phases": [ - { - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "newDescription": { - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ], - "topologyType": "ReplicaSetNoPrimary" - }, - "previousDescription": { - "servers": [], - "topologyType": "Unknown" - }, - "topologyId": "42" - } - }, - { - "server_opening_event": { - "address": "a:27017", - "topologyId": "42" - } - }, - { - "server_opening_event": { - "address": "b:27017", - "topologyId": "42" - } - }, - { - "server_description_changed_event": { - "address": "a:27017", - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - }, - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "newDescription": { - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [ - "a:27017", - "b:27017" - ], - "passives": [], - "primary": "a:27017", - "setName": "rs", - "type": "RSPrimary" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ], - "setName": "rs", - "topologyType": "ReplicaSetWithPrimary" - }, - "previousDescription": { - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - { - "address": "b:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ], - "topologyType": "ReplicaSetNoPrimary" - }, - "topologyId": "42" - } - } + "description": "Monitoring a topology that is required to be a replica set", + "uri": "mongodb://a,b/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "setName": "rs", + "setVersion": 1, + "primary": "a:27017", + "hosts": [ + "a:27017", + "b:27017" + ], + "minWireVersion": 0, + "maxWireVersion": 4 + } + ] + ], + "outcome": { + "events": [ + { + "topology_opening_event": { + "topologyId": "42" + } + }, + { + "topology_description_changed_event": { + "topologyId": "42", + "previousDescription": { + "topologyType": "Unknown", + "servers": [] + }, + "newDescription": { + "topologyType": "ReplicaSetNoPrimary", + "setName": "rs", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + }, + { + "address": "b:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } ] - }, - "responses": [ - [ - "a:27017", - { - "hosts": [ - "a:27017", - "b:27017" - ], - "ismaster": true, - "maxWireVersion": 4, - "minWireVersion": 0, - "ok": 1, - "primary": "a:27017", - "setName": "rs", - "setVersion": 1.0 - } + } + } + }, + { + "server_opening_event": { + "topologyId": "42", + "address": "a:27017" + } + }, + { + "server_opening_event": { + "topologyId": "42", + "address": "b:27017" + } + }, + { + "server_description_changed_event": { + "topologyId": "42", + "address": "a:27017", + "previousDescription": { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + }, + "newDescription": { + "address": "a:27017", + "arbiters": [], + "hosts": [ + "a:27017", + "b:27017" + ], + "passives": [], + "primary": "a:27017", + "setName": "rs", + "type": "RSPrimary" + } + } + }, + { + "topology_description_changed_event": { + "topologyId": "42", + "previousDescription": { + "topologyType": "ReplicaSetNoPrimary", + "setName": "rs", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + }, + { + "address": "b:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } ] - ] - } - ], - "uri": "mongodb://a,b/?replicaSet=rs" + }, + "newDescription": { + "topologyType": "ReplicaSetWithPrimary", + "setName": "rs", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [ + "a:27017", + "b:27017" + ], + "passives": [], + "primary": "a:27017", + "setName": "rs", + "type": "RSPrimary" + }, + { + "address": "b:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } + ] + } + } + } + ] + } + } + ] } diff --git a/test/sdam_monitoring/standalone.json b/test/sdam_monitoring/standalone.json index 1ca3c3c24..5d40286c9 100644 --- a/test/sdam_monitoring/standalone.json +++ b/test/sdam_monitoring/standalone.json @@ -1,104 +1,104 @@ { - "description": "Monitoring a standalone connection", - "phases": [ - { - "outcome": { - "events": [ - { - "topology_opening_event": { - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "newDescription": { - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ], - "topologyType": "Single" - }, - "previousDescription": { - "servers": [], - "topologyType": "Unknown" - }, - "topologyId": "42" - } - }, - { - "server_opening_event": { - "address": "a:27017", - "topologyId": "42" - } - }, - { - "server_description_changed_event": { - "address": "a:27017", - "newDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Standalone" - }, - "previousDescription": { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - }, - "topologyId": "42" - } - }, - { - "topology_description_changed_event": { - "newDescription": { - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Standalone" - } - ], - "topologyType": "Single" - }, - "previousDescription": { - "servers": [ - { - "address": "a:27017", - "arbiters": [], - "hosts": [], - "passives": [], - "type": "Unknown" - } - ], - "topologyType": "Single" - }, - "topologyId": "42" - } - } + "description": "Monitoring a standalone connection", + "uri": "mongodb://a:27017", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "minWireVersion": 0, + "maxWireVersion": 4 + } + ] + ], + "outcome": { + "events": [ + { + "topology_opening_event": { + "topologyId": "42" + } + }, + { + "topology_description_changed_event": { + "topologyId": "42", + "previousDescription": { + "topologyType": "Unknown", + "servers": [] + }, + "newDescription": { + "topologyType": "Single", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } ] - }, - "responses": [ - [ - "a:27017", - { - "ismaster": true, - "maxWireVersion": 4, - "minWireVersion": 0, - "ok": 1 - } + } + } + }, + { + "server_opening_event": { + "topologyId": "42", + "address": "a:27017" + } + }, + { + "server_description_changed_event": { + "topologyId": "42", + "address": "a:27017", + "previousDescription": { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + }, + "newDescription": { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Standalone" + } + } + }, + { + "topology_description_changed_event": { + "topologyId": "42", + "previousDescription": { + "topologyType": "Single", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } ] - ] - } - ], - "uri": "mongodb://a:27017" + }, + "newDescription": { + "topologyType": "Single", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Standalone" + } + ] + } + } + } + ] + } + } + ] } diff --git a/test/sdam_monitoring/standalone_suppress_equal_description_changes.json b/test/sdam_monitoring/standalone_suppress_equal_description_changes.json new file mode 100644 index 000000000..a4b2d10da --- /dev/null +++ b/test/sdam_monitoring/standalone_suppress_equal_description_changes.json @@ -0,0 +1,113 @@ +{ + "description": "Monitoring a standalone connection - suppress update events for equal server descriptions", + "uri": "mongodb://a:27017", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "minWireVersion": 0, + "maxWireVersion": 4 + } + ], + [ + "a:27017", + { + "ok": 1, + "ismaster": true, + "minWireVersion": 0, + "maxWireVersion": 4 + } + ] + ], + "outcome": { + "events": [ + { + "topology_opening_event": { + "topologyId": "42" + } + }, + { + "topology_description_changed_event": { + "topologyId": "42", + "previousDescription": { + "topologyType": "Unknown", + "servers": [] + }, + "newDescription": { + "topologyType": "Single", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } + ] + } + } + }, + { + "server_opening_event": { + "topologyId": "42", + "address": "a:27017" + } + }, + { + "server_description_changed_event": { + "topologyId": "42", + "address": "a:27017", + "previousDescription": { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + }, + "newDescription": { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Standalone" + } + } + }, + { + "topology_description_changed_event": { + "topologyId": "42", + "previousDescription": { + "topologyType": "Single", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Unknown" + } + ] + }, + "newDescription": { + "topologyType": "Single", + "servers": [ + { + "address": "a:27017", + "arbiters": [], + "hosts": [], + "passives": [], + "type": "Standalone" + } + ] + } + } + } + ] + } + } + ] +} diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 05bef0de2..cb17104cd 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -30,7 +30,8 @@ from pymongo.server_description import ServerDescription, SERVER_TYPE from pymongo.settings import TopologySettings from pymongo.uri_parser import parse_uri from test import unittest -from test.utils import MockPool +from test.utils import (MockPool, + server_name_to_type) # Location of JSON test specifications. @@ -121,15 +122,7 @@ def check_outcome(self, topology, outcome): self.assertTrue(topology.has_server(node)) actual_server = topology.get_server_by_address(node) actual_server_description = actual_server.description - - if expected_server['type'] == 'PossiblePrimary': - # Special case, some tests in the spec include the PossiblePrimary - # type, but only single-threaded drivers need that type. We call - # possible primaries Unknown. - expected_server_type = SERVER_TYPE.Unknown - else: - expected_server_type = getattr( - SERVER_TYPE, expected_server['type']) + expected_server_type = server_name_to_type(expected_server['type']) self.assertEqual( server_type_name(expected_server_type), diff --git a/test/test_sdam_monitoring_spec.py b/test/test_sdam_monitoring_spec.py index 574111097..0d181bb75 100644 --- a/test/test_sdam_monitoring_spec.py +++ b/test/test_sdam_monitoring_spec.py @@ -17,24 +17,23 @@ import json import os import sys -import weakref +import time sys.path[0:0] = [""] from bson.json_util import object_hook from pymongo import monitoring -from pymongo import periodic_executor +from pymongo.common import clean_node from pymongo.errors import (ConnectionFailure, NotMasterError) from pymongo.ismaster import IsMaster from pymongo.monitor import Monitor -from pymongo.read_preferences import MovingAverage from pymongo.server_description import ServerDescription -from pymongo.server_type import SERVER_TYPE from pymongo.topology_description import TOPOLOGY_TYPE from test import unittest, client_context, client_knobs, IntegrationTest from test.utils import (ServerAndTopologyEventListener, single_client, + server_name_to_type, rs_or_single_client, wait_until) @@ -46,7 +45,7 @@ _TEST_PATH = os.path.join( def compare_server_descriptions(expected, actual): if ((not expected['address'] == "%s:%s" % actual.address) or - (not SERVER_TYPE.__getattribute__(expected['type']) == + (not server_name_to_type(expected['type']) == actual.server_type)): return False expected_hosts = set( @@ -179,62 +178,56 @@ class TestAllScenarios(unittest.TestCase): def create_test(scenario_def): def run_scenario(self): - responses = (r for r in scenario_def['phases'][0]['responses']) + with client_knobs(events_queue_frequency=0.1): + _run_scenario(self) - with client_knobs(events_queue_frequency=0.1, - heartbeat_frequency=0.1, - min_heartbeat_interval=0.1): - class MockMonitor(Monitor): - """Override the _run method""" - def _run(self): - try: - if self._server_description.address != ('a', 27017): - # Because PyMongo doesn't keep information about - # the order of addresses, we might accidentally - # start a MockMonitor on the wrong server first, - # so we need to only mock responses for the server - # the test's response is supposed to come from. - return - response = next(responses)[1] - isMaster = IsMaster(response) - self._server_description = ServerDescription( - address=self._server_description.address, - ismaster=isMaster) - self._topology.on_change(self._server_description) - except (ReferenceError, StopIteration): - # Topology was garbage-collected. - self.close() + def _run_scenario(self): + class NoopMonitor(Monitor): + """Override the _run method to do nothing.""" + def _run(self): + time.sleep(0.05) - m = single_client(h=scenario_def['uri'], p=27017, - event_listeners=(self.all_listener,), - _monitor_class=MockMonitor) - - expected_results = scenario_def['phases'][0]['outcome']['events'] - - expected_len = len(expected_results) - wait_until(lambda: len(self.all_listener.results) >= expected_len, - "publish all events", timeout=15) + m = single_client(h=scenario_def['uri'], p=27017, + event_listeners=[self.all_listener], + _monitor_class=NoopMonitor) + topology = m._get_topology() try: - i = 0 - while i < expected_len: - result = self.all_listener.results[i] if len( - self.all_listener.results) > i else None - # The order of ServerOpening/ClosedEvents doesn't matter - if (isinstance(result, - monitoring.ServerOpeningEvent) or - isinstance(result, - monitoring.ServerClosedEvent)): - i, passed, message = compare_multiple_events( - i, expected_results, self.all_listener.results) - self.assertTrue(passed, message) - else: - self.assertTrue( - *compare_events(expected_results[i], result)) - i += 1 + for phase in scenario_def['phases']: + for (source, response) in phase['responses']: + source_address = clean_node(source) + topology.on_change(ServerDescription( + address=source_address, + ismaster=IsMaster(response), + round_trip_time=0)) + expected_results = phase['outcome']['events'] + expected_len = len(expected_results) + wait_until( + lambda: len(self.all_listener.results) >= expected_len, + "publish all events", timeout=15) + + i = 0 + while i < expected_len: + result = self.all_listener.results[i] if len( + self.all_listener.results) > i else None + # The order of ServerOpening/ClosedEvents doesn't matter + if (isinstance(result, + monitoring.ServerOpeningEvent) or + isinstance(result, + monitoring.ServerClosedEvent)): + i, passed, message = compare_multiple_events( + i, expected_results, self.all_listener.results) + self.assertTrue(passed, message) + else: + self.assertTrue( + *compare_events(expected_results[i], result)) + i += 1 + + self.all_listener.reset() finally: m.close() + return run_scenario diff --git a/test/utils.py b/test/utils.py index 77e08fc4e..c1f7b9a57 100644 --- a/test/utils.py +++ b/test/utils.py @@ -40,6 +40,7 @@ from pymongo.read_concern import ReadConcern from pymongo.read_preferences import ReadPreference from pymongo.server_selectors import (any_server_selector, writable_server_selector) +from pymongo.server_type import SERVER_TYPE from pymongo.write_concern import WriteConcern from test import (client_context, @@ -868,4 +869,14 @@ def parse_read_preference(pref): max_staleness = pref.get('maxStalenessSeconds', -1) tag_sets = pref.get('tag_sets') return read_preferences.make_read_preference( - mode, tag_sets=tag_sets, max_staleness=max_staleness) \ No newline at end of file + mode, tag_sets=tag_sets, max_staleness=max_staleness) + + +def server_name_to_type(name): + """Convert a ServerType name to the corresponding value. For SDAM tests.""" + # Special case, some tests in the spec include the PossiblePrimary + # type, but only single-threaded drivers need that type. We call + # possible primaries Unknown. + if name == 'PossiblePrimary': + return SERVER_TYPE.Unknown + return getattr(SERVER_TYPE, name)