Allow StackLock to be used as a context manager
We initially didn't implement this class as a context manager because it was being used exclusively to lock operations that were happening in an asycnronous thread (hence the thread_lock() context manager). However, we now have some uses for it in the same thread (see Ifa48b179723a2100fff548467db9e162bc669d13), so it makes sense to be able to use the lock object itself as a context manager. Change-Id: Ib90df8f8a149b57b0588d4fc9951f7f035ad7567
This commit is contained in:
parent
62e60c09be
commit
3a204da62d
|
@ -124,6 +124,14 @@ class StackLock(object):
|
|||
"%(stack)s" % {'engine': self.engine_id,
|
||||
'stack': self.stack_id})
|
||||
|
||||
def __enter__(self):
|
||||
self.acquire()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.release()
|
||||
return False
|
||||
|
||||
@contextlib.contextmanager
|
||||
def thread_lock(self, retry=True):
|
||||
"""Acquire a lock and release it only if there is an exception.
|
||||
|
|
|
@ -161,6 +161,32 @@ class StackLockTest(common.HeatTestCase):
|
|||
mock_steal.assert_has_calls(
|
||||
[mock.call(self.stack_id, 'fake-engine-id', self.engine_id)] * 2)
|
||||
|
||||
def test_context_mgr_exception(self):
|
||||
stack_lock_object.StackLock.create = mock.Mock(return_value=None)
|
||||
stack_lock_object.StackLock.release = mock.Mock(return_value=None)
|
||||
slock = stack_lock.StackLock(self.context, self.stack_id,
|
||||
self.engine_id)
|
||||
|
||||
def check_lock():
|
||||
with slock:
|
||||
self.assertEqual(1,
|
||||
stack_lock_object.StackLock.create.call_count)
|
||||
raise self.TestThreadLockException
|
||||
self.assertRaises(self.TestThreadLockException, check_lock)
|
||||
self.assertEqual(1, stack_lock_object.StackLock.release.call_count)
|
||||
|
||||
def test_context_mgr_noexception(self):
|
||||
stack_lock_object.StackLock.create = mock.Mock(return_value=None)
|
||||
stack_lock_object.StackLock.release = mock.Mock(return_value=None)
|
||||
slock = stack_lock.StackLock(self.context, self.stack_id,
|
||||
self.engine_id)
|
||||
|
||||
with slock:
|
||||
self.assertEqual(1,
|
||||
stack_lock_object.StackLock.create.call_count)
|
||||
|
||||
self.assertEqual(1, stack_lock_object.StackLock.release.call_count)
|
||||
|
||||
def test_thread_lock_context_mgr_exception_acquire_success(self):
|
||||
stack_lock_object.StackLock.create = mock.Mock(return_value=None)
|
||||
stack_lock_object.StackLock.release = mock.Mock(return_value=None)
|
||||
|
|
Loading…
Reference in New Issue