diff options
author | Charlie Swanson <charlie.swanson@mongodb.com> | 2020-01-14 23:53:47 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2020-01-14 23:53:47 +0000 |
commit | afb5bcf6c92775d4755b68500ddf1080429223a1 (patch) | |
tree | 8c43e7da9a762b84fdbbb492ae816931f775aeb7 /src/mongo/dbtests/query_stage_multiplan.cpp | |
parent | 917d0b9ab37d5a1027d76665c41d16a4baa0cf92 (diff) | |
download | mongo-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.cpp | 60 |
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 |