diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2017-10-24 14:48:16 -0400 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2017-10-25 12:18:07 -0400 |
commit | 23e886eebf9794190d198da98cd96e4127bb3dc8 (patch) | |
tree | ae150142ceed1cf3c7385cd4688caf19b2192b69 | |
parent | de2a67178e3365b829d57afde92cb6123dd24357 (diff) | |
download | mongo-23e886eebf9794190d198da98cd96e4127bb3dc8.tar.gz |
SERVER-31630 getParameter for featureCompatibilityVersion must expose targetVersion
8 files changed, 149 insertions, 94 deletions
diff --git a/jstests/libs/feature_compatibility_version.js b/jstests/libs/feature_compatibility_version.js new file mode 100644 index 00000000000..116706eaf27 --- /dev/null +++ b/jstests/libs/feature_compatibility_version.js @@ -0,0 +1,33 @@ +// Contains helpers for checking the featureCompatibilityVersion. + +/** + * Checks the featureCompatibilityVersion document and server parameter. The + * featureCompatibilityVersion document is of the form {_id: "featureCompatibilityVersion", version: + * <required>, targetVersion: <optional>}. The getParameter result is of the form + * {featureCompatibilityVersion: {version: <required>, targetVersion: <optional>}, ok: 1}. + */ +function checkFCV(adminDB, version, targetVersion) { + let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq(res.featureCompatibilityVersion.version, version, tojson(res)); + assert.eq(res.featureCompatibilityVersion.targetVersion, targetVersion, tojson(res)); + + let doc = adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}); + assert.eq(doc.version, version, tojson(doc)); + assert.eq(doc.targetVersion, targetVersion, tojson(doc)); +} + +/** + * Checks the featureCompatibilityVersion document and server parameter for a 3.4 binary. In 3.4, + * the featureCompatibilityVersion document is of the form {_id: "featureCompatibilityVersion", + * version: <value>}. The getParameter result is of the form {featureCompatibilityVersion: <value>, + * ok: 1}. + */ +function checkFCV34(adminDB, version) { + let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq(res.featureCompatibilityVersion, version, tojson(res)); + + let doc = adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}); + assert.eq(doc.version, version, tojson(doc)); +}
\ No newline at end of file diff --git a/jstests/multiVersion/incomplete_upgrade_downgrade.js b/jstests/multiVersion/incomplete_upgrade_downgrade.js index a46d9e7993c..f03533d3324 100644 --- a/jstests/multiVersion/incomplete_upgrade_downgrade.js +++ b/jstests/multiVersion/incomplete_upgrade_downgrade.js @@ -5,14 +5,7 @@ (function() { "use strict"; - let checkFCV = function(adminDB, version, targetVersion) { - let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq(res.featureCompatibilityVersion, version); - let doc = adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}); - assert.eq(doc.version, version); - assert.eq(doc.targetVersion, targetVersion); - }; + load("jstests/libs/feature_compatibility_version.js"); let setFCV = function(adminDB, version) { assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: version})); diff --git a/jstests/multiVersion/set_feature_compatibility_version.js b/jstests/multiVersion/set_feature_compatibility_version.js index d17eee1f235..c9917fee3d0 100644 --- a/jstests/multiVersion/set_feature_compatibility_version.js +++ b/jstests/multiVersion/set_feature_compatibility_version.js @@ -7,25 +7,9 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true; "use strict"; load("jstests/replsets/rslib.js"); + load("jstests/libs/feature_compatibility_version.js"); load("jstests/libs/get_index_helpers.js"); - let checkFCV = function(adminDB, version, targetVersion) { - let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq(res.featureCompatibilityVersion, version); - - let doc = adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}); - assert.eq(doc.version, version); - - // The 'targetVersion' field only exists on v3.6+ binaries, and is only present while an - // upgrade or downgrade is in progress. - if (targetVersion) { - assert.eq(doc.targetVersion, targetVersion); - } else { - assert.eq(null, doc.targetVersion); - } - }; - let res; const latest = "latest"; const downgrade = "3.4"; @@ -204,7 +188,7 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true; null, conn, "mongod was unable to start up with version=" + latest + " and no data files"); assert.writeOK(conn.getDB("test").coll.insert({a: 5})); adminDB = conn.getDB("admin"); - checkFCV(adminDB, "3.4"); + checkFCV34(adminDB, "3.4"); MongoRunner.stopMongod(conn); conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: latest, noCleanData: true}); @@ -399,7 +383,8 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true; assert.eq(res.featureCompatibilityVersion, "3.2"); res = secondaryAdminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); assert.commandWorked(res); - assert.eq(res.featureCompatibilityVersion, "3.4"); + assert.eq(res.featureCompatibilityVersion.version, "3.4", tojson(res)); + assert.eq(res.featureCompatibilityVersion.targetVersion, null, tojson(res)); rst.stopSet(); // @@ -560,7 +545,7 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true; downgradeShard.startSet(); downgradeShard.initiate(); assert.commandWorked(mongosAdminDB.runCommand({addShard: downgradeShard.getURL()})); - checkFCV(downgradeShard.getPrimary().getDB("admin"), "3.4"); + checkFCV34(downgradeShard.getPrimary().getDB("admin"), "3.4"); // call ShardingTest.stop before shutting down downgradeShard, so that the UUID check in // ShardingTest.stop can talk to downgradeShard. diff --git a/jstests/multiVersion/set_schema_version.js b/jstests/multiVersion/set_schema_version.js index e7ee9079230..3290cf53ce0 100644 --- a/jstests/multiVersion/set_schema_version.js +++ b/jstests/multiVersion/set_schema_version.js @@ -3,6 +3,7 @@ "use strict"; load("jstests/replsets/rslib.js"); + load("jstests/libs/feature_compatibility_version.js"); load("jstests/libs/get_index_helpers.js"); const latest = "latest"; @@ -30,16 +31,6 @@ }); }; - let checkFCV = function(adminDB, version, is34) { - if (!is34) { - let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq(res.featureCompatibilityVersion, version); - } - assert.eq(adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version, - version); - }; - let setFCV = function(adminDB, version) { assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: version})); checkFCV(adminDB, version); @@ -102,7 +93,7 @@ let downgradeAdminDB = downgradeConn.getDB("admin"); // Check FCV document - checkFCV(downgradeAdminDB, "3.4", true); + checkFCV34(downgradeAdminDB, "3.4"); // Ensure there are no UUIDs checkCollectionUUIDs(downgradeAdminDB, true); @@ -185,10 +176,10 @@ // Initially featureCompatibilityVersion document is 3.4 on primary and secondaries. checkCollectionUUIDs(downgradePrimaryAdminDB, true); - checkFCV(downgradePrimaryAdminDB, "3.4", true); + checkFCV34(downgradePrimaryAdminDB, "3.4"); for (let j = 0; j < downgradeSecondaries.length; j++) { let secondaryAdminDB = downgradeSecondaries[j].getDB("admin"); - checkFCV(secondaryAdminDB, "3.4", true); + checkFCV34(secondaryAdminDB, "3.4"); // Ensure no collections have UUIDs checkCollectionUUIDs(secondaryAdminDB, true); diff --git a/jstests/noPassthrough/arrayFilters_feature_compatibility_version.js b/jstests/noPassthrough/arrayFilters_feature_compatibility_version.js index 6877bc12c30..940ea71b762 100644 --- a/jstests/noPassthrough/arrayFilters_feature_compatibility_version.js +++ b/jstests/noPassthrough/arrayFilters_feature_compatibility_version.js @@ -19,9 +19,6 @@ // assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.4"})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); // Update. res = coll.update({_id: 0}, {$set: {"a.$[i]": 5}}, {arrayFilters: [{i: 0}]}); @@ -54,9 +51,6 @@ // assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.6", res.featureCompatibilityVersion); // Update. assert.writeOK(coll.update({_id: 0}, {$set: {"a.$[i]": 5}}, {arrayFilters: [{i: 0}]})); diff --git a/jstests/noPassthrough/drop_collections_two_phase_feature_compatibility_version.js b/jstests/noPassthrough/drop_collections_two_phase_feature_compatibility_version.js index cfaa25407e7..1dc34206575 100644 --- a/jstests/noPassthrough/drop_collections_two_phase_feature_compatibility_version.js +++ b/jstests/noPassthrough/drop_collections_two_phase_feature_compatibility_version.js @@ -10,6 +10,7 @@ (function() { "use strict"; + load("jstests/libs/feature_compatibility_version.js"); load("jstests/replsets/libs/two_phase_drops.js"); // For TwoPhaseDropCollectionTest. // Set feature compatibility version on the given node. Note that setting FCV requires a @@ -17,10 +18,7 @@ function setFCV(node, featureCompatibilityVersion) { assert.commandWorked( node.adminCommand({setFeatureCompatibilityVersion: featureCompatibilityVersion})); - let res = node.adminCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked( - res, "failed to set feature compatibility version to " + featureCompatibilityVersion); - assert.eq(featureCompatibilityVersion, res.featureCompatibilityVersion); + checkFCV(node.getDB("admin"), featureCompatibilityVersion); } // Restart the primary of the given ReplSetTest. diff --git a/jstests/noPassthrough/feature_compatibility_version.js b/jstests/noPassthrough/feature_compatibility_version.js index 9645ed79163..de37a2a29a2 100644 --- a/jstests/noPassthrough/feature_compatibility_version.js +++ b/jstests/noPassthrough/feature_compatibility_version.js @@ -4,84 +4,124 @@ (function() { "use strict"; + load("jstests/libs/feature_compatibility_version.js"); + + /** + * Checks that the featureCompatibilityVersion document is missing, and the + * featureCompatibilityVersion server parameter is "3.4". + */ + let checkFCVDocumentMissing = function(adminDB) { + assert.eq(null, adminDB.system.version.findOne({_id: "featureCompatibilityVersion"})); + + let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.4", res.featureCompatibilityVersion.version, tojson(res)); + assert.eq(null, res.featureCompatibilityVersion.targetVersion, tojson(res)); + }; + const conn = MongoRunner.runMongod({}); assert.neq(null, conn, "mongod was unable to start up"); let adminDB = conn.getDB("admin"); // Initially the featureCompatibilityVersion is 3.6. - let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.6", res.featureCompatibilityVersion); + checkFCV(adminDB, "3.6"); // Updating the featureCompatibilityVersion document changes the featureCompatibilityVersion // server parameter. assert.writeOK(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, {$set: {version: "3.4"}})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCV(adminDB, "3.4"); assert.writeOK(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, - {$set: {version: "3.6"}})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.6", res.featureCompatibilityVersion); + {$set: {version: "3.4", targetVersion: "3.6"}})); + checkFCV(adminDB, "3.4", "3.6"); + + assert.writeOK(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {version: "3.4", targetVersion: "3.4"}})); + checkFCV(adminDB, "3.4", "3.4"); + + assert.writeOK( + adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {version: "3.6"}, $unset: {targetVersion: true}})); + checkFCV(adminDB, "3.6"); // Updating the featureCompatibilityVersion document with an invalid version fails. assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, {$set: {version: "3.2"}}), ErrorCodes.BadValue); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.6", res.featureCompatibilityVersion); + checkFCV(adminDB, "3.6"); + + // Updating the featureCompatibilityVersion document with an invalid targetVersion fails. + assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {targetVersion: "3.4"}}), + ErrorCodes.BadValue); + checkFCV(adminDB, "3.6"); + + assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {targetVersion: "3.6"}}), + ErrorCodes.BadValue); + checkFCV(adminDB, "3.6"); // Deleting the featureCompatibilityVersion document changes the featureCompatibilityVersion // server parameter to 3.4. assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCVDocumentMissing(adminDB); // Inserting a featureCompatibilityVersion document with an invalid version fails. assert.writeErrorWithCode( adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.2"}), ErrorCodes.BadValue); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCVDocumentMissing(adminDB); assert.writeErrorWithCode( adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.8"}), ErrorCodes.BadValue); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCVDocumentMissing(adminDB); + + // Inserting a featureCompatibilityVersion document with an invalid targetVersion fails. + assert.writeErrorWithCode( + adminDB.system.version.insert( + {_id: "featureCompatibilityVersion", version: "3.6", targetVersion: "3.4"}), + ErrorCodes.BadValue); + checkFCVDocumentMissing(adminDB); + + assert.writeErrorWithCode( + adminDB.system.version.insert( + {_id: "featureCompatibilityVersion", version: "3.6", targetVersion: "3.6"}), + ErrorCodes.BadValue); + checkFCVDocumentMissing(adminDB); // Inserting the featureCompatibilityVersion document changes the featureCompatibilityVersion // server parameter. assert.writeOK( adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.4"})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCV(adminDB, "3.4"); + + assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"})); + checkFCVDocumentMissing(adminDB); + + assert.writeOK(adminDB.system.version.insert( + {_id: "featureCompatibilityVersion", version: "3.4", targetVersion: "3.6"})); + checkFCV(adminDB, "3.4", "3.6"); + + assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"})); + checkFCVDocumentMissing(adminDB); + + assert.writeOK(adminDB.system.version.insert( + {_id: "featureCompatibilityVersion", version: "3.4", targetVersion: "3.4"})); + checkFCV(adminDB, "3.4", "3.4"); assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCVDocumentMissing(adminDB); assert.writeOK( adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.6"})); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.6", res.featureCompatibilityVersion); + checkFCV(adminDB, "3.6"); // Dropping the admin database changes the featureCompatibilityVersion server parameter to 3.4. adminDB.dropDatabase(); - res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); - assert.commandWorked(res); - assert.eq("3.4", res.featureCompatibilityVersion); + checkFCVDocumentMissing(adminDB); MongoRunner.stopMongod(conn); }()); diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp index 10444bea57c..c4b3053d4ce 100644 --- a/src/mongo/db/commands/feature_compatibility_version.cpp +++ b/src/mongo/db/commands/feature_compatibility_version.cpp @@ -448,15 +448,36 @@ public: ) {} virtual void append(OperationContext* opCtx, BSONObjBuilder& b, const std::string& name) { - std::string version; - if (serverGlobalParams.featureCompatibility.isFullyUpgradedTo36()) { - b.append(name, - FeatureCompatibilityVersion::toString( - ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36)); - } else { - b.append(name, - FeatureCompatibilityVersion::toString( - ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34)); + BSONObjBuilder featureCompatibilityVersionBuilder(b.subobjStart(name)); + switch (serverGlobalParams.featureCompatibility.getVersion()) { + case ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36: + featureCompatibilityVersionBuilder.append( + FeatureCompatibilityVersion::kVersionField, + FeatureCompatibilityVersionCommandParser::kVersion36); + return; + case ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34: + featureCompatibilityVersionBuilder.append( + FeatureCompatibilityVersion::kVersionField, + FeatureCompatibilityVersionCommandParser::kVersion34); + return; + case ServerGlobalParams::FeatureCompatibility::Version::kUpgradingTo36: + featureCompatibilityVersionBuilder.append( + FeatureCompatibilityVersion::kVersionField, + FeatureCompatibilityVersionCommandParser::kVersion34); + featureCompatibilityVersionBuilder.append( + FeatureCompatibilityVersion::kTargetVersionField, + FeatureCompatibilityVersionCommandParser::kVersion36); + return; + case ServerGlobalParams::FeatureCompatibility::Version::kDowngradingTo34: + featureCompatibilityVersionBuilder.append( + FeatureCompatibilityVersion::kVersionField, + FeatureCompatibilityVersionCommandParser::kVersion34); + featureCompatibilityVersionBuilder.append( + FeatureCompatibilityVersion::kTargetVersionField, + FeatureCompatibilityVersionCommandParser::kVersion34); + return; + default: + MONGO_UNREACHABLE; } } |