Raise exception on failed lock's CM acquire fail

In lock's context manager we are not checking that acquire returns true
before entering managed code.

Even though we don't except acquire to return False, we should still
confirm that the lock has been really acquired and we can proceed, and
raise an exception if it failed.

This patch modified metaclass Lock to raise new exception
LockAcquireFailed if it didn't acquire the lock.

Change-Id: I6d6f14ffd9ea10dd1ca203a92c987334e8a00416
This commit is contained in:
Gorka Eguileor 2015-07-30 12:58:58 +02:00
parent baad206ecb
commit 52c0eed5e6
3 changed files with 29 additions and 1 deletions

View File

@ -436,6 +436,10 @@ class OperationTimedOut(ToozError):
"""Exception raised when an operation times out."""
class LockAcquireFailed(ToozError):
"""Exception raised when a lock acquire fails in a context manager."""
class GroupNotCreated(ToozError):
"""Exception raised when the caller request a group which does
not exist.

View File

@ -19,6 +19,8 @@ import six
import threading
import weakref
from tooz import coordination
@six.add_metaclass(abc.ABCMeta)
class Lock(object):
@ -32,7 +34,12 @@ class Lock(object):
return self._name
def __enter__(self):
self.acquire()
acquired = self.acquire()
if not acquired:
msg = u'Acquiring lock %s failed' % self.name
raise coordination.LockAcquireFailed(msg)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.release()

View File

@ -21,6 +21,7 @@ import uuid
from concurrent import futures
import fixtures
import mock
import testscenarios
from testtools import matchers
from testtools import testcase
@ -682,6 +683,22 @@ class TestAPI(testscenarios.TestWithScenarios,
with lock1:
self.assertFalse(lock2.acquire(blocking=False))
def test_get_lock_context_fails(self):
name = self._get_random_uuid()
lock1 = self._coord.get_lock(name)
lock2 = self._coord.get_lock(name)
with mock.patch.object(lock2, 'acquire', return_value=False):
with lock1:
self.assertRaises(
tooz.coordination.LockAcquireFailed,
lock2.__enter__)
def test_get_lock_context_check_value(self):
name = self._get_random_uuid()
lock = self._coord.get_lock(name)
with lock as returned_lock:
self.assertEqual(lock, returned_lock)
def test_get_lock_locked_twice(self):
name = self._get_random_uuid()
lock = self._coord.get_lock(name)