diff options
author | Maria van Keulen <maria@mongodb.com> | 2017-09-21 18:00:39 -0400 |
---|---|---|
committer | Maria van Keulen <maria@mongodb.com> | 2017-10-16 17:41:56 -0400 |
commit | c9ca12d30bbfff9abc1717f2460b8a54f965bf89 (patch) | |
tree | 16c0899518119e2e140fced74bf50eafcb3d320b /jstests/multiVersion | |
parent | bad24a802403e3d2d36e4190a9efc117e9afcf7e (diff) | |
download | mongo-c9ca12d30bbfff9abc1717f2460b8a54f965bf89.tar.gz |
SERVER-29452 Handle missing featureCompatibilityVersion document
Diffstat (limited to 'jstests/multiVersion')
-rw-r--r-- | jstests/multiVersion/major_version_upgrade.js | 17 | ||||
-rw-r--r-- | jstests/multiVersion/set_feature_compatibility_version.js | 146 |
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. // |