summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrace Luong <grace.luong@mongodb.com>2020-07-31 20:04:02 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-31 20:58:02 +0000
commitcd5a75ea3bf3915617a04a9ec463bfb2c467b27e (patch)
tree131002f02b182c7ca324c1be475a5a3c93e14f89
parent134c3ee37576de7ec36456fe3420305d6871b874 (diff)
downloadmongo-cd5a75ea3bf3915617a04a9ec463bfb2c467b27e.tar.gz
SERVER-49270: Set minWireVersion based on FCV and refactor protocol tests
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.cpp41
-rw-r--r--src/mongo/db/server_options.h5
-rw-r--r--src/mongo/db/wire_version.h7
-rw-r--r--src/mongo/rpc/protocol_test.cpp229
4 files changed, 154 insertions, 128 deletions
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp
index 733589ca43f..285c3068c48 100644
--- a/src/mongo/db/commands/feature_compatibility_version.cpp
+++ b/src/mongo/db/commands/feature_compatibility_version.cpp
@@ -233,26 +233,27 @@ void FeatureCompatibilityVersion::onInsertOrUpdate(OperationContext* opCtx, cons
void FeatureCompatibilityVersion::updateMinWireVersion() {
WireSpec& wireSpec = WireSpec::instance();
- switch (serverGlobalParams.featureCompatibility.getVersion()) {
- case ServerGlobalParams::FeatureCompatibility::kLatest:
- case ServerGlobalParams::FeatureCompatibility::Version::kUpgradingFrom44To451:
- case ServerGlobalParams::FeatureCompatibility::Version::kDowngradingFrom451To44: {
- WireSpec::Specification newSpec = *wireSpec.get();
- newSpec.incomingInternalClient.minWireVersion = LATEST_WIRE_VERSION;
- newSpec.outgoing.minWireVersion = LATEST_WIRE_VERSION;
- wireSpec.reset(std::move(newSpec));
- return;
- }
- case ServerGlobalParams::FeatureCompatibility::kLastLTS: {
- WireSpec::Specification newSpec = *wireSpec.get();
- newSpec.incomingInternalClient.minWireVersion = LATEST_WIRE_VERSION - 1;
- newSpec.outgoing.minWireVersion = LATEST_WIRE_VERSION - 1;
- wireSpec.reset(std::move(newSpec));
- return;
- }
- case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault44Behavior:
- // getVersion() does not return this value.
- MONGO_UNREACHABLE;
+ if (serverGlobalParams.featureCompatibility.isGreaterThan(
+ ServerGlobalParams::FeatureCompatibility::kLastContinuous)) {
+ // FCV == kLatest
+ WireSpec::Specification newSpec = *wireSpec.get();
+ newSpec.incomingInternalClient.minWireVersion = LATEST_WIRE_VERSION;
+ newSpec.outgoing.minWireVersion = LATEST_WIRE_VERSION;
+ wireSpec.reset(std::move(newSpec));
+ } else if (serverGlobalParams.featureCompatibility.isGreaterThan(
+ ServerGlobalParams::FeatureCompatibility::kLastLTS)) {
+ // FCV == kLastContinuous
+ WireSpec::Specification newSpec = *wireSpec.get();
+ newSpec.incomingInternalClient.minWireVersion = LAST_CONT_WIRE_VERSION;
+ newSpec.outgoing.minWireVersion = LAST_CONT_WIRE_VERSION;
+ wireSpec.reset(std::move(newSpec));
+ } else {
+ // FCV == kLastLTS
+ invariant(serverGlobalParams.featureCompatibility.isVersionInitialized());
+ WireSpec::Specification newSpec = *wireSpec.get();
+ newSpec.incomingInternalClient.minWireVersion = LAST_LTS_WIRE_VERSION;
+ newSpec.outgoing.minWireVersion = LAST_LTS_WIRE_VERSION;
+ wireSpec.reset(std::move(newSpec));
}
}
diff --git a/src/mongo/db/server_options.h b/src/mongo/db/server_options.h
index 4d239097d91..5e451140636 100644
--- a/src/mongo/db/server_options.h
+++ b/src/mongo/db/server_options.h
@@ -282,6 +282,11 @@ struct ServerGlobalParams {
return version != kLatest && version != kLastContinuous && version != kLastLTS;
}
+ // This function is to be used for generic FCV references only, and not for FCV-gating.
+ bool isUpgradingOrDowngrading(Version version) {
+ return version != kLatest && version != kLastContinuous && version != kLastLTS;
+ }
+
private:
AtomicWord<Version> _version{Version::kUnsetDefault44Behavior};
diff --git a/src/mongo/db/wire_version.h b/src/mongo/db/wire_version.h
index 730d3732804..c1ab737b586 100644
--- a/src/mongo/db/wire_version.h
+++ b/src/mongo/db/wire_version.h
@@ -89,6 +89,13 @@ enum WireVersion {
// Set this to the highest value in this enum - it will be the default maxWireVersion for
// the WireSpec values.
LATEST_WIRE_VERSION = WIRE_VERSION_451,
+
+ // Set this to LATEST_WIRE_VERSION - 1.
+ LAST_CONT_WIRE_VERSION = LATEST_WIRE_VERSION - 1,
+
+ // Set this to the wire version of the previous LTS version. We expect to update this after
+ // each LTS release.
+ LAST_LTS_WIRE_VERSION = RESUMABLE_INITIAL_SYNC,
};
/**
diff --git a/src/mongo/rpc/protocol_test.cpp b/src/mongo/rpc/protocol_test.cpp
index 067ae2b775d..2f275aaf102 100644
--- a/src/mongo/rpc/protocol_test.cpp
+++ b/src/mongo/rpc/protocol_test.cpp
@@ -35,13 +35,18 @@
#include "mongo/rpc/protocol.h"
#include "mongo/unittest/unittest.h"
+#include <vector>
+
namespace {
using mongo::WireVersion;
+using mongo::WireVersionInfo;
using namespace mongo::rpc;
using mongo::BSONObj;
using mongo::unittest::assertGet;
+using std::vector;
+
// Checks if negotiation of the first to protocol sets results in the 'proto'
const auto assert_negotiated = [](ProtocolSet fst, ProtocolSet snd, Protocol proto) {
auto negotiated = negotiate(fst, snd);
@@ -136,148 +141,156 @@ TEST(Protocol, parseProtocolSetFromIsMasterReply) {
} while (0);
TEST(Protocol, validateWireVersion) {
+ // Min, max FCV version pairs representing valid WireVersion ranges for variable binary
+ // versions used to communicate with the MongoD 'latest' binary version.
+
+ // MongoD 'latest' binary
+ vector<WireVersionInfo> mongoDLatestBinaryRanges = {
+ // upgraded FCV
+ {WireVersion::LATEST_WIRE_VERSION, WireVersion::LATEST_WIRE_VERSION},
+ // downgraded 'last-cont' FCV
+ {WireVersion::LAST_CONT_WIRE_VERSION, WireVersion::LATEST_WIRE_VERSION},
+ // downgraded 'last-lts' FCV
+ {WireVersion::LAST_LTS_WIRE_VERSION, WireVersion::LATEST_WIRE_VERSION}};
+
+ // MongoS binary versions
+ vector<WireVersionInfo> mongoSBinaryRanges = {
+ // 'latest' binary
+ {WireVersion::LATEST_WIRE_VERSION, WireVersion::LATEST_WIRE_VERSION},
+ // 'last-cont' binary
+ {WireVersion::LAST_CONT_WIRE_VERSION, WireVersion::LAST_CONT_WIRE_VERSION},
+ // 'last-lts' binary
+ {WireVersion::LAST_LTS_WIRE_VERSION, WireVersion::LAST_LTS_WIRE_VERSION}};
+
/*
- * Test communication with a MongoD latest binary server with downgraded FCV.
+ * Test communication between:
+ * MongoD 'latest' binary version <-> MongoD 'latest' binary version
+ * 'latest' should always be able to communicate to 'latest' regardless of FCV.
*/
- // MongoD 'latest' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION);
-
- // MongoD 'latest' client -> MongoD downgraded 'last-lts' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 2,
- WireVersion::LATEST_WIRE_VERSION - 1);
-
- // MongoD 'latest' client -> MongoD upgraded 'last-lts' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1);
-
- // MongoD downgraded 'last-lts' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 2,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION);
-
- // MongoD upgraded 'last-lts' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION);
-
- // MongoS 'latest' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION);
+ for (const auto& clientRange : mongoDLatestBinaryRanges) {
+ for (const auto& serverRange : mongoDLatestBinaryRanges) {
+ // We don't need to test when FCV != 'latest' && client FCV != server FCV because we
+ // don't expect users to be in this state when following our recommended
+ // upgrade/downgrade procedure.
+ if (clientRange.minWireVersion < WireVersion::LATEST_WIRE_VERSION &&
+ serverRange.minWireVersion < WireVersion::LATEST_WIRE_VERSION &&
+ clientRange.minWireVersion != serverRange.minWireVersion) {
+ continue;
+ }
+ VALIDATE_WIRE_VERSION(ASSERT_OK,
+ clientRange.minWireVersion,
+ clientRange.maxWireVersion,
+ serverRange.minWireVersion,
+ serverRange.maxWireVersion);
+ }
+ }
- // MongoS 'last-lts' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION);
/*
- * Test communication with a MongoD latest binary server with upgraded FCV.
+ * Test communication between:
+ * MongoD 'latest' binary version <-> 'last-cont' binary version with 'last-cont' FCV
*/
- // MongoD 'latest' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION);
-
- // MongoD 'latest' client -> MongoD downgraded 'last-lts' server
+ // 'latest' binary with 'latest' FCV -> 'last-cont' binary with 'last-cont' FCV
VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
WireVersion::LATEST_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 2,
- WireVersion::LATEST_WIRE_VERSION - 1);
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION);
- // MongoD 'latest' client -> MongoD upgraded 'last-lts' server
- VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1);
-
- // MongoD downgraded 'last-lts' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
- WireVersion::LATEST_WIRE_VERSION - 2,
- WireVersion::LATEST_WIRE_VERSION - 1,
+ // 'latest' binary with 'last-cont' FCV -> 'last-cont' binary with 'last-cont' FCV
+ VALIDATE_WIRE_VERSION(ASSERT_OK,
+ WireVersion::LAST_CONT_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION);
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION);
- // MongoD upgraded 'last-lts' client -> MongoD 'latest' server
+ // 'last-cont' binary with 'last-cont' FCV -> 'latest' binary with 'latest' FCV
VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION);
- // MongoS 'latest' client -> MongoD 'latest' server
+ // 'last-cont' binary with 'last-cont' FCV -> 'latest' binary with 'last-cont' FCV
VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION);
-
- // MongoS 'last-lts' client -> MongoD 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION);
/*
- * Test communication between MongoD latest binary servers where one has upgraded FCV and the
- * other downgraded FCV.
+ * Test communication between:
+ * MongoD 'latest' binary version <-> 'last-lts' binary version with 'last-lts' FCV
*/
- // MongoD upgraded 'latest' client -> MongoD downgraded 'latest' server
- VALIDATE_WIRE_VERSION(ASSERT_OK,
+ // 'latest' binary with 'latest' FCV -> 'last-lts' binary with 'last-lts' FCV
+ VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
WireVersion::LATEST_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION);
+ WireVersion::LAST_LTS_WIRE_VERSION,
+ WireVersion::LAST_LTS_WIRE_VERSION);
+
+ // 'latest' binary with 'last-cont' FCV -> 'last-lts' binary with 'last-lts' FCV
+ if (WireVersion::LAST_CONT_WIRE_VERSION != WireVersion::LAST_LTS_WIRE_VERSION) {
+ VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LATEST_WIRE_VERSION,
+ WireVersion::LAST_LTS_WIRE_VERSION,
+ WireVersion::LAST_LTS_WIRE_VERSION);
+ }
- // MongoD downgraded 'latest' client -> MongoD upgraded 'latest' server
+ // 'latest' binary with 'last-lts' FCV -> 'last-lts' binary with 'last-lts' FCV
VALIDATE_WIRE_VERSION(ASSERT_OK,
- WireVersion::LATEST_WIRE_VERSION - 1,
+ WireVersion::LAST_LTS_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION,
+ WireVersion::LAST_CONT_WIRE_VERSION);
+
+ // 'last-lts' binary with 'last-lts' FCV -> 'latest' binary with 'latest' FCV
+ VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
+ WireVersion::LAST_LTS_WIRE_VERSION,
+ WireVersion::LAST_LTS_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION,
WireVersion::LATEST_WIRE_VERSION);
+ // 'last-lts' binary with 'last-lts' FCV -> 'latest' binary with 'last-lts' FCV
+ VALIDATE_WIRE_VERSION(ASSERT_OK,
+ WireVersion::LAST_LTS_WIRE_VERSION,
+ WireVersion::LAST_LTS_WIRE_VERSION,
+ WireVersion::LAST_LTS_WIRE_VERSION,
+ WireVersion::LATEST_WIRE_VERSION);
+
/*
- * Test that it is disallowed for MongoS to communicate with a lower binary server, regardless
- * of FCV.
+ * Test communication between:
+ * variable MongoS binary version -> MongoD 'latest' binary version
+ * Note that it is disallowed for MongoS to communicate with a lower binary server.
*/
- // MongoS 'latest' -> MongoD downgraded 'last-lts' server
- VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 2,
- WireVersion::LATEST_WIRE_VERSION - 1);
-
- // MongoS 'latest' -> MongoD upgraded 'last-lts' server
- VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION,
- WireVersion::LATEST_WIRE_VERSION - 1,
- WireVersion::LATEST_WIRE_VERSION - 1);
+ for (const auto& mongoSRange : mongoSBinaryRanges) {
+ for (const auto& mongoDLatestRange : mongoDLatestBinaryRanges) {
+ // MongoS 'latest' binary can communicate with all FCV versions
+ // MongoS 'last-cont' binary can only communicate with MongoD downgraded 'last-cont' FCV
+ // MongoS 'last-lts' binary can only communicate with MongoD downgraded 'last-lts' FCV
+ if (mongoSRange.minWireVersion == WireVersion::LATEST_WIRE_VERSION ||
+ (mongoSRange.minWireVersion == WireVersion::LAST_CONT_WIRE_VERSION &&
+ mongoDLatestRange.minWireVersion == WireVersion::LAST_CONT_WIRE_VERSION) ||
+ (mongoSRange.minWireVersion == WireVersion::LAST_LTS_WIRE_VERSION &&
+ mongoDLatestRange.minWireVersion == WireVersion::LAST_LTS_WIRE_VERSION)) {
+ VALIDATE_WIRE_VERSION(ASSERT_OK,
+ mongoSRange.minWireVersion,
+ mongoSRange.maxWireVersion,
+ mongoDLatestRange.minWireVersion,
+ mongoDLatestRange.maxWireVersion);
+ } else {
+ VALIDATE_WIRE_VERSION(ASSERT_NOT_OK,
+ mongoSRange.minWireVersion,
+ mongoSRange.maxWireVersion,
+ mongoDLatestRange.minWireVersion,
+ mongoDLatestRange.maxWireVersion);
+ }
+ }
+ }
}
// A mongos is unable to communicate with a fully upgraded cluster with a higher wire version.