Files
mongo/jstests/multiVersion/genericSetFCVUsage/set_fcv_downgrade_on_disk_changes.js

248 lines
9.8 KiB
JavaScript

/**
* Unified test that makes sure calling setFeatureCompatibilityVersion with
* {downgradeOnDiskChanges: true} is able to successfully downgrade all expected on-disk changes in
* one invocation.
*/
(function() {
"use strict";
load('jstests/multiVersion/libs/multi_rs.js');
load('jstests/multiVersion/libs/multi_cluster.js');
let dbpath = MongoRunner.dataPath + jsTestName();
resetDbpath(dbpath);
const latest = "latest";
const lastContinuous = "last-continuous";
/**
* Each new feature that adds downgrade logic to the setFeatureCompatibilityVersion command with
* {downgradeOnDiskChanges: true} should add their test cases to this test file. Each test case
* should follow this 'dummyTest' template and implement the following three test functions:
* this.onDiskChangesBeforeDowngrade: This function will be called before the FCV downgrade to
* introduce durable on-disk changes that will be downgraded as part the FCV downgrade.
* this.validateAfterFCVDowngrade: This function will be called after the FCV downgrade to validate
* the downgrade of the incompatible on-disk changes introduced in onDiskChangesBeforeDowngrade.
* this.validateAfterBinaryDowngrade: This function will be called after the binary downgrade to
* 'last-continuous' binaries to validate the downgrade of the incompatible on-disk changes
* introduced in onDiskChangesBeforeDowngrade.
*
* Each new test should also be added to the downgradeOnDiskChangesTests list below.
*/
function dummyTest() {
const documents = [{_id: "dummy"}];
this.onDiskChangesBeforeDowngrade = function(conn) {
jsTestLog("Running onDiskChangesBeforeDowngrade of dummyTest");
let testDB = conn.getDB("test");
assert.commandWorked(testDB.runCommand({insert: "dummy", documents: documents}));
};
this.validateAfterFCVDowngrade = function(conn) {
jsTestLog("Running validateAfterFCVDowngrade of dummyTest");
let testDB = conn.getDB("test");
let res = testDB.dummy.find({});
assert.sameMembers(res.toArray(), documents, () => tojson(res));
};
this.validateAfterBinaryDowngrade = function(conn) {
jsTestLog("Running validateAfterBinaryDowngrade of dummyTest");
this.validateAfterFCVDowngrade(conn);
};
}
const downgradeOnDiskChangesTests = [
new dummyTest(),
];
function runStandaloneTest() {
jsTestLog("Running standalone test");
let conn;
let adminDB;
// A 'latest' binary standalone should default to 'latestFCV'.
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest});
assert.neq(
null, conn, "mongod was unable to start up with version=" + latest + " and no data files");
adminDB = conn.getDB("admin");
checkFCV(adminDB, latestFCV);
jsTestLog("Introducing on-disk changes to be downgraded in FCV downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.onDiskChangesBeforeDowngrade(conn);
}
jsTestLog(
"Test that setFeatureCompatibilityVersion succeeds with {downgradeOnDiskChanges: true}");
assert.commandWorked(adminDB.runCommand(
{setFeatureCompatibilityVersion: lastContinuousFCV, downgradeOnDiskChanges: true}));
checkFCV(adminDB, lastContinuousFCV);
checkLog.contains(conn, "Downgrading on-disk format");
jsTestLog("Validating on-disk changes after FCV downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.validateAfterFCVDowngrade(conn);
}
MongoRunner.stopMongod(conn);
// Test that the node can restart with a last-continuous binary.
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: lastContinuous, noCleanData: true});
assert.neq(null,
conn,
"mongod was unable to start up with binary version=" + lastContinuous +
" and featureCompatibilityVersion=" + lastContinuousFCV);
adminDB = conn.getDB("admin");
checkFCV(adminDB, lastContinuousFCV);
jsTestLog("Validating on-disk changes after binary downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.validateAfterBinaryDowngrade(conn);
}
MongoRunner.stopMongod(conn);
// Test that the node can restart with a latest binary.
conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest, noCleanData: true});
assert.neq(null,
conn,
"mongod was unable to start up with binary version=" + latest +
" and featureCompatibilityVersion=" + lastContinuousFCV);
adminDB = conn.getDB("admin");
checkFCV(adminDB, lastContinuousFCV);
// Test that the FCV can be upgraded back to 'latestFCV'.
assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: latestFCV}));
checkFCV(adminDB, latestFCV);
MongoRunner.stopMongod(conn);
}
function runReplicaSetTest() {
jsTestLog("Running replica set test");
// 'latest' binary replica set.
let rst = new ReplSetTest({nodes: 2, nodeOpts: {binVersion: latest}});
rst.startSet();
rst.initiateWithHighElectionTimeout();
let primaryAdminDB = rst.getPrimary().getDB("admin");
let secondaryAdminDB = rst.getSecondary().getDB("admin");
// FCV should default to 'latestFCV' on primary and secondary in a 'latest' binary replica set.
checkFCV(primaryAdminDB, latestFCV);
rst.awaitReplication();
checkFCV(secondaryAdminDB, latestFCV);
jsTestLog("Introducing on-disk changes to be downgraded in FCV downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.onDiskChangesBeforeDowngrade(rst.getPrimary());
}
jsTestLog(
"Test that setFeatureCompatibilityVersion succeeds with {downgradeOnDiskChanges: true} " +
"and propogates to the secondary");
assert.commandWorked(primaryAdminDB.runCommand(
{setFeatureCompatibilityVersion: lastContinuousFCV, downgradeOnDiskChanges: true}));
checkFCV(primaryAdminDB, lastContinuousFCV);
rst.awaitReplication();
checkFCV(secondaryAdminDB, lastContinuousFCV);
jsTestLog("Validating on-disk changes after FCV downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.validateAfterFCVDowngrade(rst.getPrimary());
}
// Test that the cluster can restart with a last-continuous binary.
rst.upgradeSet({binVersion: lastContinuous});
primaryAdminDB = rst.getPrimary().getDB("admin");
secondaryAdminDB = rst.getSecondary().getDB("admin");
checkFCV(primaryAdminDB, lastContinuousFCV);
checkFCV(secondaryAdminDB, lastContinuousFCV);
jsTestLog("Validating on-disk changes after binary downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.validateAfterBinaryDowngrade(rst.getPrimary());
}
// Test that the cluster can restart with a latest binary.
rst.upgradeSet({binVersion: latest});
primaryAdminDB = rst.getPrimary().getDB("admin");
secondaryAdminDB = rst.getSecondary().getDB("admin");
checkFCV(primaryAdminDB, lastContinuousFCV);
checkFCV(secondaryAdminDB, lastContinuousFCV);
// Test that the FCV can be upgraded back to 'latestFCV'.
assert.commandWorked(primaryAdminDB.runCommand({setFeatureCompatibilityVersion: latestFCV}));
checkFCV(primaryAdminDB, latestFCV);
rst.awaitReplication();
checkFCV(secondaryAdminDB, latestFCV);
rst.stopSet();
}
function runShardingTest() {
jsTestLog("Running sharding test");
// A 'latest' binary cluster started with clean data files will set FCV to 'latestFCV'.
let st =
new ShardingTest({shards: {rs0: {nodes: [{binVersion: latest}, {binVersion: latest}]}}});
let mongosAdminDB = st.s.getDB("admin");
let configPrimaryAdminDB = st.configRS.getPrimary().getDB("admin");
let shardPrimaryAdminDB = st.rs0.getPrimary().getDB("admin");
checkFCV(configPrimaryAdminDB, latestFCV);
checkFCV(shardPrimaryAdminDB, latestFCV);
jsTestLog("Introducing on-disk changes to be downgraded in FCV downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.onDiskChangesBeforeDowngrade(st.s);
}
jsTestLog(
"Test that setFeatureCompatibilityVersion succeeds with {downgradeOnDiskChanges: true} " +
"on mongos");
assert.commandWorked(mongosAdminDB.runCommand(
{setFeatureCompatibilityVersion: lastContinuousFCV, downgradeOnDiskChanges: true}));
// FCV propagates to config and shard.
checkFCV(configPrimaryAdminDB, lastContinuousFCV);
checkFCV(shardPrimaryAdminDB, lastContinuousFCV);
jsTestLog("Validating on-disk changes after FCV downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.validateAfterFCVDowngrade(st.s);
}
// Test that the cluster can restart with a last-continuous binary.
st.upgradeCluster(lastContinuous, {waitUntilStable: true});
configPrimaryAdminDB = st.configRS.getPrimary().getDB("admin");
shardPrimaryAdminDB = st.rs0.getPrimary().getDB("admin");
checkFCV(configPrimaryAdminDB, lastContinuousFCV);
checkFCV(shardPrimaryAdminDB, lastContinuousFCV);
jsTestLog("Validating on-disk changes after binary downgrade");
for (let test of downgradeOnDiskChangesTests) {
test.validateAfterBinaryDowngrade(st.s);
}
// Test that the cluster can restart with a latest binary.
st.upgradeCluster(latest, {waitUntilStable: true});
configPrimaryAdminDB = st.configRS.getPrimary().getDB("admin");
shardPrimaryAdminDB = st.rs0.getPrimary().getDB("admin");
checkFCV(configPrimaryAdminDB, lastContinuousFCV);
checkFCV(shardPrimaryAdminDB, lastContinuousFCV);
// Test that the FCV can be upgraded back to 'latestFCV'.
mongosAdminDB = st.s.getDB("admin");
assert.commandWorked(mongosAdminDB.runCommand({setFeatureCompatibilityVersion: latestFCV}));
checkFCV(configPrimaryAdminDB, latestFCV);
checkFCV(shardPrimaryAdminDB, latestFCV);
st.stop();
}
runStandaloneTest();
runReplicaSetTest();
runShardingTest();
})();