From 47e6cb1ab679836c41d8536eb1da9730397bc152 Mon Sep 17 00:00:00 2001 From: Sergey Zelenov Date: Mon, 23 Mar 2026 11:19:50 +0100 Subject: [PATCH] test(NODE-7462): add spec tests for disaggregated storage --- .../rs/disaggregated_storage_setversion.json | 167 +++++++++++++ .../rs/disaggregated_storage_setversion.yml | 118 +++++++++ ...h_unchanged_setversion_and_electionid.json | 227 ++++++++++++++++++ ...th_unchanged_setversion_and_electionid.yml | 161 +++++++++++++ .../migration_from_disaggregated_storage.json | 167 +++++++++++++ .../migration_from_disaggregated_storage.yml | 119 +++++++++ .../migration_to_disaggregated_storage.json | 119 +++++++++ .../rs/migration_to_disaggregated_storage.yml | 85 +++++++ 8 files changed, 1163 insertions(+) create mode 100644 test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.json create mode 100644 test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.yml create mode 100644 test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.json create mode 100644 test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.yml create mode 100644 test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.json create mode 100644 test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.yml create mode 100644 test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.json create mode 100644 test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.yml diff --git a/test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.json b/test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.json new file mode 100644 index 00000000000..c8b41d30ca3 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.json @@ -0,0 +1,167 @@ +{ + "description": "Static setVersion (DSC) is compatible with both pre and post DRIVERS-2412", + "uri": "mongodb://a/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000005" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ], + [ + "b:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": false, + "secondary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000005" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000005" + } + } + }, + { + "responses": [ + [ + "b:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000006" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "Unknown", + "setName": null, + "setVersion": null, + "electionId": null + }, + "b:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000006" + } + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000006" + } + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000005" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "Unknown", + "setName": null, + "setVersion": null, + "electionId": null + }, + "b:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000006" + } + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000006" + } + } + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.yml b/test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.yml new file mode 100644 index 00000000000..c20b0027ab9 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/disaggregated_storage_setversion.yml @@ -0,0 +1,118 @@ +# Disaggregated storage clusters use a constant setVersion (typically 1) instead of +# incrementing it on each reconfig. This test validates that primary staleness detection +# works correctly using electionId when setVersion doesn't change. +description: Static setVersion (DSC) is compatible with both pre and post DRIVERS-2412 +uri: "mongodb://a/?replicaSet=rs" +phases: + # Phase 1: Initial state - A is primary with electionId=5, setVersion=1 + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000005"} + minWireVersion: 0 + maxWireVersion: 17 + - + - "b:27017" + - ok: 1 + helloOk: true + isWritablePrimary: false + secondary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000005"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000005"} + # Phase 2: B becomes primary with newer electionId=6, but setVersion stays at 1 + # The driver should accept B as the new primary and mark A as Unknown + - responses: + - + - "b:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000006"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: Unknown + setName: null + setVersion: null + electionId: null + b:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000006"} + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000006"} + # Phase 3: Old primary A tries to come back with stale electionId=5 + # Even though setVersion is still 1 (unchanged), the driver should reject A + # because its electionId is older than the current maxElectionId=6 + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000005"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: Unknown + setName: null + setVersion: null + electionId: null + b:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000006"} + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000006"} diff --git a/test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.json b/test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.json new file mode 100644 index 00000000000..0045591db95 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.json @@ -0,0 +1,227 @@ +{ + "description": "Member list is updated when setVersion and electionId remain the same", + "uri": "mongodb://a/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ], + [ + "b:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": false, + "secondary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017", + "c:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + }, + "c:27017": { + "type": "Unknown", + "setName": null, + "setVersion": null, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } + } + }, + { + "responses": [ + [ + "c:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": false, + "secondary": true, + "hosts": [ + "a:27017", + "b:27017", + "c:27017" + ], + "setName": "rs", + "setVersion": 1, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + }, + "c:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000001" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000001" + } + } + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.yml b/test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.yml new file mode 100644 index 00000000000..7920c7e06b7 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/member_list_update_with_unchanged_setversion_and_electionid.yml @@ -0,0 +1,161 @@ +# This test validates that the member list (hosts) is updated even when +# setVersion and electionId remain unchanged. +description: Member list is updated when setVersion and electionId remain the same +uri: "mongodb://a/?replicaSet=rs" +phases: + # Phase 1: Initial state - A is primary with two members (a, b) + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + minWireVersion: 0 + maxWireVersion: 17 + - + - "b:27017" + - ok: 1 + helloOk: true + isWritablePrimary: false + secondary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000001"} + # Phase 2: Primary reports a new member c has been added, but setVersion and + # electionId remain unchanged. The driver should add c to the topology. + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + - "c:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + c:27017: + type: Unknown + setName: null + setVersion: null + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000001"} + # Phase 3: c responds and becomes a secondary + - responses: + - + - "c:27017" + - ok: 1 + helloOk: true + isWritablePrimary: false + secondary: true + hosts: + - "a:27017" + - "b:27017" + - "c:27017" + setName: rs + setVersion: 1 + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + c:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000001"} + # Phase 4: Primary reports c has been removed, but setVersion and + # electionId remain unchanged. The driver should remove c from the topology. + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000001"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000001"} + diff --git a/test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.json b/test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.json new file mode 100644 index 00000000000..c5109026bc2 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.json @@ -0,0 +1,167 @@ +{ + "description": "DSC to ASC reverse migration - ASC primary with higher setVersion is accepted", + "uri": "mongodb://a/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000005" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ], + [ + "b:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": false, + "secondary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000005" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 1, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1, + "maxElectionId": { + "$oid": "000000000000000000000005" + } + } + }, + { + "responses": [ + [ + "b:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1000, + "electionId": { + "$oid": "000000000000000000000006" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "Unknown", + "setName": null, + "setVersion": null, + "electionId": null + }, + "b:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1000, + "electionId": { + "$oid": "000000000000000000000006" + } + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1000, + "maxElectionId": { + "$oid": "000000000000000000000006" + } + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 1, + "electionId": { + "$oid": "000000000000000000000005" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "Unknown", + "setName": null, + "setVersion": null, + "electionId": null + }, + "b:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 1000, + "electionId": { + "$oid": "000000000000000000000006" + } + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 1000, + "maxElectionId": { + "$oid": "000000000000000000000006" + } + } + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.yml b/test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.yml new file mode 100644 index 00000000000..6bb88f0fc1a --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/migration_from_disaggregated_storage.yml @@ -0,0 +1,119 @@ +# When migrating from disaggregated storage (constant setVersion) back to a +# traditional replica set (incrementing setVersion), a force reconfig is used +# with a high setVersion value to ensure the driver accepts the new primary. +description: DSC to ASC reverse migration - ASC primary with higher setVersion is accepted +uri: "mongodb://a/?replicaSet=rs" +phases: + # Phase 1: Disaggregated storage cluster with constant setVersion=1 + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000005"} + minWireVersion: 0 + maxWireVersion: 17 + - + - "b:27017" + - ok: 1 + helloOk: true + isWritablePrimary: false + secondary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000005"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 1 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1 + maxElectionId: {"$oid": "000000000000000000000005"} + # Phase 2: After migration to traditional replica set, B becomes primary with + # setVersion=1000 (force reconfig with high value) and newer electionId=6 + # The driver should accept B as the new primary due to higher setVersion + - responses: + - + - "b:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1000 + electionId: {"$oid": "000000000000000000000006"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: Unknown + setName: null + setVersion: null + electionId: null + b:27017: + type: RSPrimary + setName: rs + setVersion: 1000 + electionId: {"$oid": "000000000000000000000006"} + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1000 + maxElectionId: {"$oid": "000000000000000000000006"} + # Phase 3: Old disaggregated storage primary A tries to come back + # The driver should reject it because both setVersion (1 < 1000) and + # electionId (5 < 6) are stale + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 1 + electionId: {"$oid": "000000000000000000000005"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: Unknown + setName: null + setVersion: null + electionId: null + b:27017: + type: RSPrimary + setName: rs + setVersion: 1000 + electionId: {"$oid": "000000000000000000000006"} + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 1000 + maxElectionId: {"$oid": "000000000000000000000006"} diff --git a/test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.json b/test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.json new file mode 100644 index 00000000000..57f39c93b29 --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.json @@ -0,0 +1,119 @@ +{ + "description": "ASC to DSC forward migration - DSC uses setVersionASC + 1 to prevent false stale detection", + "uri": "mongodb://a/?replicaSet=rs", + "phases": [ + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 10, + "electionId": { + "$oid": "000000000000000000000005" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ], + [ + "b:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": false, + "secondary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 10, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 10, + "electionId": { + "$oid": "000000000000000000000005" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 10, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 10, + "maxElectionId": { + "$oid": "000000000000000000000005" + } + } + }, + { + "responses": [ + [ + "a:27017", + { + "ok": 1, + "helloOk": true, + "isWritablePrimary": true, + "hosts": [ + "a:27017", + "b:27017" + ], + "setName": "rs", + "setVersion": 11, + "electionId": { + "$oid": "000000000000000000000006" + }, + "minWireVersion": 0, + "maxWireVersion": 17 + } + ] + ], + "outcome": { + "servers": { + "a:27017": { + "type": "RSPrimary", + "setName": "rs", + "setVersion": 11, + "electionId": { + "$oid": "000000000000000000000006" + } + }, + "b:27017": { + "type": "RSSecondary", + "setName": "rs", + "setVersion": 10, + "electionId": null + } + }, + "topologyType": "ReplicaSetWithPrimary", + "logicalSessionTimeoutMinutes": null, + "setName": "rs", + "maxSetVersion": 11, + "maxElectionId": { + "$oid": "000000000000000000000006" + } + } + } + ] +} diff --git a/test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.yml b/test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.yml new file mode 100644 index 00000000000..a798392dc9d --- /dev/null +++ b/test/spec/server-discovery-and-monitoring/rs/migration_to_disaggregated_storage.yml @@ -0,0 +1,85 @@ +# When migrating from a traditional replica set (incrementing setVersion) to +# disaggregated storage (constant setVersion), the migration uses setVersionASC + 1 +# to prevent the driver from incorrectly marking the new primary as stale. +description: ASC to DSC forward migration - DSC uses setVersionASC + 1 to prevent false stale detection +uri: "mongodb://a/?replicaSet=rs" +phases: + # Phase 1: Traditional replica set with incrementing setVersion=10 + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 10 + electionId: {"$oid": "000000000000000000000005"} + minWireVersion: 0 + maxWireVersion: 17 + - + - "b:27017" + - ok: 1 + helloOk: true + isWritablePrimary: false + secondary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 10 + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 10 + electionId: {"$oid": "000000000000000000000005"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 10 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 10 + maxElectionId: {"$oid": "000000000000000000000005"} + # Phase 2: After migration to disaggregated storage, setVersion becomes 11 (10 + 1) + # This ensures the driver sees a newer setVersion and accepts the new primary, + # even though future reconfigs will keep setVersion constant at 11 + - responses: + - + - "a:27017" + - ok: 1 + helloOk: true + isWritablePrimary: true + hosts: + - "a:27017" + - "b:27017" + setName: rs + setVersion: 11 + electionId: {"$oid": "000000000000000000000006"} + minWireVersion: 0 + maxWireVersion: 17 + outcome: + servers: + a:27017: + type: RSPrimary + setName: rs + setVersion: 11 + electionId: {"$oid": "000000000000000000000006"} + b:27017: + type: RSSecondary + setName: rs + setVersion: 10 + electionId: null + topologyType: ReplicaSetWithPrimary + logicalSessionTimeoutMinutes: null + setName: rs + maxSetVersion: 11 + maxElectionId: {"$oid": "000000000000000000000006"}