summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/query_stage_multiplan.cpp
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2020-01-14 23:53:47 +0000
committerevergreen <evergreen@mongodb.com>2020-01-14 23:53:47 +0000
commitafb5bcf6c92775d4755b68500ddf1080429223a1 (patch)
tree8c43e7da9a762b84fdbbb492ae816931f775aeb7 /src/mongo/dbtests/query_stage_multiplan.cpp
parent917d0b9ab37d5a1027d76665c41d16a4baa0cf92 (diff)
downloadmongo-afb5bcf6c92775d4755b68500ddf1080429223a1.tar.gz
SERVER-45507 Add context around planning failures
Diffstat (limited to 'src/mongo/dbtests/query_stage_multiplan.cpp')
-rw-r--r--src/mongo/dbtests/query_stage_multiplan.cpp60
1 files changed, 59 insertions, 1 deletions
diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp
index 877b4c2213c..8db55bc4f87 100644
--- a/src/mongo/dbtests/query_stage_multiplan.cpp
+++ b/src/mongo/dbtests/query_stage_multiplan.cpp
@@ -591,7 +591,10 @@ TEST_F(QueryStageMultiPlanTest, ShouldReportErrorIfExceedsTimeLimitDuringPlannin
multiPlanStage.addPlan(createQuerySolution(), std::move(collScanRoot), sharedWs.get());
AlwaysTimeOutYieldPolicy alwaysTimeOutPolicy(serviceContext()->getFastClockSource());
- ASSERT_EQ(ErrorCodes::ExceededTimeLimit, multiPlanStage.pickBestPlan(&alwaysTimeOutPolicy));
+ const auto status = multiPlanStage.pickBestPlan(&alwaysTimeOutPolicy);
+ ASSERT_EQ(ErrorCodes::ExceededTimeLimit, status);
+ ASSERT_STRING_CONTAINS(status.reason(),
+ "multiplanner encountered a failure while selecting best plan");
}
TEST_F(QueryStageMultiPlanTest, ShouldReportErrorIfKilledDuringPlanning) {
@@ -635,5 +638,60 @@ TEST_F(QueryStageMultiPlanTest, ShouldReportErrorIfKilledDuringPlanning) {
multiPlanStage.pickBestPlan(&alwaysPlanKilledYieldPolicy));
}
+/**
+ * A PlanStage for testing which always throws exceptions.
+ */
+class ThrowyPlanStage : public PlanStage {
+protected:
+ StageState doWork(WorkingSetID* out) {
+ uasserted(ErrorCodes::InternalError, "Mwahahaha! You've fallen into my trap.");
+ }
+
+public:
+ ThrowyPlanStage(OperationContext* opCtx) : PlanStage("throwy", opCtx) {}
+ bool isEOF() final {
+ return false;
+ }
+ StageType stageType() const final {
+ return STAGE_UNKNOWN;
+ }
+ virtual std::unique_ptr<PlanStageStats> getStats() final {
+ return nullptr;
+ }
+ virtual const SpecificStats* getSpecificStats() const final {
+ return nullptr;
+ }
+};
+
+TEST_F(QueryStageMultiPlanTest, AddsContextDuringException) {
+ insert(BSON("foo" << 10));
+ AutoGetCollectionForReadCommand ctx(_opCtx.get(), nss);
+
+ auto queryRequest = std::make_unique<QueryRequest>(nss);
+ queryRequest->setFilter(BSON("fake"
+ << "query"));
+ auto canonicalQuery =
+ uassertStatusOK(CanonicalQuery::canonicalize(opCtx(), std::move(queryRequest)));
+ MultiPlanStage multiPlanStage(opCtx(),
+ ctx.getCollection(),
+ canonicalQuery.get(),
+ MultiPlanStage::CachingMode::NeverCache);
+ unique_ptr<WorkingSet> sharedWs(new WorkingSet());
+ multiPlanStage.addPlan(
+ createQuerySolution(), std::make_unique<ThrowyPlanStage>(opCtx()), sharedWs.get());
+ multiPlanStage.addPlan(
+ createQuerySolution(), std::make_unique<ThrowyPlanStage>(opCtx()), sharedWs.get());
+
+ PlanYieldPolicy yieldPolicy(PlanExecutor::NO_YIELD, _clock);
+ ASSERT_THROWS_WITH_CHECK(multiPlanStage.pickBestPlan(&yieldPolicy),
+ AssertionException,
+ [](const AssertionException& ex) {
+ ASSERT_EQ(ex.toStatus().code(), ErrorCodes::InternalError);
+ ASSERT_STRING_CONTAINS(
+ ex.what(),
+ "exception thrown while multiplanner was selecting best plan");
+ });
+}
+
} // namespace
} // namespace mongo