diff options
Diffstat (limited to 'src/mongo/db/operation_context_test.cpp')
-rw-r--r-- | src/mongo/db/operation_context_test.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/mongo/db/operation_context_test.cpp b/src/mongo/db/operation_context_test.cpp index 66fcda8632a..6850bc61f03 100644 --- a/src/mongo/db/operation_context_test.cpp +++ b/src/mongo/db/operation_context_test.cpp @@ -737,6 +737,74 @@ TEST_F(OperationDeadlineTests, DuringWaitMaxTimeExpirationDominatesUntilExpirati ASSERT_TRUE(opCtx->getCancellationToken().isCanceled()); } +TEST_F(OperationDeadlineTests, + MaxTimeExpirationIgnoredWhenIgnoringInterruptsExceptReplStateChange) { + auto opCtx = client->makeOperationContext(); + opCtx->setDeadlineByDate(mockClock->now(), ErrorCodes::MaxTimeMSExpired); + auto m = MONGO_MAKE_LATCH(); + stdx::condition_variable cv; + stdx::unique_lock<Latch> lk(m); + ASSERT_FALSE(opCtx->getCancellationToken().isCanceled()); + opCtx->setIgnoreInterruptsExceptForReplStateChange(true); + // Advance the clock so the MaxTimeMS is hit before the timeout. + mockClock->advance(Milliseconds(100)); + ASSERT_FALSE( + opCtx->waitForConditionOrInterruptUntil(cv, lk, mockClock->now(), [] { return false; })); + ASSERT_FALSE(opCtx->getCancellationToken().isCanceled()); +} + +TEST_F(OperationDeadlineTests, + AlreadyExpiredMaxTimeIgnoredWhenIgnoringInterruptsExceptReplStateChange) { + auto opCtx = client->makeOperationContext(); + opCtx->setDeadlineByDate(mockClock->now(), ErrorCodes::MaxTimeMSExpired); + auto m = MONGO_MAKE_LATCH(); + stdx::condition_variable cv; + stdx::unique_lock<Latch> lk(m); + ASSERT_FALSE(opCtx->getCancellationToken().isCanceled()); + ASSERT_THROWS_CODE(opCtx->waitForConditionOrInterruptUntil( + cv, lk, mockClock->now() + Seconds(1), [] { return false; }), + DBException, + ErrorCodes::MaxTimeMSExpired); + + ASSERT_EQ(ErrorCodes::MaxTimeMSExpired, opCtx->checkForInterruptNoAssert()); + ASSERT_TRUE(opCtx->getCancellationToken().isCanceled()); + opCtx->setIgnoreInterruptsExceptForReplStateChange(true); + ASSERT_OK(opCtx->checkForInterruptNoAssert()); + // Advance the clock so the MaxTimeMS is hit before the timeout. + mockClock->advance(Milliseconds(100)); + ASSERT_FALSE( + opCtx->waitForConditionOrInterruptUntil(cv, lk, mockClock->now(), [] { return false; })); + ASSERT_TRUE(opCtx->getCancellationToken().isCanceled()); +} + +TEST_F(OperationDeadlineTests, + MaxTimeRespectedAfterReplStateChangeWhenIgnoringInterruptsExceptReplStateChange) { + auto opCtx = client->makeOperationContext(); + opCtx->setDeadlineByDate(mockClock->now(), ErrorCodes::MaxTimeMSExpired); + auto m = MONGO_MAKE_LATCH(); + stdx::condition_variable cv; + stdx::unique_lock<Latch> lk(m); + ASSERT_FALSE(opCtx->getCancellationToken().isCanceled()); + ASSERT_THROWS_CODE(opCtx->waitForConditionOrInterruptUntil( + cv, lk, mockClock->now() + Seconds(1), [] { return false; }), + DBException, + ErrorCodes::MaxTimeMSExpired); + + ASSERT_EQ(ErrorCodes::MaxTimeMSExpired, opCtx->checkForInterruptNoAssert()); + ASSERT_TRUE(opCtx->getCancellationToken().isCanceled()); + opCtx->setIgnoreInterruptsExceptForReplStateChange(true); + ASSERT_OK(opCtx->checkForInterruptNoAssert()); + opCtx->markKilled(ErrorCodes::InterruptedDueToReplStateChange); + ASSERT_EQ(ErrorCodes::MaxTimeMSExpired, opCtx->checkForInterruptNoAssert()); + // Advance the clock so the MaxTimeMS is hit before the timeout. + mockClock->advance(Milliseconds(100)); + ASSERT_THROWS_CODE( + opCtx->waitForConditionOrInterruptUntil(cv, lk, mockClock->now(), [] { return false; }), + DBException, + ErrorCodes::MaxTimeMSExpired); + ASSERT_TRUE(opCtx->getCancellationToken().isCanceled()); +} + class ThreadedOperationDeadlineTests : public OperationDeadlineTests { public: using CvPred = std::function<bool()>; |