Add TaskManager tests and fix decorator.
Fix the require_exclusive_lock decorator so it works on both functions and class methods. Add unit tests for TaskManager and require_exclusive_lock(). Change-Id: I5b86b365cce1ceb2d4926634ebcb0b412740c37d
This commit is contained in:
parent
db1568b729
commit
8df05652d8
@ -82,8 +82,8 @@ def require_exclusive_lock(f):
|
||||
|
||||
"""
|
||||
def wrapper(*args, **kwargs):
|
||||
tracker = args[0]
|
||||
if tracker.shared:
|
||||
task = args[0] if isinstance(args[0], TaskManager) else args[1]
|
||||
if task.shared:
|
||||
raise exception.ExclusiveLockRequired()
|
||||
return f(*args, **kwargs)
|
||||
return wrapper
|
||||
|
@ -16,14 +16,34 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Test class for Ironic TaskManagers."""
|
||||
"""Tests for :class:`ironic.manager.task_manager`."""
|
||||
|
||||
from testtools import matchers
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.db import api as dbapi
|
||||
#from ironic.drivers import fake as fake_driver
|
||||
#from ironic.manager import task_manager
|
||||
#from ironic.manager import resource_manager
|
||||
from ironic.manager import task_manager
|
||||
from ironic.openstack.common import uuidutils
|
||||
from ironic.tests.db import base
|
||||
from ironic.tests.db import utils
|
||||
from ironic.tests.manager import utils as mgr_utils
|
||||
|
||||
|
||||
def create_fake_node(i):
|
||||
dbh = dbapi.get_instance()
|
||||
node = utils.get_test_node(id=i,
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
control_driver='fake',
|
||||
deploy_driver='fake')
|
||||
dbh.create_node(node)
|
||||
return node['uuid']
|
||||
|
||||
|
||||
def ContainsUUIDs(uuids):
|
||||
def _task_uuids(task):
|
||||
return [r.node.uuid for r in task.resources]
|
||||
return matchers.AfterPreprocessing(_task_uuids,
|
||||
matchers.Equals(uuids))
|
||||
|
||||
|
||||
class TaskManagerTestCase(base.DbTestCase):
|
||||
@ -31,8 +51,111 @@ class TaskManagerTestCase(base.DbTestCase):
|
||||
def setUp(self):
|
||||
super(TaskManagerTestCase, self).setUp()
|
||||
self.dbapi = dbapi.get_instance()
|
||||
(self.controller, self.deployer) = mgr_utils.get_mocked_node_manager()
|
||||
|
||||
def _init(self):
|
||||
self.node = utils.get_test_node(control_driver='fake',
|
||||
deploy_driver='fake')
|
||||
self.dbapi.create_node(self.node)
|
||||
self.uuids = [create_fake_node(i) for i in xrange(1, 6)]
|
||||
self.uuids.sort()
|
||||
|
||||
def test_get_one_node(self):
|
||||
uuids = [self.uuids[0]]
|
||||
|
||||
self.config(host='test-host')
|
||||
|
||||
with task_manager.acquire(uuids) as task:
|
||||
node = task.resources[0].node
|
||||
self.assertEqual(uuids[0], node.uuid)
|
||||
self.assertEqual('test-host', node.reservation)
|
||||
|
||||
def test_get_many_nodes(self):
|
||||
uuids = self.uuids[1:3]
|
||||
|
||||
self.config(host='test-host')
|
||||
|
||||
with task_manager.acquire(uuids) as task:
|
||||
self.assertThat(task, ContainsUUIDs(uuids))
|
||||
for node in [r.node for r in task.resources]:
|
||||
self.assertEqual('test-host', node.reservation)
|
||||
|
||||
def test_get_nodes_nested(self):
|
||||
uuids = self.uuids[0:2]
|
||||
more_uuids = self.uuids[3:4]
|
||||
|
||||
with task_manager.acquire(uuids) as task:
|
||||
self.assertThat(task, ContainsUUIDs(uuids))
|
||||
with task_manager.acquire(more_uuids) as another_task:
|
||||
self.assertThat(another_task, ContainsUUIDs(more_uuids))
|
||||
|
||||
def test_get_locked_node(self):
|
||||
uuids = self.uuids[0:2]
|
||||
|
||||
def _lock_again(u):
|
||||
with task_manager.acquire(u):
|
||||
raise exception.IronicException("Acquired lock twice.")
|
||||
|
||||
with task_manager.acquire(uuids) as task:
|
||||
self.assertThat(task, ContainsUUIDs(uuids))
|
||||
self.assertRaises(exception.NodeLocked,
|
||||
_lock_again,
|
||||
uuids)
|
||||
|
||||
def test_get_shared_lock(self):
|
||||
uuids = self.uuids[0:2]
|
||||
|
||||
# confirm we can elevate from shared -> exclusive
|
||||
with task_manager.acquire(uuids, shared=True) as task:
|
||||
self.assertThat(task, ContainsUUIDs(uuids))
|
||||
with task_manager.acquire(uuids, shared=False) as inner_task:
|
||||
self.assertThat(inner_task, ContainsUUIDs(uuids))
|
||||
|
||||
# confirm someone else can still get a shared lock
|
||||
with task_manager.acquire(uuids, shared=False) as task:
|
||||
self.assertThat(task, ContainsUUIDs(uuids))
|
||||
with task_manager.acquire(uuids, shared=True) as inner_task:
|
||||
self.assertThat(inner_task, ContainsUUIDs(uuids))
|
||||
|
||||
|
||||
class ExclusiveLockDecoratorTestCase(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ExclusiveLockDecoratorTestCase, self).setUp()
|
||||
self.dbapi = dbapi.get_instance()
|
||||
(self.controller, self.deployer) = mgr_utils.get_mocked_node_manager()
|
||||
self.uuids = [create_fake_node(123)]
|
||||
|
||||
def test_require_exclusive_lock(self):
|
||||
@task_manager.require_exclusive_lock
|
||||
def do_state_change(task):
|
||||
for r in task.resources:
|
||||
task.dbapi.update_node(r.node.uuid,
|
||||
{'task_state': 'test-state'})
|
||||
|
||||
with task_manager.acquire(self.uuids, shared=True) as task:
|
||||
self.assertRaises(exception.ExclusiveLockRequired,
|
||||
do_state_change,
|
||||
task)
|
||||
|
||||
with task_manager.acquire(self.uuids, shared=False) as task:
|
||||
do_state_change(task)
|
||||
|
||||
for uuid in self.uuids:
|
||||
res = self.dbapi.get_node(uuid)
|
||||
self.assertEqual('test-state', res.task_state)
|
||||
|
||||
@task_manager.require_exclusive_lock
|
||||
def _do_state_change(self, task):
|
||||
for r in task.resources:
|
||||
task.dbapi.update_node(r.node.uuid,
|
||||
{'task_state': 'test-state'})
|
||||
|
||||
def test_require_exclusive_lock_on_object(self):
|
||||
with task_manager.acquire(self.uuids, shared=True) as task:
|
||||
self.assertRaises(exception.ExclusiveLockRequired,
|
||||
self._do_state_change,
|
||||
task)
|
||||
|
||||
with task_manager.acquire(self.uuids, shared=False) as task:
|
||||
self._do_state_change(task)
|
||||
|
||||
for uuid in self.uuids:
|
||||
res = self.dbapi.get_node(uuid)
|
||||
self.assertEqual('test-state', res.task_state)
|
||||
|
Loading…
Reference in New Issue
Block a user