summaryrefslogtreecommitdiff
path: root/src/mongo/db/session_catalog_test.cpp
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2018-03-15 19:55:35 -0400
committerSpencer T Brody <spencer@mongodb.com>2018-03-20 17:15:09 -0400
commitcf6745a9523bb030dbceaea3bfbf26e553306762 (patch)
treecd4c464aa30d1f1abd00c30600340e3ac1b152b8 /src/mongo/db/session_catalog_test.cpp
parent6622688c3a1be6555dc9279850a6d1c0cbfa3a7d (diff)
downloadmongo-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.cpp96
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());
}
}
}