def testRequestForTypeOfLockAlreadyHeld(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # First session gets a lock on user 'bob' locks = {'user':['bob']} lockserver.do_acquire_locks(sess[0], locks) # First session then tries to get another user lock, which it shouldn't be # allowed to do while it already holds a user lock. locks = {'user':['alice']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Second session gets a lock on node '123'. locks = {'node':['123']} lockserver.do_acquire_locks(sess[1], locks) # Second session then tries to get another node lock, which it shouldn't be # allowed to do while it already holds a node lock. locks = {'node':['123']} func = lockserver.do_acquire_locks args = (sess[1], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testRequestForTypeOfLockAlreadyHeld(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # First session gets a lock on user 'bob' locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[0], locks) # First session then tries to get another user lock, which it shouldn't be # allowed to do while it already holds a user lock. locks = {'user': ['alice']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Second session gets a lock on node '123'. locks = {'node': ['123']} lockserver.do_acquire_locks(sess[1], locks) # Second session then tries to get another node lock, which it shouldn't be # allowed to do while it already holds a node lock. locks = {'node': ['123']} func = lockserver.do_acquire_locks args = (sess[1], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testEndSessionFailsWhenSessionNotEmpty(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # Have the first session acquire a lock. locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[0], locks) # Make sure we can't end the session while the session holds locks. func = lockserver.do_end_session args = (sess[0], ) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Have the second session be queued for the same lock. locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[1], locks) # Make sure we can't end the session while the session has pending # lock acquisition requests. func = lockserver.do_end_session args = (sess[0], ) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testStartSessionCreatesUniqueIds(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) self.assertNotEqual(sess[0], sess[1]) self.assertNotEqual(sess[1], sess[2])
def testLockdictWithMultipleLockTypes(self): sess = [] sess.append(lockserver.do_start_session()) # It is not allowed to make a single request for multiple types of locks. locks = {'user':['bob'], 'node':['123']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testLockdictWithMultipleLockTypes(self): sess = [] sess.append(lockserver.do_start_session()) # It is not allowed to make a single request for multiple types of locks. locks = {'user': ['bob'], 'node': ['123']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testEndSessionFailsWhenSessionNotEmpty(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # Have the first session acquire a lock. locks = {'user':['bob']} lockserver.do_acquire_locks(sess[0], locks) # Make sure we can't end the session while the session holds locks. func = lockserver.do_end_session args = (sess[0],) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Have the second session be queued for the same lock. locks = {'user':['bob']} lockserver.do_acquire_locks(sess[1], locks) # Make sure we can't end the session while the session has pending # lock acquisition requests. func = lockserver.do_end_session args = (sess[0],) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testRequestForUserLockWhileHoldingNodeLock(self): sess = [] sess.append(lockserver.do_start_session()) # First session gets a lock on node '123' locks = {'node':['123']} lockserver.do_acquire_locks(sess[0], locks) # First session then tries to get a user lock, which it shouldn't be # allowed to do while it already holds a node lock. locks = {'user':['bob']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testRequestForUserLockWhileHoldingNodeLock(self): sess = [] sess.append(lockserver.do_start_session()) # First session gets a lock on node '123' locks = {'node': ['123']} lockserver.do_acquire_locks(sess[0], locks) # First session then tries to get a user lock, which it shouldn't be # allowed to do while it already holds a node lock. locks = {'user': ['bob']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args)
def testStartSessionCreatesNonemptyStringsForIds(self): sess = [] sess.append(lockserver.do_start_session()) self.assertNotEqual(sess[0], '') self.assertTrue(isinstance(sess[0], str))
def testUserAndNodeLockContention_one(self): # Start three sessions. sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # First session requests lock on the user 'bob'. locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[0], locks) # First session requests locks on the nodes '123' and '456'. locks = {'node': ['123', '456']} lockserver.do_acquire_locks(sess[0], locks) # Second session requests lock on the node '123'. locks = {'node': ['123']} lockserver.do_acquire_locks(sess[1], locks) # Third session requests lock on the user 'bob'. locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[2], locks) expected_heldlockdict = { 'user': { 'bob': { 'locked_by_session': sess[0], 'queue': [sess[2]] } }, 'node': { '123': { 'locked_by_session': sess[0], 'queue': [sess[1]] }, '456': { 'locked_by_session': sess[0], 'queue': [] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': ['bob'], 'node': ['123', '456'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123'] }, 'acquirelocksproceedeventset': False }, sess[2]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': ['bob'], 'node': [] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # First session releases user lock on 'bob'. # Note: they still hold the node locks on '123' and '456' locks = {'user': ['bob']} lockserver.do_release_locks(sess[0], locks) expected_heldlockdict = { 'user': { 'bob': { 'locked_by_session': sess[2], 'queue': [] } }, 'node': { '123': { 'locked_by_session': sess[0], 'queue': [sess[1]] }, '456': { 'locked_by_session': sess[0], 'queue': [] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': [], 'node': ['123', '456'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123'] }, 'acquirelocksproceedeventset': False }, sess[2]: { 'heldlocks': { 'user': ['bob'], 'node': [] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # First session releases node lock on '123'. # Note: they still hold the node lock on '456' locks = {'node': ['123']} lockserver.do_release_locks(sess[0], locks) expected_heldlockdict = { 'user': { 'bob': { 'locked_by_session': sess[2], 'queue': [] } }, 'node': { '123': { 'locked_by_session': sess[1], 'queue': [] }, '456': { 'locked_by_session': sess[0], 'queue': [] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': [], 'node': ['456'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'user': [], 'node': ['123'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'user': ['bob'], 'node': [] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # First session releases node lock on '456' and then requests locks on # user 'bob' and nodes '123' and '456' again. It can't request the node # locks, however, until it gets the node lock (in xmlrpc usage, the # user lock request would have blocked). So, we have the session that is # holding the lock on user 'bob' release that lock before the first session # makes the node lock requests. locks = {'node': ['456']} lockserver.do_release_locks(sess[0], locks) locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[0], locks) locks = {'user': ['bob']} lockserver.do_release_locks(sess[2], locks) locks = {'node': ['123', '456']} lockserver.do_acquire_locks(sess[0], locks) expected_heldlockdict = { 'user': { 'bob': { 'locked_by_session': sess[0], 'queue': [] } }, 'node': { '123': { 'locked_by_session': sess[1], 'queue': [sess[0]] }, '456': { 'locked_by_session': sess[0], 'queue': [] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': ['bob'], 'node': ['456'] }, 'neededlocks': { 'user': [], 'node': ['123'] }, 'acquirelocksproceedeventset': False }, sess[1]: { 'heldlocks': { 'user': [], 'node': ['123'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testEndSession(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) expected_heldlockdict = {'node': {}, 'user': {}} expected_sessiondict = { sess[0]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # End the first session. lockserver.do_end_session(sess[0]) expected_heldlockdict = {'node': {}, 'user': {}} expected_sessiondict = { sess[1]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # Make sure we aren't allowed to use the session we just ended in a lock request. locks = {'user': ['bob']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Make sure we aren't allowed to end the same session again. func = lockserver.do_end_session args = (sess[0], ) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Make sure the sessions we didn't end still work (the second session # will acquire the lock, the third session will be queued for it). locks = {'user': ['bob']} lockserver.do_acquire_locks(sess[1], locks) lockserver.do_acquire_locks(sess[2], locks) expected_heldlockdict = { 'node': {}, 'user': { 'bob': { 'locked_by_session': sess[1], 'queue': [sess[2]] } } } expected_sessiondict = { sess[1]: { 'heldlocks': { 'node': [], 'user': ['bob'] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': ['bob'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testContentionForMultipleNodeLocks(self): """ This is the same as testContentionForMultipleUserLocks but involves contention over a multiple node locks rather than over multiple user locks. Both could have been done with much less code using a helper method, but that makes the dictionaries of expected data much less intuitive to look at and thus makes the tests hard to understand. So, just duplicating code, instead. """ # This entire test will use this same lockdict in each request locks = {'node':['123', '456', '789']} # Start three sessions. sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # Have all three session try to acquire a lock on a single user. lockserver.do_acquire_locks(sess[0], locks) lockserver.do_acquire_locks(sess[1], locks) lockserver.do_acquire_locks(sess[2], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'user': {}, 'node': {'123': {'locked_by_session': sess[0], 'queue': [sess[1], sess[2]]}, '456': {'locked_by_session': sess[0], 'queue': [sess[1], sess[2]]}, '789': {'locked_by_session': sess[0], 'queue': [sess[1], sess[2]]}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': [], 'node': ['123', '456', '789']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123', '456', '789']}, 'acquirelocksproceedeventset': False}, sess[2]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123', '456', '789']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # Have the session that holds the lock release it. lockserver.do_release_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'user': {}, 'node': {'123': {'locked_by_session': sess[1], 'queue': [sess[2]]}, '456': {'locked_by_session': sess[1], 'queue': [sess[2]]}, '789': {'locked_by_session': sess[1], 'queue': [sess[2]]}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'user': [], 'node': ['123', '456', '789']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123', '456', '789']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # The session that just released it tries to acquire it again. lockserver.do_acquire_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'user': {}, 'node': {'123': {'locked_by_session': sess[1], 'queue': [sess[2], sess[0]]}, '456': {'locked_by_session': sess[1], 'queue': [sess[2], sess[0]]}, '789': {'locked_by_session': sess[1], 'queue': [sess[2], sess[0]]}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123', '456', '789']}, 'acquirelocksproceedeventset': False}, sess[1]: {'heldlocks': {'user': [], 'node': ['123', '456', '789']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123', '456', '789']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testContentionForMultipleUserLocks(self): # This entire test will use this same lockdict in each request locks = {'user':['bob', 'alice', 'joe']} # Start three sessions. sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # Have all three session try to acquire a lock on a single user. lockserver.do_acquire_locks(sess[0], locks) lockserver.do_acquire_locks(sess[1], locks) lockserver.do_acquire_locks(sess[2], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'node': {}, 'user': {'bob': {'locked_by_session': sess[0], 'queue': [sess[1], sess[2]]}, 'alice': {'locked_by_session': sess[0], 'queue': [sess[1], sess[2]]}, 'joe': {'locked_by_session': sess[0], 'queue': [sess[1], sess[2]]}}} expected_sessiondict = { sess[0]: {'heldlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'acquirelocksproceedeventset': False}, sess[2]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # Have the session that holds the lock release it. lockserver.do_release_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'node': {}, 'user': {'bob': {'locked_by_session': sess[1], 'queue': [sess[2]]}, 'alice': {'locked_by_session': sess[1], 'queue': [sess[2]]}, 'joe': {'locked_by_session': sess[1], 'queue': [sess[2]]}}} expected_sessiondict = { sess[0]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # The session that just released it tries to acquire it again. lockserver.do_acquire_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'node': {}, 'user': {'bob': {'locked_by_session': sess[1], 'queue': [sess[2], sess[0]]}, 'alice': {'locked_by_session': sess[1], 'queue': [sess[2], sess[0]]}, 'joe': {'locked_by_session': sess[1], 'queue': [sess[2], sess[0]]}}} expected_sessiondict = { sess[0]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'acquirelocksproceedeventset': False}, sess[1]: {'heldlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': ['bob', 'alice', 'joe']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testContentionForMultipleUserLocks(self): # This entire test will use this same lockdict in each request locks = {'user': ['bob', 'alice', 'joe']} # Start three sessions. sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # Have all three session try to acquire a lock on a single user. lockserver.do_acquire_locks(sess[0], locks) lockserver.do_acquire_locks(sess[1], locks) lockserver.do_acquire_locks(sess[2], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'node': {}, 'user': { 'bob': { 'locked_by_session': sess[0], 'queue': [sess[1], sess[2]] }, 'alice': { 'locked_by_session': sess[0], 'queue': [sess[1], sess[2]] }, 'joe': { 'locked_by_session': sess[0], 'queue': [sess[1], sess[2]] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'acquirelocksproceedeventset': False }, sess[2]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # Have the session that holds the lock release it. lockserver.do_release_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'node': {}, 'user': { 'bob': { 'locked_by_session': sess[1], 'queue': [sess[2]] }, 'alice': { 'locked_by_session': sess[1], 'queue': [sess[2]] }, 'joe': { 'locked_by_session': sess[1], 'queue': [sess[2]] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # The session that just released it tries to acquire it again. lockserver.do_acquire_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'node': {}, 'user': { 'bob': { 'locked_by_session': sess[1], 'queue': [sess[2], sess[0]] }, 'alice': { 'locked_by_session': sess[1], 'queue': [sess[2], sess[0]] }, 'joe': { 'locked_by_session': sess[1], 'queue': [sess[2], sess[0]] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'acquirelocksproceedeventset': False }, sess[1]: { 'heldlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'neededlocks': { 'node': [], 'user': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'node': [], 'user': [] }, 'neededlocks': { 'node': [], 'user': ['bob', 'alice', 'joe'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testEndSession(self): sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) expected_heldlockdict = { 'node': {}, 'user': {}} expected_sessiondict = { sess[0]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # End the first session. lockserver.do_end_session(sess[0]) expected_heldlockdict = { 'node': {}, 'user': {}} expected_sessiondict = { sess[1]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # Make sure we aren't allowed to use the session we just ended in a lock request. locks = {'user':['bob']} func = lockserver.do_acquire_locks args = (sess[0], locks) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Make sure we aren't allowed to end the same session again. func = lockserver.do_end_session args = (sess[0],) self.assertRaises(lockserver.LockserverInvalidRequestError, func, *args) # Make sure the sessions we didn't end still work (the second session # will acquire the lock, the third session will be queued for it). locks = {'user':['bob']} lockserver.do_acquire_locks(sess[1], locks) lockserver.do_acquire_locks(sess[2], locks) expected_heldlockdict = { 'node': {}, 'user': {'bob': {'locked_by_session': sess[1], 'queue': [sess[2]]}}} expected_sessiondict = { sess[1]: {'heldlocks': {'node': [], 'user': ['bob']}, 'neededlocks': {'node': [], 'user': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'node': [], 'user': []}, 'neededlocks': {'node': [], 'user': ['bob']}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testContentionForMultipleNodeLocks(self): """ This is the same as testContentionForMultipleUserLocks but involves contention over a multiple node locks rather than over multiple user locks. Both could have been done with much less code using a helper method, but that makes the dictionaries of expected data much less intuitive to look at and thus makes the tests hard to understand. So, just duplicating code, instead. """ # This entire test will use this same lockdict in each request locks = {'node': ['123', '456', '789']} # Start three sessions. sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # Have all three session try to acquire a lock on a single user. lockserver.do_acquire_locks(sess[0], locks) lockserver.do_acquire_locks(sess[1], locks) lockserver.do_acquire_locks(sess[2], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'user': {}, 'node': { '123': { 'locked_by_session': sess[0], 'queue': [sess[1], sess[2]] }, '456': { 'locked_by_session': sess[0], 'queue': [sess[1], sess[2]] }, '789': { 'locked_by_session': sess[0], 'queue': [sess[1], sess[2]] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'acquirelocksproceedeventset': False }, sess[2]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # Have the session that holds the lock release it. lockserver.do_release_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'user': {}, 'node': { '123': { 'locked_by_session': sess[1], 'queue': [sess[2]] }, '456': { 'locked_by_session': sess[1], 'queue': [sess[2]] }, '789': { 'locked_by_session': sess[1], 'queue': [sess[2]] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[1]: { 'heldlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # The session that just released it tries to acquire it again. lockserver.do_acquire_locks(sess[0], locks) # The first session should have the lock and the other two sessions should # be queued in order for that lock. expected_heldlockdict = { 'user': {}, 'node': { '123': { 'locked_by_session': sess[1], 'queue': [sess[2], sess[0]] }, '456': { 'locked_by_session': sess[1], 'queue': [sess[2], sess[0]] }, '789': { 'locked_by_session': sess[1], 'queue': [sess[2], sess[0]] } } } expected_sessiondict = { sess[0]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'acquirelocksproceedeventset': False }, sess[1]: { 'heldlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'neededlocks': { 'user': [], 'node': [] }, 'acquirelocksproceedeventset': True }, sess[2]: { 'heldlocks': { 'user': [], 'node': [] }, 'neededlocks': { 'user': [], 'node': ['123', '456', '789'] }, 'acquirelocksproceedeventset': False } } status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])
def testUserAndNodeLockContention_one(self): # Start three sessions. sess = [] sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) sess.append(lockserver.do_start_session()) # First session requests lock on the user 'bob'. locks = {'user':['bob']} lockserver.do_acquire_locks(sess[0], locks) # First session requests locks on the nodes '123' and '456'. locks = {'node':['123','456']} lockserver.do_acquire_locks(sess[0], locks) # Second session requests lock on the node '123'. locks = {'node':['123']} lockserver.do_acquire_locks(sess[1], locks) # Third session requests lock on the user 'bob'. locks = {'user':['bob']} lockserver.do_acquire_locks(sess[2], locks) expected_heldlockdict = { 'user': {'bob': {'locked_by_session': sess[0], 'queue': [sess[2]]}}, 'node': {'123': {'locked_by_session': sess[0], 'queue': [sess[1]]}, '456': {'locked_by_session': sess[0], 'queue': []}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': ['bob'], 'node': ['123','456']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123']}, 'acquirelocksproceedeventset': False}, sess[2]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': ['bob'], 'node': []}, 'acquirelocksproceedeventset': False}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # First session releases user lock on 'bob'. # Note: they still hold the node locks on '123' and '456' locks = {'user':['bob']} lockserver.do_release_locks(sess[0], locks) expected_heldlockdict = { 'user': {'bob': {'locked_by_session': sess[2], 'queue': []}}, 'node': {'123': {'locked_by_session': sess[0], 'queue': [sess[1]]}, '456': {'locked_by_session': sess[0], 'queue': []}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': [], 'node': ['123','456']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': ['123']}, 'acquirelocksproceedeventset': False}, sess[2]: {'heldlocks': {'user': ['bob'], 'node': []}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # First session releases node lock on '123'. # Note: they still hold the node lock on '456' locks = {'node':['123']} lockserver.do_release_locks(sess[0], locks) expected_heldlockdict = { 'user': {'bob': {'locked_by_session': sess[2], 'queue': []}}, 'node': {'123': {'locked_by_session': sess[1], 'queue': []}, '456': {'locked_by_session': sess[0], 'queue': []}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': [], 'node': ['456']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[1]: {'heldlocks': {'user': [], 'node': ['123']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'user': ['bob'], 'node': []}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"]) # First session releases node lock on '456' and then requests locks on # user 'bob' and nodes '123' and '456' again. It can't request the node # locks, however, until it gets the node lock (in xmlrpc usage, the # user lock request would have blocked). So, we have the session that is # holding the lock on user 'bob' release that lock before the first session # makes the node lock requests. locks = {'node':['456']} lockserver.do_release_locks(sess[0], locks) locks = {'user':['bob']} lockserver.do_acquire_locks(sess[0], locks) locks = {'user':['bob']} lockserver.do_release_locks(sess[2], locks) locks = {'node':['123', '456']} lockserver.do_acquire_locks(sess[0], locks) expected_heldlockdict = { 'user': {'bob': {'locked_by_session': sess[0], 'queue': []}}, 'node': {'123': {'locked_by_session': sess[1], 'queue': [sess[0]]}, '456': {'locked_by_session': sess[0], 'queue': []}}} expected_sessiondict = { sess[0]: {'heldlocks': {'user': ['bob'], 'node': ['456']}, 'neededlocks': {'user': [], 'node': ['123']}, 'acquirelocksproceedeventset': False}, sess[1]: {'heldlocks': {'user': [], 'node': ['123']}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}, sess[2]: {'heldlocks': {'user': [], 'node': []}, 'neededlocks': {'user': [], 'node': []}, 'acquirelocksproceedeventset': True}} status = lockserver.do_get_status() self.assertEqual(expected_heldlockdict, status["heldlockdict"]) self.assertEqual(expected_sessiondict, status["sessiondict"])