diff options
author | Spencer T Brody <spencer@mongodb.com> | 2018-03-15 19:55:35 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2018-03-20 17:15:09 -0400 |
commit | cf6745a9523bb030dbceaea3bfbf26e553306762 (patch) | |
tree | cd4c464aa30d1f1abd00c30600340e3ac1b152b8 /src/mongo/db/session_catalog_test.cpp | |
parent | 6622688c3a1be6555dc9279850a6d1c0cbfa3a7d (diff) | |
download | mongo-cf6745a9523bb030dbceaea3bfbf26e553306762.tar.gz |
SERVER-33922 Remove nestingLevel from SessionCatalog, check for DBDirectClient explicitly instead
Diffstat (limited to 'src/mongo/db/session_catalog_test.cpp')
-rw-r--r-- | src/mongo/db/session_catalog_test.cpp | 96 |
1 files changed, 89 insertions, 7 deletions
diff --git a/src/mongo/db/session_catalog_test.cpp b/src/mongo/db/session_catalog_test.cpp index 7ad97852248..57506630023 100644 --- a/src/mongo/db/session_catalog_test.cpp +++ b/src/mongo/db/session_catalog_test.cpp @@ -58,6 +58,23 @@ protected: } }; +// When this class is in scope, makes the system behave as if we're in a DBDirectClient +class DirectClientSetter { +public: + explicit DirectClientSetter(OperationContext* opCtx) + : _opCtx(opCtx), _wasInDirectClient(opCtx->getClient()->isInDirectClient()) { + opCtx->getClient()->setInDirectClient(true); + } + + ~DirectClientSetter() { + _opCtx->getClient()->setInDirectClient(_wasInDirectClient); + } + +private: + const OperationContext* _opCtx; + const bool _wasInDirectClient; +}; + TEST_F(SessionCatalogTest, CheckoutAndReleaseSession) { opCtx()->setLogicalSessionId(makeLogicalSessionIdForTest()); @@ -132,6 +149,7 @@ TEST_F(SessionCatalogTest, NestedOperationContextSession) { OperationContextSession outerScopedSession(opCtx(), true, boost::none); { + DirectClientSetter inDirectClient(opCtx()); OperationContextSession innerScopedSession(opCtx(), true, boost::none); auto session = OperationContextSession::get(opCtx()); @@ -140,6 +158,7 @@ TEST_F(SessionCatalogTest, NestedOperationContextSession) { } { + DirectClientSetter inDirectClient(opCtx()); auto session = OperationContextSession::get(opCtx()); ASSERT(session); ASSERT_EQ(*opCtx()->getLogicalSessionId(), session->getSessionId()); @@ -149,22 +168,85 @@ TEST_F(SessionCatalogTest, NestedOperationContextSession) { ASSERT(!OperationContextSession::get(opCtx())); } -TEST_F(SessionCatalogTest, CannotAccessTopLevelSessionInNestedOnes) { +TEST_F(SessionCatalogTest, StashInNestedSessionIsANoop) { opCtx()->setLogicalSessionId(makeLogicalSessionIdForTest()); opCtx()->setTxnNumber(1); { OperationContextSession outerScopedSession(opCtx(), true, boost::none); - auto* session = outerScopedSession.get(opCtx(), true); - ASSERT(session); + Locker* originalLocker = opCtx()->lockState(); + RecoveryUnit* originalRecoveryUnit = opCtx()->recoveryUnit(); + ASSERT(originalLocker); + ASSERT(originalRecoveryUnit); + + // Set the readConcern on the OperationContext. + repl::ReadConcernArgs readConcernArgs; + ASSERT_OK(readConcernArgs.initialize(BSON("find" + << "test" + << repl::ReadConcernArgs::kReadConcernFieldName + << BSON(repl::ReadConcernArgs::kLevelFieldName + << "snapshot")))); + repl::ReadConcernArgs::get(opCtx()) = readConcernArgs; + + // Perform initial unstash, which sets up a WriteUnitOfWork. + OperationContextSession::get(opCtx())->unstashTransactionResources(opCtx()); + ASSERT_EQUALS(originalLocker, opCtx()->lockState()); + ASSERT_EQUALS(originalRecoveryUnit, opCtx()->recoveryUnit()); + ASSERT(opCtx()->getWriteUnitOfWork()); + { + // Make it look like we're in a DBDirectClient running a nested operation. + DirectClientSetter inDirectClient(opCtx()); OperationContextSession innerScopedSession(opCtx(), true, boost::none); - // Cannot get the top level session since we're a nested one. - const bool topLevelOnly = true; - auto* innerSession = OperationContextSession::get(opCtx(), topLevelOnly); - ASSERT(!innerSession); + // Indicate that there is a stashed cursor. If we were not in a nested session, this + // would ensure that stashing is not a noop. + opCtx()->setStashedCursor(); + + OperationContextSession::get(opCtx())->stashTransactionResources(opCtx()); + + // The stash was a noop, so the locker, RecoveryUnit, and WriteUnitOfWork on the + // OperationContext are unaffected. + ASSERT_EQUALS(originalLocker, opCtx()->lockState()); + ASSERT_EQUALS(originalRecoveryUnit, opCtx()->recoveryUnit()); + ASSERT(opCtx()->getWriteUnitOfWork()); + } + } +} + +TEST_F(SessionCatalogTest, UnstashInNestedSessionIsANoop) { + opCtx()->setLogicalSessionId(makeLogicalSessionIdForTest()); + opCtx()->setTxnNumber(1); + + { + OperationContextSession outerScopedSession(opCtx(), true, boost::none); + + Locker* originalLocker = opCtx()->lockState(); + RecoveryUnit* originalRecoveryUnit = opCtx()->recoveryUnit(); + ASSERT(originalLocker); + ASSERT(originalRecoveryUnit); + + // Set the readConcern on the OperationContext. + repl::ReadConcernArgs readConcernArgs; + ASSERT_OK(readConcernArgs.initialize(BSON("find" + << "test" + << repl::ReadConcernArgs::kReadConcernFieldName + << BSON(repl::ReadConcernArgs::kLevelFieldName + << "snapshot")))); + repl::ReadConcernArgs::get(opCtx()) = readConcernArgs; + + { + // Make it look like we're in a DBDirectClient running a nested operation. + DirectClientSetter inDirectClient(opCtx()); + OperationContextSession innerScopedSession(opCtx(), true, boost::none); + + OperationContextSession::get(opCtx())->unstashTransactionResources(opCtx()); + + // The unstash was a noop, so the OperationContext did not get a WriteUnitOfWork. + ASSERT_EQUALS(originalLocker, opCtx()->lockState()); + ASSERT_EQUALS(originalRecoveryUnit, opCtx()->recoveryUnit()); + ASSERT_FALSE(opCtx()->getWriteUnitOfWork()); } } } |