diff options
Diffstat (limited to 'src/mongo/rpc/metadata/server_selection_metadata_test.cpp')
-rw-r--r-- | src/mongo/rpc/metadata/server_selection_metadata_test.cpp | 265 |
1 files changed, 136 insertions, 129 deletions
diff --git a/src/mongo/rpc/metadata/server_selection_metadata_test.cpp b/src/mongo/rpc/metadata/server_selection_metadata_test.cpp index fe6de217b46..ae8d4057b45 100644 --- a/src/mongo/rpc/metadata/server_selection_metadata_test.cpp +++ b/src/mongo/rpc/metadata/server_selection_metadata_test.cpp @@ -38,138 +38,145 @@ #include "mongo/unittest/unittest.h" namespace { - using namespace mongo; - using namespace mongo::rpc; - using mongo::unittest::assertGet; - - ServerSelectionMetadata checkParse(const BSONObj& metadata) { - return assertGet(ServerSelectionMetadata::readFromMetadata(metadata)); +using namespace mongo; +using namespace mongo::rpc; +using mongo::unittest::assertGet; + +ServerSelectionMetadata checkParse(const BSONObj& metadata) { + return assertGet(ServerSelectionMetadata::readFromMetadata(metadata)); +} + +TEST(ServerSelectionMetadata, ReadFromMetadata) { + { + // Empty object - should work just fine. + auto ss = checkParse(BSONObj()); + ASSERT_FALSE(ss.isSecondaryOk()); + ASSERT_FALSE(ss.getReadPreference().is_initialized()); } - - TEST(ServerSelectionMetadata, ReadFromMetadata) { - { - // Empty object - should work just fine. - auto ss = checkParse(BSONObj()); - ASSERT_FALSE(ss.isSecondaryOk()); - ASSERT_FALSE(ss.getReadPreference().is_initialized()); - } - { - // Set secondaryOk but not readPreference. - auto ss = checkParse(BSON("$secondaryOk" << 1)); - ASSERT_TRUE(ss.isSecondaryOk()); - ASSERT_FALSE(ss.getReadPreference().is_initialized()); - } - { - // Set readPreference but not secondaryOk. - auto ss = checkParse(BSON("$readPreference" << - BSON("mode" << "primary"))); - ASSERT_FALSE(ss.isSecondaryOk()); - ASSERT_TRUE(ss.getReadPreference().is_initialized()); - ASSERT_TRUE(ss.getReadPreference()->pref == ReadPreference::PrimaryOnly); - } - { - // Set both. - auto ss = checkParse(BSON("$secondaryOk" << 1 << - "$readPreference" << - BSON("mode" << "secondaryPreferred"))); - ASSERT_TRUE(ss.isSecondaryOk()); - ASSERT_TRUE(ss.getReadPreference()->pref == ReadPreference::SecondaryPreferred); - } + { + // Set secondaryOk but not readPreference. + auto ss = checkParse(BSON("$secondaryOk" << 1)); + ASSERT_TRUE(ss.isSecondaryOk()); + ASSERT_FALSE(ss.getReadPreference().is_initialized()); } - - void checkUpconvert(const BSONObj& legacyCommand, - const int legacyQueryFlags, - const BSONObj& upconvertedCommand, - const BSONObj& upconvertedMetadata) { - BSONObjBuilder upconvertedCommandBob; - BSONObjBuilder upconvertedMetadataBob; - auto convertStatus = ServerSelectionMetadata::upconvert(legacyCommand, - legacyQueryFlags, - &upconvertedCommandBob, - &upconvertedMetadataBob); - ASSERT_OK(convertStatus); - // We don't care about the order of the fields in the metadata object - const auto sorted = [](const BSONObj& obj) { - BSONObjIteratorSorted iter(obj); - BSONObjBuilder bob; - while (iter.more()) { - bob.append(iter.next()); - } - return bob.obj(); - }; - - ASSERT_EQ(upconvertedCommand, upconvertedCommandBob.done()); - ASSERT_EQ(sorted(upconvertedMetadata), sorted(upconvertedMetadataBob.done())); + { + // Set readPreference but not secondaryOk. + auto ss = checkParse(BSON("$readPreference" << BSON("mode" + << "primary"))); + ASSERT_FALSE(ss.isSecondaryOk()); + ASSERT_TRUE(ss.getReadPreference().is_initialized()); + ASSERT_TRUE(ss.getReadPreference()->pref == ReadPreference::PrimaryOnly); } - - TEST(ServerSelectionMetadata, UpconvertValidMetadata) { - // Wrapped in $query, with readPref and slaveOk bit set. - checkUpconvert(BSON("$query" << BSON("ping" << 1) << - "$readPreference" << BSON("mode" << "secondary")), - mongo::QueryOption_SlaveOk, - BSON("ping" << 1), - BSON("$secondaryOk" << 1 << - "$readPreference" << BSON("mode" << "secondary"))); - - // Wrapped in 'query', with readPref. - checkUpconvert(BSON("query" << BSON("pong" << 1 << "foo" << "bar") << - "$readPreference" << BSON("mode" << "primary" << - "tags" << BSON("dc" << "ny"))), - 0, - BSON("pong" << 1 << "foo" << "bar"), - BSON("$readPreference" << BSON("mode" << "primary" << - "tags" << BSON("dc" << "ny")))); - // Unwrapped, no readPref, no slaveOk - checkUpconvert(BSON("ping" << 1), - 0, - BSON("ping" << 1), - BSONObj()); - - // Readpref wrapped in $queryOptions - checkUpconvert(BSON("pang" << "pong" << - "$queryOptions" << - BSON("$readPreference" << BSON("mode" << "nearest" << - "tags" << BSON("rack" << "city")))), - 0, - BSON("pang" << "pong"), - BSON("$readPreference" << BSON("mode" << "nearest" << - "tags" << BSON("rack" << "city")))); - } - - void checkUpconvertFails(const BSONObj& legacyCommand, ErrorCodes::Error error) { - BSONObjBuilder upconvertedCommandBob; - BSONObjBuilder upconvertedMetadataBob; - auto upconvertStatus = ServerSelectionMetadata::upconvert(legacyCommand, - 0, - &upconvertedCommandBob, - &upconvertedMetadataBob); - ASSERT_NOT_OK(upconvertStatus); - ASSERT_EQ(upconvertStatus.code(), error); - } - - TEST(ServerSelectionMetadata, UpconvertInvalidMetadata) { - // $readPreference not an object. - checkUpconvertFails(BSON("$query" << BSON("pang" << "pong") << - "$readPreference" << 2), - ErrorCodes::TypeMismatch); - - // has $maxTimeMS option - checkUpconvertFails(BSON("query" << BSON("foo" << "bar") << - "$maxTimeMS" << 200), - ErrorCodes::InvalidOptions); - checkUpconvertFails(BSON("$query" << BSON("foo" << "bar") << - "$maxTimeMS" << 200), - ErrorCodes::InvalidOptions); - - // has $queryOptions field, but invalid $readPreference - checkUpconvertFails(BSON("ping" << "pong" << - "$queryOptions" << BSON("$readPreference" << 1.2)), - ErrorCodes::TypeMismatch); - - // has $queryOptions field, but no $readPreference - checkUpconvertFails(BSON("ping" << "pong" << - "$queryOptions" << BSONObj()), - ErrorCodes::NoSuchKey); + { + // Set both. + auto ss = checkParse( + BSON("$secondaryOk" << 1 << "$readPreference" << BSON("mode" + << "secondaryPreferred"))); + ASSERT_TRUE(ss.isSecondaryOk()); + ASSERT_TRUE(ss.getReadPreference()->pref == ReadPreference::SecondaryPreferred); } +} + +void checkUpconvert(const BSONObj& legacyCommand, + const int legacyQueryFlags, + const BSONObj& upconvertedCommand, + const BSONObj& upconvertedMetadata) { + BSONObjBuilder upconvertedCommandBob; + BSONObjBuilder upconvertedMetadataBob; + auto convertStatus = ServerSelectionMetadata::upconvert( + legacyCommand, legacyQueryFlags, &upconvertedCommandBob, &upconvertedMetadataBob); + ASSERT_OK(convertStatus); + // We don't care about the order of the fields in the metadata object + const auto sorted = [](const BSONObj& obj) { + BSONObjIteratorSorted iter(obj); + BSONObjBuilder bob; + while (iter.more()) { + bob.append(iter.next()); + } + return bob.obj(); + }; + + ASSERT_EQ(upconvertedCommand, upconvertedCommandBob.done()); + ASSERT_EQ(sorted(upconvertedMetadata), sorted(upconvertedMetadataBob.done())); +} + +TEST(ServerSelectionMetadata, UpconvertValidMetadata) { + // Wrapped in $query, with readPref and slaveOk bit set. + checkUpconvert(BSON("$query" << BSON("ping" << 1) << "$readPreference" << BSON("mode" + << "secondary")), + mongo::QueryOption_SlaveOk, + BSON("ping" << 1), + BSON("$secondaryOk" << 1 << "$readPreference" << BSON("mode" + << "secondary"))); + + // Wrapped in 'query', with readPref. + checkUpconvert(BSON("query" << BSON("pong" << 1 << "foo" + << "bar") << "$readPreference" + << BSON("mode" + << "primary" + << "tags" << BSON("dc" + << "ny"))), + 0, + BSON("pong" << 1 << "foo" + << "bar"), + BSON("$readPreference" << BSON("mode" + << "primary" + << "tags" << BSON("dc" + << "ny")))); + // Unwrapped, no readPref, no slaveOk + checkUpconvert(BSON("ping" << 1), 0, BSON("ping" << 1), BSONObj()); + + // Readpref wrapped in $queryOptions + checkUpconvert(BSON("pang" + << "pong" + << "$queryOptions" + << BSON("$readPreference" << BSON("mode" + << "nearest" + << "tags" << BSON("rack" + << "city")))), + 0, + BSON("pang" + << "pong"), + BSON("$readPreference" << BSON("mode" + << "nearest" + << "tags" << BSON("rack" + << "city")))); +} + +void checkUpconvertFails(const BSONObj& legacyCommand, ErrorCodes::Error error) { + BSONObjBuilder upconvertedCommandBob; + BSONObjBuilder upconvertedMetadataBob; + auto upconvertStatus = ServerSelectionMetadata::upconvert( + legacyCommand, 0, &upconvertedCommandBob, &upconvertedMetadataBob); + ASSERT_NOT_OK(upconvertStatus); + ASSERT_EQ(upconvertStatus.code(), error); +} + +TEST(ServerSelectionMetadata, UpconvertInvalidMetadata) { + // $readPreference not an object. + checkUpconvertFails(BSON("$query" << BSON("pang" + << "pong") << "$readPreference" << 2), + ErrorCodes::TypeMismatch); + + // has $maxTimeMS option + checkUpconvertFails(BSON("query" << BSON("foo" + << "bar") << "$maxTimeMS" << 200), + ErrorCodes::InvalidOptions); + checkUpconvertFails(BSON("$query" << BSON("foo" + << "bar") << "$maxTimeMS" << 200), + ErrorCodes::InvalidOptions); + + // has $queryOptions field, but invalid $readPreference + checkUpconvertFails(BSON("ping" + << "pong" + << "$queryOptions" << BSON("$readPreference" << 1.2)), + ErrorCodes::TypeMismatch); + + // has $queryOptions field, but no $readPreference + checkUpconvertFails(BSON("ping" + << "pong" + << "$queryOptions" << BSONObj()), + ErrorCodes::NoSuchKey); +} } // namespace |