Refactor add nodes operation in cluster action

This patch refactors the add-nodes operations in cluster action module
to make use of the 'create' method from Action base class.

Change-Id: Ice1bdf35f3111eb20701e017a068113050b42b72
This commit is contained in:
tengqm
2016-02-28 21:58:12 -05:00
parent b0a781475c
commit e0a90e954a
2 changed files with 35 additions and 60 deletions

View File

@@ -364,27 +364,23 @@ class ClusterAction(base.Action):
reason = _('Completed adding nodes.')
child_actions = []
child = []
for node in nodes:
kwargs = {
'name': 'node_join_%s' % node.id[:8],
'cause': base.CAUSE_DERIVED,
'inputs': {'cluster_id': self.target},
'user': self.context.user,
'project': self.context.project,
'domain': self.context.domain,
}
action = base.Action(node.id, 'NODE_JOIN', **kwargs)
action.store(self.context)
child_actions.append(action)
action_id = base.Action.create(self.context, node.id,
consts.NODE_JOIN, **kwargs)
child.append(action_id)
if child_actions:
db_api.dependency_add(self.context, [c.id for c in child_actions],
self.id)
for child in child_actions:
db_api.action_update(self.context, child.id,
{'status': child.READY})
dispatcher.start_action(action_id=child.id)
if child:
db_api.dependency_add(self.context, [c for c in child], self.id)
for cid in child:
db_api.action_update(self.context, cid,
{'status': base.Action.READY})
dispatcher.start_action(action_id=cid)
# Wait for dependent action if any
result, new_reason = self._wait_for_dependents()

View File

