mirror of https://github.com/mongodb/mongo
121 lines
4.5 KiB
JavaScript
121 lines
4.5 KiB
JavaScript
/**
|
|
* Tests collection contents are preserved across upgrade/downgrade when ident generation changes
|
|
* across versions.
|
|
*/
|
|
import "jstests/multiVersion/libs/verify_versions.js";
|
|
import "jstests/multiVersion/libs/multi_rs.js";
|
|
|
|
import {assertDropAndRecreateCollection} from "jstests/libs/collection_drop_recreate.js";
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
const lastLTSVersion = {
|
|
binVersion: "last-lts",
|
|
};
|
|
const latestVersion = {
|
|
binVersion: "latest",
|
|
};
|
|
|
|
const dbName = jsTestName();
|
|
// The set of documents expected for each collection in 'dbName'.
|
|
const docs = [
|
|
{_id: 0, x: 0},
|
|
{_id: 1, x: 1},
|
|
];
|
|
const getDB = (primaryConnection) => primaryConnection.getDB(dbName);
|
|
|
|
// Prints collection idents for collections in the 'dbName' database.
|
|
function printIdents(node) {
|
|
const identsResult = node
|
|
.getDB("admin")
|
|
.aggregate([{$listCatalog: {}}, {$match: {db: dbName}}, {$project: {ns: 1, ident: 1, idxIdent: 1}}])
|
|
.toArray();
|
|
jsTestLog(`Collection idents on ${node.port}: ${tojson(identsResult)}`);
|
|
}
|
|
|
|
// Given a list of 'collNames', asserts the corresponding collection exists and contains 'docs' on
|
|
// each node of the replica set.
|
|
function validateCollectionContents(rst, collNames) {
|
|
rst.awaitReplication();
|
|
rst.nodes.forEach((node) => {
|
|
printIdents(node, dbName);
|
|
for (let collName of collNames) {
|
|
const coll = getDB(node)[collName];
|
|
const foundDocs = coll.find().toArray();
|
|
assert.sameMembers(
|
|
docs,
|
|
foundDocs,
|
|
`Expected collection ${collName} on ${node.host} to contain all docs: ${tojson(
|
|
docs,
|
|
)}. Found docs: ${tojson(foundDocs)}`,
|
|
);
|
|
}
|
|
});
|
|
rst.checkReplicatedDataHashes();
|
|
}
|
|
|
|
function setupCollection(rst, collName) {
|
|
const primaryConnection = rst.getPrimary();
|
|
const coll = assertDropAndRecreateCollection(getDB(primaryConnection), collName);
|
|
assert.commandWorked(coll.insertMany(docs));
|
|
}
|
|
|
|
function downgradeSecondariesToLastLTS(rst) {
|
|
// First downgrade FCV to simulate replica set downgrade.
|
|
const primaryConnection = rst.getPrimary();
|
|
assert.commandWorked(primaryConnection.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
|
|
|
|
// Finally, downgrade the secondaries to result in a mixed bin version replica set.
|
|
rst.upgradeSecondaries({...lastLTSVersion});
|
|
}
|
|
|
|
// Starting 8.2, ident suffix generation changes to encode a UUID rather than a random number +
|
|
// counter. Tests that idents generated in newer versions are still compatible with 8.0.
|
|
function testIdentsCompatibleAcrossVersions() {
|
|
const rst = new ReplSetTest({
|
|
name: jsTestName(),
|
|
nodes: [{...latestVersion}, {...latestVersion}],
|
|
});
|
|
rst.startSet();
|
|
rst.initiate(null, null, {initiateWithDefaultElectionTimeout: true});
|
|
|
|
jsTestLog(`Creating new collection when all nodes are on ${tojson(latestVersion)}`);
|
|
const collLatestName = "collCreatedOnLatest";
|
|
setupCollection(rst, collLatestName);
|
|
validateCollectionContents(rst, [collLatestName]);
|
|
|
|
jsTestLog(`Downgrading secondaries to simulate mixed version replica set`);
|
|
downgradeSecondariesToLastLTS(rst);
|
|
assert.binVersion(rst.getPrimary(), latestVersion.binVersion);
|
|
assert.binVersion(rst.getSecondary(), lastLTSVersion.binVersion);
|
|
|
|
jsTestLog(`Creating collection with on replica set with mixed binVersions`);
|
|
const collMixedName = "collCreatedOnMixedVersionReplica";
|
|
setupCollection(rst, collMixedName);
|
|
|
|
jsTestLog(`Validating collection contents in the mixed version replica set`);
|
|
validateCollectionContents(rst, [collLatestName, collMixedName]);
|
|
|
|
jsTestLog(`Downgrading entire set to lastLTS`);
|
|
rst.upgradeSet({...lastLTSVersion});
|
|
assert.binVersion(rst.getPrimary(), lastLTSVersion.binVersion);
|
|
|
|
// The new node is on the older version, and generates idents, for both
|
|
// collections, using the legacy method.
|
|
jsTestLog(`Initial syncing a new node on lastLTS`);
|
|
rst.add({...lastLTSVersion});
|
|
rst.reInitiate();
|
|
rst.awaitReplication();
|
|
rst.awaitSecondaryNodes();
|
|
|
|
jsTestLog(`Validating collection contents with all nodes on 'lastLTS'`);
|
|
validateCollectionContents(rst, [collLatestName, collMixedName]);
|
|
|
|
jsTestLog(`Finally, upgrading the entire set back to 'latest'`);
|
|
rst.upgradeSet({...latestVersion});
|
|
validateCollectionContents(rst, [collLatestName, collMixedName]);
|
|
|
|
rst.stopSet();
|
|
}
|
|
|
|
testIdentsCompatibleAcrossVersions();
|