summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorPavi Vetriselvan <pavithra.vetriselvan@mongodb.com>2021-03-31 22:52:25 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-04-08 18:25:51 +0000
commitf1ac83b03c330d1ef59dd13e55aeddf3c6d41b4b (patch)
tree976cf5d925750e8e9698a2d58f6930751166b4ba /jstests
parent60f2db4bd2f1bad10f1c92f3eb0b626eca933477 (diff)
downloadmongo-f1ac83b03c330d1ef59dd13e55aeddf3c6d41b4b.tar.gz
SERVER-54829 Avoid crashing during kUpgrading/kDowngrading state if config has incompatible field name
Diffstat (limited to 'jstests')
-rw-r--r--jstests/multiVersion/stepdown_interrupts_setFCV_before_reconfig.js102
1 files changed, 102 insertions, 0 deletions
diff --git a/jstests/multiVersion/stepdown_interrupts_setFCV_before_reconfig.js b/jstests/multiVersion/stepdown_interrupts_setFCV_before_reconfig.js
new file mode 100644
index 00000000000..962484d5b27
--- /dev/null
+++ b/jstests/multiVersion/stepdown_interrupts_setFCV_before_reconfig.js
@@ -0,0 +1,102 @@
+/**
+ * Tests a scenario where stepdown interrupts the setFCV command after transitioning to the
+ * intermediary kUpgrading/kDowngrading state but before the reconfig to change the delay field
+ * name. In this state, a subsequent stepup attempt may have an FCV incompatible field name.
+ * Since we are expected to run the setFCV command to finish the upgrade/downgrade procedure,
+ * the delay field name will eventually be changed to the correct value, so it's safe to
+ * temporarily skip the FCV compatibility check for stepup reconfigs instead of crashing the
+ * server.
+ *
+ */
+
+(function() {
+"use strict";
+
+load("jstests/libs/parallel_shell_helpers.js");
+load("jstests/libs/fail_point_util.js");
+
+function runSetFCV(targetVersion) {
+ assert.commandFailedWithCode(db.adminCommand({setFeatureCompatibilityVersion: targetVersion}),
+ ErrorCodes.InterruptedDueToReplStateChange);
+}
+
+function checkForSecondaryDelaySecs(primary) {
+ let config = primary.adminCommand({replSetGetConfig: 1}).config;
+ assert.eq(config.members[0].secondaryDelaySecs, 0, config);
+ assert(!config.members[0].hasOwnProperty('slaveDelay'), config);
+}
+
+function checkForSlaveDelay(primary) {
+ let config = primary.adminCommand({replSetGetConfig: 1}).config;
+ assert.eq(config.members[0].slaveDelay, 0, config);
+ assert(!config.members[0].hasOwnProperty('secondaryDelaySecs'), config);
+}
+
+const replTest = new ReplSetTest({name: jsTestName(), nodes: 1});
+replTest.startSet();
+replTest.initiateWithHighElectionTimeout();
+let primary = replTest.getPrimary();
+
+jsTestLog("Testing stepdown interrupting FCV downgrade.");
+// Enable failpoint to hang after transitioning to kDowngrading.
+let failpoint = configureFailPoint(primary, 'hangAfterStartingFCVTransition');
+let setFCVThread = startParallelShell(funWithArgs(runSetFCV, lastLTSFCV), primary.port);
+failpoint.wait();
+
+// Verify the node is in a partially downgraded state by checking that the 'targetVersion'
+// was set to 'lastLTSFCV'.
+checkFCV(primary.getDB("admin"), lastLTSFCV /* version */, lastLTSFCV /* targetVersion */);
+
+// Interrupt the setFCV command with a stepdown.
+assert.commandWorked(primary.adminCommand({replSetStepDown: 1, force: true}));
+failpoint.off();
+setFCVThread();
+replTest.waitForState(primary, ReplSetTest.State.SECONDARY);
+
+// The automatic reconfig on stepup should be able to succeed, resulting in the
+// 'secondaryDelaySecs' field still being present in the config even though we're in the
+// kDowngrading FCV.
+replTest.stepUp(primary);
+primary = replTest.getPrimary();
+checkForSecondaryDelaySecs(primary);
+
+jsTestLog("Complete FCV downgrade.");
+assert.commandWorked(primary.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV}));
+
+// Verify the feature compatibility version transition is complete. Once we've completed the
+// downgrade, the delay field should have been properly renamed to 'slaveDelay'.
+checkFCV(primary.getDB("admin"), lastLTSFCV);
+checkForSlaveDelay(primary);
+
+jsTestLog("Testing stepdown interrupting FCV upgrade.");
+// Enable failpoint to hang after transitioning to kUpgrading.
+failpoint = configureFailPoint(primary, 'hangAfterStartingFCVTransition');
+setFCVThread = startParallelShell(funWithArgs(runSetFCV, latestFCV), primary.port);
+failpoint.wait();
+
+// Verify the node is in a partially upgraded state by checking that the 'targetVersion'
+// was set to 'latestFCV'.
+checkFCV(primary.getDB("admin"), lastLTSFCV /* version */, latestFCV /* targetVersion */);
+
+// Interrupt the setFCV command with a stepdown.
+assert.commandWorked(primary.adminCommand({replSetStepDown: 1, force: true}));
+failpoint.off();
+setFCVThread();
+replTest.waitForState(primary, ReplSetTest.State.SECONDARY);
+
+// The automatic reconfig on stepup should be able to succeed, resulting in the 'slaveDelay'
+// field still being present in the config even though we're in the kUpgrading FCV.
+replTest.stepUp(primary);
+primary = replTest.getPrimary();
+checkForSlaveDelay(primary);
+
+jsTestLog("Complete FCV upgrade.");
+assert.commandWorked(primary.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
+
+// Verify the feature compatibility version transition is complete. Once we've completed the
+// upgrade, the delay field should have been properly renamed to 'secondaryDelaySecs'.
+checkFCV(primary.getDB("admin"), latestFCV);
+checkForSecondaryDelaySecs(primary);
+
+replTest.stopSet();
+}());