@@ -742,12 +742,14 @@ class ClusterActionTest(base.SenlinTestCase):
self.assertEqual('Cannot delete cluster object.', res_msg)
@mock.patch.object(db_api, 'action_update')
@mock.patch.object(base_action.Action, 'create')
@mock.patch.object(node_mod.Node, 'load')
@mock.patch.object(db_api, 'dependency_add')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(ca.ClusterAction, '_wait_for_dependents')
def test_do_add_nodes_single(self, mock_wait, mock_start, mock_dep,
mock_load_node, mock_update, mock_load):
mock_load_node, mock_action, mock_update,
mock_load):
cluster = mock.Mock()
cluster.id = 'CLUSTER_ID'
mock_load.return_value = cluster
@@ -763,11 +765,7 @@ class ClusterActionTest(base.SenlinTestCase):
node.cluster_id = None
node.status = node.ACTIVE
mock_load_node.return_value = node
node_action = mock.Mock()
node_action.id = 'NODE_ACTION_ID'
mock_action = self.patchobject(base_action, 'Action',
return_value=node_action)
mock_action.return_value = 'NODE_ACTION_ID'
mock_wait.return_value = (action.RES_OK, 'Good to go!')
# do it
@@ -780,26 +778,26 @@ class ClusterActionTest(base.SenlinTestCase):
mock_load_node.assert_called_once_with(action.context, 'NODE_1')
mock_action.assert_called_once_with(
'NODE_1', 'NODE_JOIN', user=self.ctx.user,
project=self.ctx.project, domain=self.ctx.domain,
action.context, 'NODE_1', 'NODE_JOIN',
name='node_join_NODE_1', cause='Derived Action',
inputs={'cluster_id': 'CLUSTER_ID'})
node_action.store.assert_called_once_with(action.context)
mock_dep.assert_called_once_with(action.context, ['NODE_ACTION_ID'],
'CLUSTER_ACTION_ID')
mock_update.assert_called_once_with(
action.context, 'NODE_ACTION_ID', {'status': node_action.READY})
action.context, 'NODE_ACTION_ID', {'status': 'READY'})
mock_start.assert_called_once_with(action_id='NODE_ACTION_ID')
mock_wait.assert_called_once_with()
cluster.add_node.assert_called_once_with(node)
@mock.patch.object(db_api, 'action_update')
@mock.patch.object(base_action.Action, 'create')
@mock.patch.object(node_mod.Node, 'load')
@mock.patch.object(db_api, 'dependency_add')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(ca.ClusterAction, '_wait_for_dependents')
def test_do_add_nodes_multiple(self, mock_wait, mock_start, mock_dep,
mock_load_node, mock_update, mock_load):
mock_load_node, mock_action, mock_update,
mock_load):
cluster = mock.Mock()
cluster.id = 'CLUSTER_ID'
mock_load.return_value = cluster
@@ -818,14 +816,7 @@ class ClusterActionTest(base.SenlinTestCase):
node2.cluster_id = None
node2.status = node2.ACTIVE
mock_load_node.side_effect = [node1, node2]
node_action_1 = mock.Mock()
node_action_1.id = 'NODE_ACTION_ID_1'
node_action_2 = mock.Mock()
node_action_2.id = 'NODE_ACTION_ID_2'
mock_action = self.patchobject(
base_action, 'Action', side_effect=[node_action_1, node_action_2])
mock_action.side_effect = ['NODE_ACTION_1', 'NODE_ACTION_2']
mock_wait.return_value = (action.RES_OK, 'Good to go!')
# do it
@@ -840,30 +831,24 @@ class ClusterActionTest(base.SenlinTestCase):
mock.call(action.context, 'NODE_1'),
mock.call(action.context, 'NODE_2')])
mock_action.assert_has_calls([
mock.call('NODE_1', 'NODE_JOIN', user=self.ctx.user,
project=self.ctx.project, domain=self.ctx.domain,
mock.call(action.context, 'NODE_1', 'NODE_JOIN',
name='node_join_NODE_1', cause='Derived Action',
inputs={'cluster_id': 'CLUSTER_ID'}),
mock.call('NODE_2', 'NODE_JOIN', user=self.ctx.user,
project=self.ctx.project, domain=self.ctx.domain,
mock.call(action.context, 'NODE_2', 'NODE_JOIN',
name='node_join_NODE_2', cause='Derived Action',
inputs={'cluster_id': 'CLUSTER_ID'})])
node_action_1.store.assert_called_once_with(action.context)
node_action_2.store.assert_called_once_with(action.context)
mock_dep.assert_called_once_with(
action.context,
['NODE_ACTION_ID_1', 'NODE_ACTION_ID_2'],
['NODE_ACTION_1', 'NODE_ACTION_2'],
'CLUSTER_ACTION_ID')
mock_update.assert_has_calls([
mock.call(action.context, 'NODE_ACTION_ID_1',
{'status': node_action_1.READY}),
mock.call(action.context, 'NODE_ACTION_ID_2',
{'status': node_action_2.READY})
mock.call(action.context, 'NODE_ACTION_1', {'status': 'READY'}),
mock.call(action.context, 'NODE_ACTION_2', {'status': 'READY'})
])
mock_start.assert_has_calls([
mock.call(action_id='NODE_ACTION_ID_1'),
mock.call(action_id='NODE_ACTION_ID_2')])
mock.call(action_id='NODE_ACTION_1'),
mock.call(action_id='NODE_ACTION_2')])
mock_wait.assert_called_once_with()
cluster.add_node.assert_has_calls([
@@ -949,29 +934,23 @@ class ClusterActionTest(base.SenlinTestCase):
self.assertEqual("Node [NODE_1] is not in ACTIVE status.", res_msg)
@mock.patch.object(db_api, 'action_update')
@mock.patch.object(base_action.Action, 'create')
@mock.patch.object(node_mod.Node, 'load')
@mock.patch.object(db_api, 'dependency_add')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(ca.ClusterAction, '_wait_for_dependents')
def test_do_add_nodes_failed_waiting(self, mock_wait, mock_start, mock_dep,
mock_load_node, mock_update,
mock_load):
mock_load_node, mock_action,
mock_update, mock_load):
action = ca.ClusterAction('ID', 'CLUSTER_ACTION', self.ctx)
action.id = 'CLUSTER_ACTION_ID'
action.inputs = {'nodes': ['NODE_1']}
action.data = {}
cluster = mock.Mock()
cluster.id = 'CLUSTER_ID'
node = mock.Mock()
node.id = 'NODE_1'
node.cluster_id = None
node.status = node.ACTIVE
mock_load_node.return_value = node
node_action = mock.Mock()
node_action.id = 'NODE_ACTION_ID'
self.patchobject(base_action, 'Action', return_value=node_action)
mock_load_node.return_value = mock.Mock(id='NODE_1', cluster_id=None,
status='ACTIVE',
ACTIVE='ACTIVE')
mock_action.return_value = 'NODE_ACTION_ID'
mock_wait.return_value = (action.RES_TIMEOUT, 'Timeout!')
# do it
@@ -980,7 +959,7 @@ class ClusterActionTest(base.SenlinTestCase):
# assertions
mock_update.assert_called_once_with(
action.context, 'NODE_ACTION_ID',
{'status': node_action.READY})
{'status': base_action.Action.READY})
self.assertEqual(action.RES_TIMEOUT, res_code)
self.assertEqual('Timeout!', res_msg)
self.assertEqual({}, action.data)