summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough
diff options
context:
space:
mode:
authorHana Pearlman <hana.pearlman@mongodb.com>2021-04-08 13:00:07 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-04-08 21:44:02 +0000
commitd8c427452b50ff985c2e9054ca0149ee23a093ab (patch)
treebf7c302c79a1a7c6a6f08fdb86de15eebd8434ae /jstests/noPassthrough
parentdbb4d41af08a99985d8585023faf0948c16ab80d (diff)
downloadmongo-d8c427452b50ff985c2e9054ca0149ee23a093ab.tar.gz
SERVER-55903: Move hello_feature_compatibility_version test into noPassthrough
Diffstat (limited to 'jstests/noPassthrough')
-rw-r--r--jstests/noPassthrough/hello_feature_compatibility_version.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/jstests/noPassthrough/hello_feature_compatibility_version.js b/jstests/noPassthrough/hello_feature_compatibility_version.js
new file mode 100644
index 00000000000..20aab513111
--- /dev/null
+++ b/jstests/noPassthrough/hello_feature_compatibility_version.js
@@ -0,0 +1,95 @@
+// Tests that when the featureCompatibilityVersion is not equal to the downgrade version, running
+// hello/isMaster with internalClient returns a response with minWireVersion == maxWireVersion. This
+// ensures that an older version mongod/mongos will fail to connect to the node when it is upgraded,
+// upgrading, or downgrading.
+//
+(function() {
+"use strict";
+
+const conn = MongoRunner.runMongod();
+const adminDB = conn.getDB("admin");
+
+// This test manually runs hello/isMaster with the 'internalClient' field, which means that to the
+// mongod, the connection appears to be from another server. This makes mongod to return a
+// hello/isMaster response with a real 'minWireVersion' for internal clients instead of 0.
+//
+// The value of 'internalClient.maxWireVersion' in the hello/isMaster command does not matter for
+// the purpose of this test and the hello/isMaster command will succeed regardless because this is
+// run through the shell and the shell is always compatible talking to the server. In reality
+// though, a real internal client with a lower binary version is expected to hang up immediately
+// after receiving the response to the hello/isMaster command from a latest server with an upgraded
+// FCV.
+//
+// And we need to use a side connection to do so in order to prevent the test connection from
+// being closed on FCV changes.
+function cmdAsInternalClient(cmd) {
+ const command =
+ {[cmd]: 1, internalClient: {minWireVersion: NumberInt(0), maxWireVersion: NumberInt(7)}};
+ const connInternal = new Mongo(adminDB.getMongo().host);
+ const res = assert.commandWorked(connInternal.adminCommand(command));
+ connInternal.close();
+ return res;
+}
+
+// When the featureCompatibilityVersion is equal to the upgrade version, running hello/isMaster with
+// internalClient returns a response with minWireVersion == maxWireVersion.
+checkFCV(adminDB, latestFCV);
+let res = cmdAsInternalClient("hello");
+assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+res = cmdAsInternalClient("isMaster");
+assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+
+// Test wire version for upgrade/downgrade.
+function runTest(downgradeFCV, downgradeWireVersion, maxWireVersion, cmd) {
+ // When the featureCompatibilityVersion is upgrading, running hello/isMaster with internalClient
+ // returns a response with minWireVersion == maxWireVersion.
+ assert.commandWorked(
+ adminDB.system.version.update({_id: "featureCompatibilityVersion"},
+ {$set: {version: downgradeFCV, targetVersion: latestFCV}}));
+ let res = cmdAsInternalClient(cmd);
+ assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+ assert.eq(maxWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the featureCompatibilityVersion is downgrading, running hello/isMaster with
+ // internalClient returns a response with minWireVersion == maxWireVersion.
+ assert.commandWorked(adminDB.system.version.update(
+ {_id: "featureCompatibilityVersion"},
+ {$set: {version: downgradeFCV, targetVersion: downgradeFCV, previousVersion: latestFCV}}));
+ res = cmdAsInternalClient(cmd);
+ assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+ assert.eq(maxWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the featureCompatibilityVersion is equal to the downgrade version, running
+ // hello/isMaster with internalClient returns a response with minWireVersion + 1 ==
+ // maxWireVersion.
+ assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: downgradeFCV}));
+ res = cmdAsInternalClient(cmd);
+ assert.eq(downgradeWireVersion, res.minWireVersion, tojson(res));
+ assert.eq(maxWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the internalClient field is missing from the hello/isMaster command, the response
+ // returns the full wire version range from minWireVersion == 0 to maxWireVersion == latest
+ // version, even if the featureCompatibilityVersion is equal to the upgrade version.
+ assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: latestFCV}));
+ res = adminDB.runCommand({[cmd]: 1});
+ assert.commandWorked(res);
+ assert.eq(res.minWireVersion, 0, tojson(res));
+ assert.lt(res.minWireVersion, res.maxWireVersion, tojson(res));
+ assert.eq(maxWireVersion, res.maxWireVersion, tojson(res));
+}
+
+// Test upgrade/downgrade between 'latest' and 'last-continuous' if 'last-continuous' is not
+// 'last-lts'.
+if (lastContinuousFCV !== lastLTSFCV) {
+ runTest(lastContinuousFCV, res.maxWireVersion - 1, res.maxWireVersion, "hello");
+ runTest(lastContinuousFCV, res.maxWireVersion - 1, res.maxWireVersion, "isMaster");
+ runTest(lastContinuousFCV, res.maxWireVersion - 1, res.maxWireVersion, "ismaster");
+}
+
+// Test upgrade/downgrade between 'latest' and 'last-lts'.
+runTest(lastLTSFCV, res.maxWireVersion - numVersionsSinceLastLTS, res.maxWireVersion, "hello");
+runTest(lastLTSFCV, res.maxWireVersion - numVersionsSinceLastLTS, res.maxWireVersion, "isMaster");
+runTest(lastLTSFCV, res.maxWireVersion - numVersionsSinceLastLTS, res.maxWireVersion, "ismaster");
+
+MongoRunner.stopMongod(conn);
+})();