/** * Test a manager that has one cursor running inside of a session. */ TEST_F(CursorManagerTestCustomOpCtx, OneCursorWithASession) { // Add a cursor with a session to the cursor manager. auto lsid = makeLogicalSessionIdForTest(); auto opCtx = _queryServiceContext->makeOperationContext(lsid, boost::none); auto pinned = makeCursor(opCtx.get()); // Retrieve all sessions active in manager - set should contain just lsid. LogicalSessionIdSet lsids; useCursorManager()->appendActiveSessions(&lsids); ASSERT_EQ(lsids.size(), size_t(1)); ASSERT(lsids.find(lsid) != lsids.end()); // Retrieve all cursors for this lsid - should be just ours. auto cursors = useCursorManager()->getCursorsForSession(lsid); ASSERT_EQ(cursors.size(), size_t(1)); auto cursorId = pinned.getCursor()->cursorid(); ASSERT(cursors.find(cursorId) != cursors.end()); // Remove the cursor from the manager. pinned.release(); ASSERT_OK(useCursorManager()->killCursor(opCtx.get(), cursorId, false)); // There should be no more cursor entries by session id. LogicalSessionIdSet sessions; useCursorManager()->appendActiveSessions(&sessions); ASSERT(sessions.empty()); ASSERT(useCursorManager()->getCursorsForSession(lsid).empty()); }
/** * Removes the specified set of session ids from the persistent sessions collection and returns the * number of sessions actually removed. */ int removeSessionsRecords(OperationContext* opCtx, SessionsCollection& sessionsCollection, const LogicalSessionIdSet& sessionIdsToRemove) { if (sessionIdsToRemove.empty()) { return 0; } Locker* locker = opCtx->lockState(); Locker::LockSnapshot snapshot; invariant(locker->saveLockStateAndUnlock(&snapshot)); const auto guard = MakeGuard([&] { UninterruptibleLockGuard noInterrupt(opCtx->lockState()); locker->restoreLockState(opCtx, snapshot); }); // Top-level locks are freed, release any potential low-level (storage engine-specific // locks). If we are yielding, we are at a safe place to do so. opCtx->recoveryUnit()->abandonSnapshot(); // Track the number of yields in CurOp. CurOp::get(opCtx)->yielded(); auto removed = uassertStatusOK(sessionsCollection.findRemovedSessions(opCtx, sessionIdsToRemove)); uassertStatusOK(sessionsCollection.removeTransactionRecords(opCtx, removed)); return removed.size(); }
/** * Test that a manager whose cursors do not have sessions does not return them. */ TEST_F(CursorManagerTestCustomOpCtx, CursorsWithoutSessions) { // Add a cursor with no session to the cursor manager. auto opCtx = _queryServiceContext->makeOperationContext(); auto pinned = makeCursor(opCtx.get()); ASSERT_EQUALS(pinned.getCursor()->getSessionId(), boost::none); // Retrieve all sessions active in manager - set should be empty. LogicalSessionIdSet lsids; useCursorManager()->appendActiveSessions(&lsids); ASSERT(lsids.empty()); }