summaryrefslogtreecommitdiff
path: root/jstests/multiVersion
diff options
context:
space:
mode:
authorMaria van Keulen <maria@mongodb.com>2017-09-21 18:00:39 -0400
committerMaria van Keulen <maria@mongodb.com>2017-10-16 17:41:56 -0400
commitc9ca12d30bbfff9abc1717f2460b8a54f965bf89 (patch)
tree16c0899518119e2e140fced74bf50eafcb3d320b /jstests/multiVersion
parentbad24a802403e3d2d36e4190a9efc117e9afcf7e (diff)
downloadmongo-c9ca12d30bbfff9abc1717f2460b8a54f965bf89.tar.gz
SERVER-29452 Handle missing featureCompatibilityVersion document
Diffstat (limited to 'jstests/multiVersion')
-rw-r--r--jstests/multiVersion/major_version_upgrade.js17
-rw-r--r--jstests/multiVersion/set_feature_compatibility_version.js146
2 files changed, 163 insertions, 0 deletions
diff --git a/jstests/multiVersion/major_version_upgrade.js b/jstests/multiVersion/major_version_upgrade.js
index 1365fac361c..07966eba73a 100644
--- a/jstests/multiVersion/major_version_upgrade.js
+++ b/jstests/multiVersion/major_version_upgrade.js
@@ -174,6 +174,14 @@
// We're on the latest version, check bad indexes are still readable.
validateBadIndexesStandalone(testDB);
}
+
+ // Make sure a featureCompatibilityVersion document exists during the version.binVersion
+ // === 3.4 iteration and all remaining iterations of "version".
+ if (version.binVersion === "3.4") {
+ let adminDB = conn.getDB("admin");
+ assert.commandWorked(adminDB.runCommand({"setFeatureCompatibilityVersion": "3.4"}));
+ }
+
// Shutdown the current mongod.
MongoRunner.stopMongod(conn);
@@ -282,6 +290,15 @@
GetIndexHelpers.findByKeyPattern(testDB[oldVersionCollection].getIndexes(), {b: 1}),
`index from ${oldVersionCollection} should be available; nodes: ${tojson(nodes)}`);
}
+
+ // Make sure a featureCompatibilityVersion document exists during the version.binVersion
+ // === 3.4 iteration and all remaining iterations of "version".
+ if (version.binVersion === "3.4") {
+ let primaryAdminDB = primary.getDB("admin");
+ assert.commandWorked(
+ primaryAdminDB.runCommand({setFeatureCompatibilityVersion: "3.4"}));
+ rst.awaitReplication();
+ }
}
// Stop the replica set.
diff --git a/jstests/multiVersion/set_feature_compatibility_version.js b/jstests/multiVersion/set_feature_compatibility_version.js
index a9829dcc393..32125a9d4d2 100644
--- a/jstests/multiVersion/set_feature_compatibility_version.js
+++ b/jstests/multiVersion/set_feature_compatibility_version.js
@@ -26,6 +26,85 @@
const latest = "latest";
const downgrade = "3.4";
+ let recoverMMapJournal = function(isMMAPv1, conn, dbpath) {
+ // If we're using mmapv1, recover the journal files from the unclean shutdown before
+ // attempting to run with --repair.
+ if (isMMAPv1) {
+ let returnCode = runMongoProgram("mongod",
+ "--port",
+ conn.port,
+ "--journalOptions",
+ /*MMAPV1Options::JournalRecoverOnly*/ 4,
+ "--dbpath",
+ dbpath);
+ assert.eq(returnCode, /*EXIT_NET_ERROR*/ 48);
+ }
+ };
+
+ let doStartupFailTests = function(withUUIDs, dbpath) {
+ // Fail to start up if no admin database is present but other non-local databases are
+ // present.
+ if (withUUIDs) {
+ setupMissingAdminDB(latest, dbpath);
+ } else {
+ setupMissingAdminDB(downgrade, dbpath);
+ }
+ conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest, noCleanData: true});
+ assert.eq(
+ null,
+ conn,
+ "expected mongod to fail when data files are present and no admin database is found.");
+
+ // Fail to start up if no featureCompatibilityVersion document is present and non-local
+ // databases are present.
+ if (withUUIDs) {
+ setupMissingFCVDoc(latest, dbpath);
+ } else {
+ setupMissingFCVDoc(downgrade, dbpath);
+ }
+ conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest, noCleanData: true});
+ assert.eq(
+ null,
+ conn,
+ "expected mongod to fail when data files are present and no featureCompatibilityVersion document is found.");
+ };
+
+ let setupMissingFCVDoc = function(version, dbpath) {
+ let conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: version});
+ assert.neq(null,
+ conn,
+ "mongod was unable to start up with version=" + version + " and no data files");
+ adminDB = conn.getDB("admin");
+ if (version === latest) {
+ assert.eq(
+ adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version,
+ "3.6",
+ "expected 3.6 mongod with no data files to start up with featureCompatibilityVersion 3.6");
+ } else {
+ assert.eq(
+ adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version,
+ "3.4",
+ "expected 3.4 mongod with no data files to start up with featureCompatibilityVersion 3.4");
+ }
+ assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
+ MongoRunner.stopMongod(conn);
+ return conn;
+ };
+
+ let setupMissingAdminDB = function(version, dbpath) {
+ conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: version});
+ assert.neq(null,
+ conn,
+ "mongod was unable to start up with version=" + version + " and no data files");
+ let testDB = conn.getDB("test");
+ assert.commandWorked(testDB.createCollection("testcoll"));
+ adminDB = conn.getDB("admin");
+ assert.commandWorked(adminDB.runCommand({dropDatabase: 1}),
+ "expected drop of admin database to be successful");
+ MongoRunner.stopMongod(conn);
+ return conn;
+ };
+
//
// Standalone tests.
//
@@ -105,6 +184,73 @@
checkFCV(adminDB, "3.4");
MongoRunner.stopMongod(conn);
+ const isMMAPv1 = jsTest.options().storageEngine === "mmapv1";
+ // Fail to start up if no featureCompatibilityVersion is present.
+ doStartupFailTests(/*withUUIDs*/ true, dbpath);
+
+ // Fail to start up if no featureCompatibilityVersion is present and no collections have UUIDs.
+ doStartupFailTests(/*withUUIDs*/ false, dbpath);
+
+ // --repair can be used to restore a missing admin database and featureCompatibilityVersion
+ // document if at least some collections have UUIDs.
+ conn = setupMissingAdminDB(latest, dbpath);
+ recoverMMapJournal(isMMAPv1, conn, dbpath);
+ let returnCode = runMongoProgram("mongod", "--port", conn.port, "--repair", "--dbpath", dbpath);
+ assert.eq(
+ returnCode,
+ 0,
+ "expected mongod --repair to execute successfully when restoring a missing admin database.");
+ conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest, noCleanData: true});
+ assert.neq(null,
+ conn,
+ "mongod was unable to start up with version=" + latest + " and existing data files");
+ // featureCompatibilityVersion is 3.4 and targetVersion is 3.6 because the admin.system.version
+ // collection was restored without a UUID.
+ adminDB = conn.getDB("admin");
+ assert.eq(adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version, "3.4");
+ assert.eq(adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).targetVersion,
+ "3.6");
+ let adminInfos = adminDB.getCollectionInfos();
+ assert(!adminInfos[0].uuid,
+ "Expected collection with infos " + tojson(adminInfos) + " to not have a UUID.");
+ MongoRunner.stopMongod(conn);
+
+ // --repair can be used to restore a missing featureCompatibilityVersion document to an
+ // existing admin database if at least some collections have UUIDs.
+ conn = setupMissingFCVDoc(latest, dbpath);
+ recoverMMapJournal(isMMAPv1, conn, dbpath);
+ returnCode = runMongoProgram("mongod", "--port", conn.port, "--repair", "--dbpath", dbpath);
+ assert.eq(
+ returnCode,
+ 0,
+ "expected mongod --repair to execute successfully when restoring a missing featureCompatibilityVersion document.");
+ conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest, noCleanData: true});
+ assert.neq(null,
+ conn,
+ "mongod was unable to start up with version=" + latest + " and existing data files");
+ // featureCompatibilityVersion is 3.6 because all collections were left intact with UUIDs.
+ adminDB = conn.getDB("admin");
+ assert.eq(adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version, "3.6");
+ MongoRunner.stopMongod(conn);
+
+ // --repair cannot be used to restore a missing featureCompatibilityVersion document if there
+ // are no collections with UUIDs.
+ conn = setupMissingFCVDoc(downgrade, dbpath);
+ recoverMMapJournal(isMMAPv1, conn, dbpath);
+ returnCode = runMongoProgram("mongod", "--port", conn.port, "--repair", "--dbpath", dbpath);
+ assert.neq(returnCode, 0, "expected mongod --repair to fail if no collections have UUIDs.");
+
+ // If the featureCompatibilityVersion document is present but there are no collection UUIDs,
+ // --repair should not attempt to restore the document and thus not fassert.
+ conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: downgrade});
+ assert.neq(null,
+ conn,
+ "mongod was unable to start up with version=" + downgrade + " and no data files");
+ MongoRunner.stopMongod(conn);
+ recoverMMapJournal(isMMAPv1, conn, dbpath);
+ returnCode = runMongoProgram("mongod", "--port", conn.port, "--repair", "--dbpath", dbpath);
+ assert.eq(returnCode, 0);
+
//
// Replica set tests.
//