TEST(LockManagerTest, TxError) { LockManager lm; LockManager::LockStatus status; Transaction tx(1); // release a lock on a resource we haven't locked lm.acquire(&tx, kShared, 2); status = lm.release(&tx, kShared, 1); // this is in error ASSERT(LockManager::kLockResourceNotFound == status); status = lm.release(&tx, kShared, 2); ASSERT(LockManager::kLockReleased == status); // release a record we've locked in a different mode lm.acquire(&tx, kShared, 1); status = lm.release(&tx, kExclusive, 1); // this is in error ASSERT(LockManager::kLockModeNotFound == status); status = lm.release(&tx, kShared, 1); ASSERT(LockManager::kLockReleased == status); lm.acquire(&tx, kExclusive, 1); status = lm.release(&tx, kShared, 1); // this is in error ASSERT(LockManager::kLockModeNotFound == status); status = lm.release(&tx, kExclusive, 1); ASSERT(LockManager::kLockReleased == status); // attempt to acquire on a transaction that aborted try { lm.abort(&tx); } catch (const LockManager::AbortException& err) { } try { lm.acquire(&tx, kShared, 1); // error ASSERT(false); } catch (const LockManager::AbortException& error) { } }
TEST(LockManagerTest, SingleTx) { LockManager lm; Transaction t1(1); ResourceId r1 = 1; LockManager::LockStatus status; // acquire a shared record lock ASSERT(! lm.isLocked(&t1, kShared, r1)); lm.acquire(&t1, kShared, r1); ASSERT(lm.isLocked(&t1, kShared, r1)); // release a shared record lock lm.release(&t1, kShared, r1); ASSERT(! lm.isLocked(&t1, kShared, r1)); // acquire a shared record lock twice, on same ResourceId lm.acquire(&t1, kShared, r1); lm.acquire(&t1, kShared, r1); ASSERT(lm.isLocked(&t1, kShared, r1)); // release the twice-acquired lock, once. Still locked status = lm.release(&t1, kShared, r1); ASSERT(LockManager::kLockCountDecremented == status); ASSERT(lm.isLocked(&t1, kShared, r1)); // after 2nd release, it's not locked status = lm.release(&t1, kShared, r1); ASSERT(LockManager::kLockReleased == status); ASSERT(!lm.isLocked(&t1, kShared, r1)); // --- test downgrade and release --- // acquire an exclusive then a shared lock, on the same ResourceId lm.acquire(&t1, kExclusive, r1); ASSERT(lm.isLocked(&t1, kExclusive, r1)); lm.acquire(&t1, kShared, r1); ASSERT(lm.isLocked(&t1, kExclusive, r1)); ASSERT(lm.isLocked(&t1, kShared, r1)); // release shared first, then exclusive lm.release(&t1, kShared, r1); ASSERT(! lm.isLocked(&t1, kShared, r1)); ASSERT(lm.isLocked(&t1, kExclusive, r1)); lm.release(&t1, kExclusive, r1); ASSERT(! lm.isLocked(&t1, kExclusive, r1)); // release exclusive first, then shared lm.acquire(&t1, kExclusive, r1); lm.acquire(&t1, kShared, r1); lm.release(&t1, kExclusive, r1); ASSERT(! lm.isLocked(&t1, kExclusive, r1)); ASSERT(lm.isLocked(&t1, kShared, r1)); lm.release(&t1, kShared, r1); ASSERT(! lm.isLocked(&t1, kShared, r1)); // --- test upgrade and release --- // acquire a shared, then an exclusive lock on the same ResourceId lm.acquire(&t1, kShared, r1); ASSERT(lm.isLocked(&t1, kShared, r1)); lm.acquire(&t1, kExclusive, r1); ASSERT(lm.isLocked(&t1, kShared, r1)); ASSERT(lm.isLocked(&t1, kExclusive, r1)); // release exclusive first, then shared lm.release(&t1, kExclusive, r1); ASSERT(! lm.isLocked(&t1, kExclusive, r1)); ASSERT(lm.isLocked(&t1, kShared, r1)); lm.release(&t1, kShared, r1); ASSERT(! lm.isLocked(&t1, kShared, r1)); // release shared first, then exclusive lm.acquire(&t1, kShared, r1); lm.acquire(&t1, kExclusive, r1); lm.release(&t1, kShared, r1); ASSERT(! lm.isLocked(&t1, kShared, r1)); ASSERT(lm.isLocked(&t1, kExclusive, r1)); lm.release(&t1, kExclusive, r1); ASSERT(! lm.isLocked(&t1, kExclusive, r1)); }