diff options
author | Grace Luong <grace.luong@mongodb.com> | 2020-07-31 20:04:02 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-07-31 20:58:02 +0000 |
commit | cd5a75ea3bf3915617a04a9ec463bfb2c467b27e (patch) | |
tree | 131002f02b182c7ca324c1be475a5a3c93e14f89 | |
parent | 134c3ee37576de7ec36456fe3420305d6871b874 (diff) | |
download | mongo-cd5a75ea3bf3915617a04a9ec463bfb2c467b27e.tar.gz |
SERVER-49270: Set minWireVersion based on FCV and refactor protocol tests
-rw-r--r-- | src/mongo/db/commands/feature_compatibility_version.cpp | 41 | ||||
-rw-r--r-- | src/mongo/db/server_options.h | 5 | ||||
-rw-r--r-- | src/mongo/db/wire_version.h | 7 | ||||
-rw-r--r-- | src/mongo/rpc/protocol_test.cpp | 229 |
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. |