summaryrefslogtreecommitdiff
path: root/src/mongo/db/operation_context_test.cpp
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@mongodb.com>2022-02-10 11:11:41 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-10 17:40:45 +0000
commitd8ff665343ad29cf286ee2cf4a1960d29371937b (patch)
tree132cda0c3339655dd8cff29d26a92937a12c29e4 /src/mongo/db/operation_context_test.cpp
parent482d143fdff542e67b7aa2a2d9e7c4468d1ecd28 (diff)
downloadmongo-d8ff665343ad29cf286ee2cf4a1960d29371937b.tar.gz
SERVER-63143 Operation can be interrupted by maxTimeMS timeout while waiting for lock even if _ignoreInterruptsExceptForReplStateChange is set
Diffstat (limited to 'src/mongo/db/operation_context_test.cpp')
-rw-r--r--src/mongo/db/operation_context_test.cpp68
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()>;