summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWilliam Schultz <william.schultz@mongodb.com>2020-04-09 20:09:25 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-10 00:34:43 +0000
commit9c5d82ff1fb2bb7367e10c9e21ac67b440e7097e (patch)
treeb0149e2037ba2bfddb0ad40b617336e1253f8a3b /src
parent90e56683e8d9c24f155ffbb64bb13b4169c924e8 (diff)
downloadmongo-9c5d82ff1fb2bb7367e10c9e21ac67b440e7097e.tar.gz
SERVER-46720 Allow non strict replication message parsing
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp18
-rw-r--r--src/mongo/db/repl/repl_set_heartbeat_response_test.cpp8
-rw-r--r--src/mongo/db/repl/repl_set_request_votes_args.cpp18
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp21
-rw-r--r--src/mongo/db/repl/reporter_test.cpp38
-rw-r--r--src/mongo/db/repl/vote_requester_test.cpp30
-rw-r--r--src/mongo/rpc/metadata/oplog_query_metadata_test.cpp7
-rw-r--r--src/mongo/rpc/metadata/repl_set_metadata_test.cpp7
8 files changed, 111 insertions, 36 deletions
diff --git a/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp b/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp
index d97b1d15759..688e99b1250 100644
--- a/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp
+++ b/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp
@@ -49,25 +49,11 @@ const std::string kSenderHostFieldName = "from";
const std::string kSenderIdFieldName = "fromId";
const std::string kSetNameFieldName = "replSetHeartbeat";
const std::string kTermFieldName = "term";
-
-const std::string kLegalHeartbeatFieldNames[] = {kCheckEmptyFieldName,
- kConfigVersionFieldName,
- kConfigTermFieldName,
- kHeartbeatVersionFieldName,
- kSenderHostFieldName,
- kSenderIdFieldName,
- kSetNameFieldName,
- kTermFieldName};
-
} // namespace
Status ReplSetHeartbeatArgsV1::initialize(const BSONObj& argsObj) {
- Status status = bsonCheckOnlyHasFieldsForCommand(
- "ReplSetHeartbeatArgs", argsObj, kLegalHeartbeatFieldNames);
- if (!status.isOK())
- return status;
-
- status = bsonExtractBooleanFieldWithDefault(argsObj, kCheckEmptyFieldName, false, &_checkEmpty);
+ Status status =
+ bsonExtractBooleanFieldWithDefault(argsObj, kCheckEmptyFieldName, false, &_checkEmpty);
if (!status.isOK())
return status;
diff --git a/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp b/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp
index 3851ebda892..07c1966fdd5 100644
--- a/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp
+++ b/src/mongo/db/repl/repl_set_heartbeat_response_test.cpp
@@ -124,7 +124,13 @@ TEST(ReplSetHeartbeatResponse, DefaultConstructThenSlowlyBuildToFullObj) {
ASSERT_EQUALS(2, hbResponseObj["state"].numberLong());
ASSERT_EQUALS("syncTarget:27017", hbResponseObj["syncingTo"].String());
- initializeResult = hbResponseObjRoundTripChecker.initialize(hbResponseObj, 0);
+ // Verify that we allow an unknown field.
+ BSONObjBuilder hbResponseBob;
+ hbResponseBob.appendElements(hbResponseObj);
+ hbResponseBob.append("unknownField", 1);
+ auto cmdObj = hbResponseBob.obj();
+
+ initializeResult = hbResponseObjRoundTripChecker.initialize(cmdObj, 0);
ASSERT_EQUALS(Status::OK(), initializeResult);
ASSERT_EQUALS(hbResponseObj.toString(), hbResponseObjRoundTripChecker.toBSON().toString());
}
diff --git a/src/mongo/db/repl/repl_set_request_votes_args.cpp b/src/mongo/db/repl/repl_set_request_votes_args.cpp
index b685bb0ab4e..7978b26987f 100644
--- a/src/mongo/db/repl/repl_set_request_votes_args.cpp
+++ b/src/mongo/db/repl/repl_set_request_votes_args.cpp
@@ -51,27 +51,11 @@ const std::string kSetNameFieldName = "setName";
const std::string kTermFieldName = "term";
const std::string kVoteGrantedFieldName = "voteGranted";
const std::string kOperationTime = "operationTime";
-
-const std::string kLegalArgsFieldNames[] = {
- kCandidateIndexFieldName,
- kCommandName,
- kConfigVersionFieldName,
- kConfigTermFieldName,
- kDryRunFieldName,
- kLastAppliedOpTimeFieldName,
- kSetNameFieldName,
- kTermFieldName,
- kOperationTime,
-};
-
} // namespace
Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) {
- Status status =
- bsonCheckOnlyHasFieldsForCommand("ReplSetRequestVotes", argsObj, kLegalArgsFieldNames);
-
- status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
+ Status status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
if (!status.isOK())
return status;
diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp
index ed453a28f1f..4a1a347b0d2 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat_v1_test.cpp
@@ -56,6 +56,27 @@ using executor::NetworkInterfaceMock;
using executor::RemoteCommandRequest;
using executor::RemoteCommandResponse;
+TEST(ReplSetHeartbeatArgs, AcceptsUnknownField) {
+ ReplSetHeartbeatArgsV1 hbArgs;
+ hbArgs.setConfigTerm(1);
+ hbArgs.setConfigVersion(1);
+ hbArgs.setHeartbeatVersion(1);
+ hbArgs.setTerm(1);
+ hbArgs.setSenderHost(HostAndPort("host:1"));
+ hbArgs.setSetName("replSet");
+ BSONObjBuilder bob;
+ hbArgs.addToBSON(&bob);
+ bob.append("unknownField", 1); // append an unknown field.
+ BSONObj cmdObj = bob.obj();
+ ASSERT_OK(hbArgs.initialize(cmdObj));
+
+ // The serialized object should be the same as the original except for the unknown field.
+ BSONObjBuilder bob2;
+ hbArgs.addToBSON(&bob2);
+ bob2.append("unknownField", 1);
+ ASSERT_BSONOBJ_EQ(bob2.obj(), cmdObj);
+}
+
class ReplCoordHBV1Test : public ReplCoordTest {
protected:
void assertMemberState(MemberState expected, std::string msg = "");
diff --git a/src/mongo/db/repl/reporter_test.cpp b/src/mongo/db/repl/reporter_test.cpp
index f4538c6c6fa..260c50bbbfc 100644
--- a/src/mongo/db/repl/reporter_test.cpp
+++ b/src/mongo/db/repl/reporter_test.cpp
@@ -234,6 +234,44 @@ void ReporterTest::assertReporterDone() {
ASSERT_EQUALS(reporter->join(), reporter->trigger());
}
+TEST(UpdatePositionArgs, AcceptsUnknownField) {
+ UpdatePositionArgs updatePositionArgs;
+ BSONObjBuilder bob;
+ bob.append(UpdatePositionArgs::kCommandFieldName, 1);
+ bob.append(UpdatePositionArgs::kUpdateArrayFieldName, BSONArray());
+ bob.append("unknownField", 1); // append an unknown field.
+ BSONObj cmdObj = bob.obj();
+ ASSERT_OK(updatePositionArgs.initialize(cmdObj));
+}
+TEST(UpdatePositionArgs, AcceptsUnknownFieldInUpdateInfo) {
+ UpdatePositionArgs updatePositionArgs;
+ BSONObjBuilder bob;
+ bob.append(UpdatePositionArgs::kCommandFieldName, 1);
+ auto now = Date_t();
+ auto updateInfo =
+ BSON(UpdatePositionArgs::kConfigVersionFieldName
+ << 1 << UpdatePositionArgs::kMemberIdFieldName << 1
+ << UpdatePositionArgs::kDurableOpTimeFieldName << OpTime()
+ << UpdatePositionArgs::kAppliedOpTimeFieldName << OpTime()
+ << UpdatePositionArgs::kAppliedWallTimeFieldName << now
+ << UpdatePositionArgs::kDurableWallTimeFieldName << now << "unknownField" << 1);
+ bob.append(UpdatePositionArgs::kUpdateArrayFieldName, BSON_ARRAY(updateInfo));
+ BSONObj cmdObj = bob.obj();
+ ASSERT_OK(updatePositionArgs.initialize(cmdObj));
+
+ // The serialized object should be the same as the original except for the unknown field.
+ BSONObjBuilder bob2;
+ auto updateArgsObj = updatePositionArgs.toBSON();
+ auto updatesArr =
+ BSONArray(updateArgsObj.getObjectField(UpdatePositionArgs::kUpdateArrayFieldName));
+ ASSERT_EQ(updatesArr.nFields(), 1);
+ bob2.appendElements(updatesArr[0].Obj());
+ bob2.append(UpdatePositionArgs::kAppliedWallTimeFieldName, now);
+ bob2.append(UpdatePositionArgs::kDurableWallTimeFieldName, now);
+ bob2.append("unknownField", 1);
+ ASSERT_EQ(bob2.obj().woCompare(updateInfo), 0);
+}
+
TEST_F(ReporterTestNoTriggerAtSetUp, InvalidConstruction) {
// null PrepareReplSetUpdatePositionCommandFn
ASSERT_THROWS(Reporter(&getExecutor(),
diff --git a/src/mongo/db/repl/vote_requester_test.cpp b/src/mongo/db/repl/vote_requester_test.cpp
index b5155003603..8fc176e0c10 100644
--- a/src/mongo/db/repl/vote_requester_test.cpp
+++ b/src/mongo/db/repl/vote_requester_test.cpp
@@ -54,6 +54,36 @@ bool stringContains(const std::string& haystack, const std::string& needle) {
return haystack.find(needle) != std::string::npos;
}
+TEST(ReplSetRequestVotes, ArgsAcceptsUnknownField) {
+ ReplSetRequestVotesArgs requestVoteArgs;
+ BSONObjBuilder bob;
+ requestVoteArgs.addToBSON(&bob);
+ bob.append("unknownField", 1); // append an unknown field.
+ BSONObj cmdObj = bob.obj();
+ ASSERT_OK(requestVoteArgs.initialize(cmdObj));
+
+ // The serialized object should be the same as the original except for the unknown field.
+ BSONObjBuilder bob2;
+ requestVoteArgs.addToBSON(&bob2);
+ bob2.append("unknownField", 1);
+ ASSERT_BSONOBJ_EQ(bob2.obj(), cmdObj);
+}
+
+TEST(ReplSetRequestVotes, ResponseAcceptsUnknownField) {
+ ReplSetRequestVotesResponse requestVoteRes;
+ BSONObjBuilder bob;
+ requestVoteRes.addToBSON(&bob);
+ bob.append("unknownField", 1); // append an unknown field.
+ BSONObj cmdObj = bob.obj();
+ ASSERT_OK(requestVoteRes.initialize(cmdObj));
+
+ // The serialized object should be the same as the original except for the unknown field.
+ BSONObjBuilder bob2;
+ requestVoteRes.addToBSON(&bob2);
+ bob2.append("unknownField", 1);
+ ASSERT_BSONOBJ_EQ(bob2.obj(), cmdObj);
+}
+
class VoteRequesterTest : public mongo::unittest::Test {
public:
diff --git a/src/mongo/rpc/metadata/oplog_query_metadata_test.cpp b/src/mongo/rpc/metadata/oplog_query_metadata_test.cpp
index 8fc74167115..bb267ccac59 100644
--- a/src/mongo/rpc/metadata/oplog_query_metadata_test.cpp
+++ b/src/mongo/rpc/metadata/oplog_query_metadata_test.cpp
@@ -62,7 +62,12 @@ TEST(ReplResponseMetadataTest, OplogQueryMetadataRoundtrip) {
BSONObj serializedObj = builder.obj();
ASSERT_BSONOBJ_EQ(expectedObj, serializedObj);
- auto cloneStatus = OplogQueryMetadata::readFromMetadata(serializedObj);
+ // Verify that we allow unknown fields.
+ BSONObjBuilder bob;
+ bob.appendElements(serializedObj);
+ bob.append("unknownField", 1);
+
+ auto cloneStatus = OplogQueryMetadata::readFromMetadata(bob.obj());
ASSERT_OK(cloneStatus.getStatus());
const auto& clonedMetadata = cloneStatus.getValue();
diff --git a/src/mongo/rpc/metadata/repl_set_metadata_test.cpp b/src/mongo/rpc/metadata/repl_set_metadata_test.cpp
index 9a121fd20d5..b7c1b0825a3 100644
--- a/src/mongo/rpc/metadata/repl_set_metadata_test.cpp
+++ b/src/mongo/rpc/metadata/repl_set_metadata_test.cpp
@@ -73,7 +73,12 @@ TEST(ReplResponseMetadataTest, Roundtrip) {
BSONObj serializedObj = builder.obj();
ASSERT_BSONOBJ_EQ(expectedObj, serializedObj);
- auto cloneStatus = ReplSetMetadata::readFromMetadata(serializedObj);
+ // Verify that we allow unknown fields.
+ BSONObjBuilder bob;
+ bob.appendElements(serializedObj);
+ bob.append("unknownField", 1);
+
+ auto cloneStatus = ReplSetMetadata::readFromMetadata(bob.obj());
ASSERT_OK(cloneStatus.getStatus());
const auto& clonedMetadata = cloneStatus.getValue();