231 lines
8.8 KiB
JavaScript
231 lines
8.8 KiB
JavaScript
/**
|
|
* Tests upgrading a standalone node or replica set through several major versions.
|
|
*
|
|
* For each version downloaded by the multiversion setup:
|
|
* - Start a node or replica set of that version, without clearing data files from the previous
|
|
* iteration.
|
|
* - Create a new collection.
|
|
* - Insert a document into the new collection.
|
|
* - Create an index on the new collection.
|
|
*
|
|
* @tags: [requires_v4_0]
|
|
*/
|
|
|
|
import "jstests/multiVersion/libs/multi_rs.js";
|
|
import "jstests/multiVersion/libs/verify_versions.js";
|
|
|
|
import {IndexCatalogHelpers} from "jstests/libs/index_catalog_helpers.js";
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
// Setup the dbpath for this test.
|
|
const dbpath = MongoRunner.dataPath + "major_version_upgrade";
|
|
resetDbpath(dbpath);
|
|
|
|
// We set noCleanData to true in order to preserve the data files between iterations.
|
|
const defaultOptions = {
|
|
dbpath: dbpath,
|
|
noCleanData: true,
|
|
};
|
|
|
|
// This lists all supported releases and needs to be kept up to date as versions are added and
|
|
// dropped.
|
|
// TODO SERVER-76166: Programmatically generate list of LTS versions.
|
|
const versions = [
|
|
{binVersion: "6.0", featureCompatibilityVersion: "6.0", testCollection: "six_zero"},
|
|
{binVersion: "7.0", featureCompatibilityVersion: "7.0", testCollection: "seven_zero"},
|
|
{binVersion: "last-lts", featureCompatibilityVersion: lastLTSFCV, testCollection: "last_lts"},
|
|
{
|
|
binVersion: "last-continuous",
|
|
featureCompatibilityVersion: lastContinuousFCV,
|
|
testCollection: "last_continuous",
|
|
},
|
|
{binVersion: "latest", featureCompatibilityVersion: latestFCV, testCollection: "latest"},
|
|
];
|
|
|
|
// Standalone
|
|
// Iterate from earliest to latest versions specified in the versions list, and follow the steps
|
|
// outlined at the top of this test file.
|
|
for (let i = 0; i < versions.length; i++) {
|
|
let version = versions[i];
|
|
let mongodOptions = Object.extend({binVersion: version.binVersion}, defaultOptions);
|
|
|
|
// Start a mongod with specified version.
|
|
let conn = null;
|
|
try {
|
|
conn = MongoRunner.runMongod(mongodOptions);
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
assert.neq(null, conn, "mongod was unable to start up with options: " + tojson(mongodOptions));
|
|
assert.binVersion(conn, version.binVersion);
|
|
|
|
// Connect to the 'test' database.
|
|
let testDB = conn.getDB("test");
|
|
|
|
// Verify that the data and indices from previous iterations are still accessible.
|
|
for (let j = 0; j < i; j++) {
|
|
let oldVersionCollection = versions[j].testCollection;
|
|
assert.eq(
|
|
1,
|
|
testDB[oldVersionCollection].count(),
|
|
`data from ${oldVersionCollection} should be available; options: ` + tojson(mongodOptions),
|
|
);
|
|
assert.neq(
|
|
null,
|
|
IndexCatalogHelpers.findByKeyPattern(testDB[oldVersionCollection].getIndexes(), {a: 1}),
|
|
`index from ${oldVersionCollection} should be available; options: ` + tojson(mongodOptions),
|
|
);
|
|
}
|
|
|
|
// Create a new collection.
|
|
assert.commandWorked(testDB.createCollection(version.testCollection));
|
|
|
|
// Insert a document into the new collection.
|
|
assert.commandWorked(testDB[version.testCollection].insert({a: 1}));
|
|
assert.eq(
|
|
1,
|
|
testDB[version.testCollection].count(),
|
|
`mongo should have inserted 1 document into collection ${version.testCollection}; ` +
|
|
"options: " +
|
|
tojson(mongodOptions),
|
|
);
|
|
|
|
// Create an index on the new collection.
|
|
assert.commandWorked(testDB[version.testCollection].createIndex({a: 1}));
|
|
|
|
// Set the appropriate featureCompatibilityVersion upon upgrade, if applicable.
|
|
if (version.hasOwnProperty("featureCompatibilityVersion")) {
|
|
let adminDB = conn.getDB("admin");
|
|
const res = adminDB.runCommand({"setFeatureCompatibilityVersion": version.featureCompatibilityVersion});
|
|
if (!res.ok && res.code === 7369100) {
|
|
// We failed due to requiring 'confirm: true' on the command. This will only
|
|
// occur on 7.0+ nodes that have 'enableTestCommands' set to false. Retry the
|
|
// setFCV command with 'confirm: true'.
|
|
assert.commandWorked(
|
|
adminDB.runCommand({
|
|
"setFeatureCompatibilityVersion": version.featureCompatibilityVersion,
|
|
confirm: true,
|
|
}),
|
|
);
|
|
} else {
|
|
assert.commandWorked(res);
|
|
}
|
|
}
|
|
|
|
// Shutdown the current mongod.
|
|
MongoRunner.stopMongod(conn);
|
|
}
|
|
|
|
// Replica Sets
|
|
// Setup the ReplSetTest object.
|
|
let nodes = {
|
|
n1: {binVersion: versions[0].binVersion},
|
|
n2: {binVersion: versions[0].binVersion},
|
|
n3: {binVersion: versions[0].binVersion},
|
|
};
|
|
let rst = new ReplSetTest({nodes});
|
|
|
|
// Start up and initiate the replica set.
|
|
rst.startSet();
|
|
rst.initiate();
|
|
|
|
// Iterate from earliest to latest versions specified in the versions list, and follow the steps
|
|
// outlined at the top of this test file.
|
|
for (let i = 0; i < versions.length; i++) {
|
|
let version = versions[i];
|
|
|
|
// Connect to the primary running the old version to ensure that the test can insert and
|
|
// create indices.
|
|
let primary = rst.getPrimary();
|
|
|
|
// Upgrade the secondary nodes first.
|
|
rst.upgradeSecondaries({binVersion: version.binVersion});
|
|
|
|
assert.eq(primary, rst.getPrimary(), "Primary changed unexpectedly after upgrading secondaries");
|
|
assert.neq(
|
|
null,
|
|
primary,
|
|
`replica set was unable to start up after upgrading secondaries to version: ${version.binVersion}`,
|
|
);
|
|
|
|
// Connect to the 'test' database.
|
|
let testDB = primary.getDB("test");
|
|
assert.commandWorked(testDB.createCollection(version.testCollection));
|
|
assert.commandWorked(testDB[version.testCollection].insert({a: 1}));
|
|
assert.eq(
|
|
1,
|
|
testDB[version.testCollection].count(),
|
|
`mongo should have inserted 1 document into collection ${version.testCollection}; ` + "nodes: " + tojson(nodes),
|
|
);
|
|
|
|
// Create an index on the new collection.
|
|
assert.commandWorked(testDB[version.testCollection].createIndex({a: 1}));
|
|
|
|
// Do the index creation and insertion again after upgrading the primary node.
|
|
primary = rst.upgradePrimary(primary, {binVersion: version.binVersion});
|
|
assert.neq(null, primary, `replica set was unable to start up with version: ${version.binVersion}`);
|
|
assert.binVersion(primary, version.binVersion);
|
|
testDB = primary.getDB("test");
|
|
|
|
assert.commandWorked(testDB[version.testCollection].insert({b: 1}));
|
|
assert.eq(
|
|
2,
|
|
testDB[version.testCollection].count(),
|
|
`mongo should have inserted 2 documents into collection ${version.testCollection}; ` +
|
|
"nodes: " +
|
|
tojson(nodes),
|
|
);
|
|
|
|
assert.commandWorked(testDB[version.testCollection].createIndex({b: 1}));
|
|
|
|
// Verify that all previously inserted data and indices are accessible.
|
|
for (let j = 0; j <= i; j++) {
|
|
let oldVersionCollection = versions[j].testCollection;
|
|
assert.eq(
|
|
2,
|
|
testDB[oldVersionCollection].count(),
|
|
`data from ${oldVersionCollection} should be available; nodes: ${tojson(nodes)}`,
|
|
);
|
|
assert.neq(
|
|
null,
|
|
IndexCatalogHelpers.findByKeyPattern(testDB[oldVersionCollection].getIndexes(), {a: 1}),
|
|
`index from ${oldVersionCollection} should be available; nodes: ${tojson(nodes)}`,
|
|
);
|
|
assert.neq(
|
|
null,
|
|
IndexCatalogHelpers.findByKeyPattern(testDB[oldVersionCollection].getIndexes(), {b: 1}),
|
|
`index from ${oldVersionCollection} should be available; nodes: ${tojson(nodes)}`,
|
|
);
|
|
}
|
|
|
|
// Set the appropriate featureCompatibilityVersion upon upgrade, if applicable.
|
|
if (version.hasOwnProperty("featureCompatibilityVersion")) {
|
|
let primaryAdminDB = primary.getDB("admin");
|
|
const res = primaryAdminDB.runCommand({"setFeatureCompatibilityVersion": version.featureCompatibilityVersion});
|
|
if (!res.ok && res.code === 7369100) {
|
|
// We failed due to requiring 'confirm: true' on the command. This will only
|
|
// occur on 7.0+ nodes that have 'enableTestCommands' set to false. Retry the
|
|
// setFCV command with 'confirm: true'.
|
|
assert.commandWorked(
|
|
primaryAdminDB.runCommand({
|
|
"setFeatureCompatibilityVersion": version.featureCompatibilityVersion,
|
|
confirm: true,
|
|
}),
|
|
);
|
|
} else {
|
|
assert.commandWorked(res);
|
|
}
|
|
rst.awaitReplication();
|
|
|
|
// Make sure we reach the new featureCompatibilityVersion in the committed snapshot on
|
|
// on all nodes before continuing to upgrade.
|
|
for (let n of rst.nodes) {
|
|
checkFCV(n.getDB("admin"), version.featureCompatibilityVersion);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Stop the replica set.
|
|
rst.stopSet();
|