diff options
Diffstat (limited to 'src/mongo/db/pipeline/aggregation_request_test.cpp')
-rw-r--r-- | src/mongo/db/pipeline/aggregation_request_test.cpp | 105 |
1 files changed, 99 insertions, 6 deletions
diff --git a/src/mongo/db/pipeline/aggregation_request_test.cpp b/src/mongo/db/pipeline/aggregation_request_test.cpp index 45313fc8a1e..a40bca8d8d1 100644 --- a/src/mongo/db/pipeline/aggregation_request_test.cpp +++ b/src/mongo/db/pipeline/aggregation_request_test.cpp @@ -58,7 +58,8 @@ TEST(AggregationRequestTest, ShouldParseAllKnownOptions) { "bypassDocumentValidation: true, collation: {locale: 'en_US'}, cursor: {batchSize: 10}, " "hint: {a: 1}}"); auto request = unittest::assertGet(AggregationRequest::parseFromBSON(nss, inputBson)); - ASSERT_TRUE(request.isExplain()); + ASSERT_TRUE(request.getExplain()); + ASSERT(*request.getExplain() == ExplainOptions::Verbosity::kQueryPlanner); ASSERT_TRUE(request.shouldAllowDiskUse()); ASSERT_TRUE(request.isFromRouter()); ASSERT_TRUE(request.shouldBypassDocumentValidation()); @@ -69,6 +70,33 @@ TEST(AggregationRequestTest, ShouldParseAllKnownOptions) { << "en_US")); } +TEST(AggregationRequestTest, ShouldParseExplicitExplainFalseWithCursorOption) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: [], explain: false, cursor: {batchSize: 10}}"); + auto request = unittest::assertGet(AggregationRequest::parseFromBSON(nss, inputBson)); + ASSERT_FALSE(request.getExplain()); + ASSERT_EQ(request.getBatchSize(), 10); +} + +TEST(AggregationRequestTest, ShouldParseWithSeparateQueryPlannerExplainModeArg) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: []}"); + auto request = unittest::assertGet(AggregationRequest::parseFromBSON( + nss, inputBson, ExplainOptions::Verbosity::kQueryPlanner)); + ASSERT_TRUE(request.getExplain()); + ASSERT(*request.getExplain() == ExplainOptions::Verbosity::kQueryPlanner); +} + +TEST(AggregationRequestTest, ShouldParseWithSeparateQueryPlannerExplainModeArgAndCursorOption) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: [], cursor: {batchSize: 10}}"); + auto request = unittest::assertGet( + AggregationRequest::parseFromBSON(nss, inputBson, ExplainOptions::Verbosity::kExecStats)); + ASSERT_TRUE(request.getExplain()); + ASSERT(*request.getExplain() == ExplainOptions::Verbosity::kExecStats); + ASSERT_EQ(request.getBatchSize(), 10); +} + // // Serialization // @@ -87,7 +115,7 @@ TEST(AggregationRequestTest, ShouldOnlySerializeRequiredFieldsIfNoOptionalFields TEST(AggregationRequestTest, ShouldNotSerializeOptionalValuesIfEquivalentToDefault) { NamespaceString nss("a.collection"); AggregationRequest request(nss, {}); - request.setExplain(false); + request.setExplain(boost::none); request.setAllowDiskUse(false); request.setFromRouter(false); request.setBypassDocumentValidation(false); @@ -104,11 +132,10 @@ TEST(AggregationRequestTest, ShouldNotSerializeOptionalValuesIfEquivalentToDefau TEST(AggregationRequestTest, ShouldSerializeOptionalValuesIfSet) { NamespaceString nss("a.collection"); AggregationRequest request(nss, {}); - request.setExplain(true); request.setAllowDiskUse(true); request.setFromRouter(true); request.setBypassDocumentValidation(true); - request.setBatchSize(10); // batchSize not serialzed when explain is true. + request.setBatchSize(10); const auto hintObj = BSON("a" << 1); request.setHint(hintObj); const auto collationObj = BSON("locale" @@ -118,11 +145,12 @@ TEST(AggregationRequestTest, ShouldSerializeOptionalValuesIfSet) { auto expectedSerialization = Document{{AggregationRequest::kCommandName, nss.coll()}, {AggregationRequest::kPipelineName, Value(std::vector<Value>{})}, - {AggregationRequest::kExplainName, true}, {AggregationRequest::kAllowDiskUseName, true}, {AggregationRequest::kFromRouterName, true}, {bypassDocumentValidationCommandOption(), true}, {AggregationRequest::kCollationName, collationObj}, + {AggregationRequest::kCursorName, + Value(Document({{AggregationRequest::kBatchSizeName, 10}}))}, {AggregationRequest::kHintName, hintObj}}; ASSERT_DOCUMENT_EQ(request.serializeToCommandObj(), expectedSerialization); } @@ -159,6 +187,18 @@ TEST(AggregationRequestTest, ShouldAcceptHintAsString) { << "a_1")); } +TEST(AggregationRequestTest, ShouldNotSerializeBatchSizeOrExplainWhenExplainSet) { + NamespaceString nss("a.collection"); + AggregationRequest request(nss, {}); + request.setBatchSize(10); + request.setExplain(ExplainOptions::Verbosity::kQueryPlanner); + + auto expectedSerialization = + Document{{AggregationRequest::kCommandName, nss.coll()}, + {AggregationRequest::kPipelineName, Value(std::vector<Value>{})}}; + ASSERT_DOCUMENT_EQ(request.serializeToCommandObj(), expectedSerialization); +} + // // Error cases. // @@ -201,13 +241,20 @@ TEST(AggregationRequestTest, ShouldRejectHintAsArray) { AggregationRequest::parseFromBSON(NamespaceString("a.collection"), inputBson).getStatus()); } -TEST(AggregationRequestTest, ShouldRejectNonBoolExplain) { +TEST(AggregationRequestTest, ShouldRejectExplainIfNumber) { NamespaceString nss("a.collection"); const BSONObj inputBson = fromjson("{pipeline: [{$match: {a: 'abc'}}], cursor: {}, explain: 1}"); ASSERT_NOT_OK(AggregationRequest::parseFromBSON(nss, inputBson).getStatus()); } +TEST(AggregationRequestTest, ShouldRejectExplainIfObject) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = + fromjson("{pipeline: [{$match: {a: 'abc'}}], cursor: {}, explain: {}}"); + ASSERT_NOT_OK(AggregationRequest::parseFromBSON(nss, inputBson).getStatus()); +} + TEST(AggregationRequestTest, ShouldRejectNonBoolFromRouter) { NamespaceString nss("a.collection"); const BSONObj inputBson = @@ -228,6 +275,52 @@ TEST(AggregationRequestTest, ShouldRejectNoCursorNoExplain) { ASSERT_NOT_OK(AggregationRequest::parseFromBSON(nss, inputBson).getStatus()); } +TEST(AggregationRequestTest, ShouldRejectExplainTrueWithSeparateExplainArg) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: [], explain: true}"); + ASSERT_NOT_OK( + AggregationRequest::parseFromBSON(nss, inputBson, ExplainOptions::Verbosity::kExecStats) + .getStatus()); +} + +TEST(AggregationRequestTest, ShouldRejectExplainFalseWithSeparateExplainArg) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: [], explain: false}"); + ASSERT_NOT_OK( + AggregationRequest::parseFromBSON(nss, inputBson, ExplainOptions::Verbosity::kExecStats) + .getStatus()); +} + +TEST(AggregationRequestTest, ShouldRejectExplainWithReadConcernMajority) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = + fromjson("{pipeline: [], explain: true, readConcern: {level: 'majority'}}"); + ASSERT_NOT_OK(AggregationRequest::parseFromBSON(nss, inputBson).getStatus()); +} + +TEST(AggregationRequestTest, ShouldRejectExplainExecStatsVerbosityWithReadConcernMajority) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: [], readConcern: {level: 'majority'}}"); + ASSERT_NOT_OK( + AggregationRequest::parseFromBSON(nss, inputBson, ExplainOptions::Verbosity::kExecStats) + .getStatus()); +} + +TEST(AggregationRequestTest, ShouldRejectExplainWithWriteConcernMajority) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = + fromjson("{pipeline: [], explain: true, writeConcern: {w: 'majority'}}"); + ASSERT_NOT_OK(AggregationRequest::parseFromBSON(nss, inputBson).getStatus()); +} + +TEST(AggregationRequestTest, ShouldRejectExplainExecStatsVerbosityWithWriteConcernMajority) { + NamespaceString nss("a.collection"); + const BSONObj inputBson = fromjson("{pipeline: [], writeConcern: {w: 'majority'}}"); + ASSERT_NOT_OK( + AggregationRequest::parseFromBSON(nss, inputBson, ExplainOptions::Verbosity::kExecStats) + .getStatus()); +} + // // Ignore fields parsed elsewhere. // |