remove 'health_check' param for scaling actions
this patch remove all 'health_check' in scaling actions, we think the user should run cluster_check to check all physical resources' current status. Change-Id: I8e7af7283578d537935bd4c9bcf1e474d0dfc627
This commit is contained in:
parent
a9844dffea
commit
2e2077de55
|
@ -428,7 +428,6 @@ Request Parameters
|
|||
- cluster_id: cluster_id_url
|
||||
- action: action_request
|
||||
- count: scale_count
|
||||
- health_check: health_check
|
||||
|
||||
|
||||
The ``action_name`` in the request body has to be ``scale_in``.
|
||||
|
|
|
@ -740,15 +740,6 @@ events:
|
|||
description: |
|
||||
A list of event objects.
|
||||
|
||||
health_check:
|
||||
type: string
|
||||
in: body
|
||||
required: False
|
||||
description: |
|
||||
A boolean parameter indicates whether check physical resource when
|
||||
scaling.
|
||||
min_version: 1.7
|
||||
|
||||
host:
|
||||
type: string
|
||||
in: body
|
||||
|
|
|
@ -186,13 +186,10 @@ class ClusterController(wsgi.Controller):
|
|||
|
||||
def _do_scale_in(self, req, cid, data):
|
||||
count = data.get('count', None)
|
||||
health = data.get('health_check', None)
|
||||
params = {'identity': cid}
|
||||
|
||||
if count is not None:
|
||||
params['count'] = count
|
||||
if health is not None:
|
||||
params['health_check'] = health
|
||||
|
||||
obj = util.parse_request('ClusterScaleInRequest', req, params)
|
||||
return self.rpc_client.call(req.context, 'cluster_scale_in', obj)
|
||||
|
|
|
@ -801,31 +801,6 @@ class ClusterAction(base.Action):
|
|||
|
||||
return result, reason
|
||||
|
||||
def _check_nodes(self):
|
||||
|
||||
child = []
|
||||
res = self.RES_OK
|
||||
reason = _('Nodes status checking completed.')
|
||||
for node in self.entity.nodes:
|
||||
node_id = node.id
|
||||
action_id = base.Action.create(
|
||||
self.context, node_id, consts.NODE_CHECK,
|
||||
name='node_check_%s' % node_id[:8],
|
||||
cause=consts.CAUSE_DERIVED
|
||||
)
|
||||
child.append(action_id)
|
||||
|
||||
if child:
|
||||
dobj.Dependency.create(self.context, [c for c in child], self.id)
|
||||
for cid in child:
|
||||
ao.Action.update(self.context, cid,
|
||||
{'status': base.Action.READY})
|
||||
dispatcher.start_action()
|
||||
|
||||
res, reason = self._wait_for_dependents()
|
||||
|
||||
return res, reason
|
||||
|
||||
@profiler.trace('ClusterAction.do_scale_in', hide_args=False)
|
||||
def do_scale_in(self):
|
||||
"""Handler for the CLUSTER_SCALE_IN action.
|
||||
|
@ -841,11 +816,9 @@ class ClusterAction(base.Action):
|
|||
candidates = pd.get('candidates', [])
|
||||
# if scaling policy is attached, get 'count' from action data
|
||||
count = len(candidates) or pd['count']
|
||||
health_check = pd.get('health_check', False)
|
||||
else:
|
||||
# If no scaling policy is attached, use the input count directly
|
||||
candidates = []
|
||||
health_check = self.inputs.get('health_check', False)
|
||||
value = self.inputs.get('count', 1)
|
||||
success, count = utils.get_positive_int(value)
|
||||
if not success:
|
||||
|
@ -871,14 +844,6 @@ class ClusterAction(base.Action):
|
|||
_('Cluster scale in started.'),
|
||||
desired_capacity=new_size)
|
||||
|
||||
# check nodes' current status if health_check set to True
|
||||
if health_check is True:
|
||||
# do we need to care about the result
|
||||
result, reason = self._check_nodes()
|
||||
if result == self.RES_OK:
|
||||
nodes = no.Node.get_all_by_cluster(self.context, self.target)
|
||||
self.entity.update_node(nodes)
|
||||
|
||||
# Choose victims randomly
|
||||
if len(candidates) == 0:
|
||||
candidates = scaleutils.nodes_by_random(self.entity.nodes, count)
|
||||
|
|
|
@ -1332,9 +1332,6 @@ class EngineService(service.Service):
|
|||
LOG.info('Scaling in cluster %s', db_cluster.name)
|
||||
inputs = {}
|
||||
|
||||
req.obj_set_defaults()
|
||||
inputs['health_check'] = req.health_check
|
||||
|
||||
params = {
|
||||
'name': 'cluster_scale_in_%s' % db_cluster.id[:8],
|
||||
'cause': consts.CAUSE_RPC,
|
||||
|
|
|
@ -169,13 +169,6 @@ class ClusterReplaceNodesRequest(base.SenlinObject):
|
|||
@base.SenlinObjectRegistry.register
|
||||
class ClusterResizeRequest(base.SenlinObject):
|
||||
|
||||
# VERSION 1.0: initial version
|
||||
# VERSION 1.1: added field 'health_check'
|
||||
VERSION = '1.1'
|
||||
VERSION_MAP = {
|
||||
'1.7': '1.1',
|
||||
}
|
||||
|
||||
fields = {
|
||||
'identity': fields.StringField(),
|
||||
'adjustment_type': fields.AdjustmentTypeField(nullable=True),
|
||||
|
@ -184,67 +177,27 @@ class ClusterResizeRequest(base.SenlinObject):
|
|||
'max_size': fields.CapacityField(nullable=True, minimum=-1),
|
||||
'min_step': fields.NonNegativeIntegerField(nullable=True),
|
||||
'strict': fields.BooleanField(nullable=True, default=True),
|
||||
'health_check': fields.BooleanField(nullable=True, default=False)
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(ClusterResizeRequest, self).obj_make_compatible(
|
||||
primitive, target_version)
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 1):
|
||||
if 'health_check' in primitive['senlin_object.data']:
|
||||
del primitive['senlin_object.data']['health_check']
|
||||
|
||||
|
||||
@base.SenlinObjectRegistry.register
|
||||
class ClusterScaleInRequest(base.SenlinObject):
|
||||
|
||||
# VERSION 1.0: initial version
|
||||
# VERSION 1.1: added field 'health_check'
|
||||
VERSION = '1.1'
|
||||
VERSION_MAP = {
|
||||
'1.7': '1.1',
|
||||
}
|
||||
|
||||
fields = {
|
||||
'identity': fields.StringField(),
|
||||
'count': fields.NonNegativeIntegerField(nullable=True),
|
||||
'health_check': fields.BooleanField(nullable=True, default=False)
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(ClusterScaleInRequest, self).obj_make_compatible(
|
||||
primitive, target_version)
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 1):
|
||||
if 'health_check' in primitive['senlin_object.data']:
|
||||
del primitive['senlin_object.data']['health_check']
|
||||
|
||||
|
||||
@base.SenlinObjectRegistry.register
|
||||
class ClusterScaleOutRequest(base.SenlinObject):
|
||||
|
||||
# VERSION 1.0: initial version
|
||||
# VERSION 1.1: added field 'health_check'
|
||||
VERSION = '1.1'
|
||||
VERSION_MAP = {
|
||||
'1.7': '1.1',
|
||||
}
|
||||
|
||||
fields = {
|
||||
'identity': fields.StringField(),
|
||||
'count': fields.NonNegativeIntegerField(nullable=True),
|
||||
'health_check': fields.BooleanField(nullable=True, default=False)
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(ClusterScaleOutRequest, self).obj_make_compatible(
|
||||
primitive, target_version)
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 1):
|
||||
if 'health_check' in primitive['senlin_object.data']:
|
||||
del primitive['senlin_object.data']['health_check']
|
||||
|
||||
|
||||
@base.SenlinObjectRegistry.register
|
||||
class ClusterAttachPolicyRequest(base.SenlinObject):
|
||||
|
|
|
@ -31,8 +31,7 @@ class TestClusterActionScaleIn(base.BaseSenlinAPITest):
|
|||
def test_cluster_action_scale_in(self):
|
||||
params = {
|
||||
"scale_in": {
|
||||
"count": "1",
|
||||
"health_check": False
|
||||
"count": "1"
|
||||
}
|
||||
}
|
||||
# Trigger cluster action
|
||||
|
@ -67,25 +66,6 @@ class TestClusterScaleInInvalidRequest(base.BaseSenlinAPITest):
|
|||
"The value for count must be an integer: 'bad-count'.",
|
||||
str(message))
|
||||
|
||||
@decorators.idempotent_id('ee7be9d4-7c9b-4054-9ca1-45e5284972ad')
|
||||
def test_cluster_scale_in_invalid_health_check(self):
|
||||
params = {
|
||||
"scale_in": {
|
||||
"health_check": "bad-health"
|
||||
}
|
||||
}
|
||||
|
||||
# Verify badrequest exception(400) is raised.
|
||||
ex = self.assertRaises(exceptions.BadRequest,
|
||||
self.client.trigger_action,
|
||||
'clusters', 'fake', params)
|
||||
|
||||
message = ex.resp_body['error']['message']
|
||||
self.assertEqual(
|
||||
"Unrecognized value 'bad-health', acceptable values are: '0',"
|
||||
" '1', 'f', 'false', 'n', 'no', 'off', 'on', 't', 'true',"
|
||||
" 'y', 'yes'", str(message))
|
||||
|
||||
|
||||
class TestClusterScaleInNegativeBadRequest(base.BaseSenlinAPITest):
|
||||
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from senlin.common import consts
|
||||
from senlin.engine.actions import base as ab
|
||||
from senlin.engine.actions import cluster_action as ca
|
||||
from senlin.engine import cluster as cm
|
||||
from senlin.engine import dispatcher
|
||||
from senlin.objects import action as ao
|
||||
from senlin.objects import dependency as dobj
|
||||
from senlin.tests.unit.common import base
|
||||
from senlin.tests.unit.common import utils
|
||||
|
||||
|
||||
@mock.patch.object(cm.Cluster, 'load')
|
||||
class ClusterCheckNodesTest(base.SenlinTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ClusterCheckNodesTest, self).setUp()
|
||||
self.ctx = utils.dummy_context()
|
||||
|
||||
@mock.patch.object(ao.Action, 'update')
|
||||
@mock.patch.object(ab.Action, 'create')
|
||||
@mock.patch.object(dobj.Dependency, 'create')
|
||||
@mock.patch.object(dispatcher, 'start_action')
|
||||
@mock.patch.object(ca.ClusterAction, '_wait_for_dependents')
|
||||
def test__check_nodes(self, mock_wait, mock_start, mock_dep,
|
||||
mock_action, mock_update, mock_load):
|
||||
node1 = mock.Mock(id='NODE_1')
|
||||
node2 = mock.Mock(id='NODE_2')
|
||||
cluster = mock.Mock(id='FAKE_ID', status='old status',
|
||||
status_reason='old reason')
|
||||
cluster.nodes = [node1, node2]
|
||||
mock_load.return_value = cluster
|
||||
mock_action.side_effect = ['NODE_ACTION_1', 'NODE_ACTION_2']
|
||||
|
||||
action = ca.ClusterAction('FAKE_CLUSTER', 'CLUSTER_CHECK', self.ctx)
|
||||
action.id = 'CLUSTER_ACTION_ID'
|
||||
|
||||
mock_wait.return_value = (action.RES_OK, 'Everything is Okay')
|
||||
|
||||
# do it
|
||||
res_code, res_msg = action._check_nodes()
|
||||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_OK, res_code)
|
||||
self.assertEqual('Everything is Okay', res_msg)
|
||||
|
||||
mock_load.assert_called_once_with(action.context, 'FAKE_CLUSTER')
|
||||
mock_action.assert_has_calls([
|
||||
mock.call(action.context, 'NODE_1', 'NODE_CHECK',
|
||||
name='node_check_NODE_1',
|
||||
cause=consts.CAUSE_DERIVED),
|
||||
mock.call(action.context, 'NODE_2', 'NODE_CHECK',
|
||||
name='node_check_NODE_2',
|
||||
cause=consts.CAUSE_DERIVED)
|
||||
])
|
||||
mock_dep.assert_called_once_with(action.context,
|
||||
['NODE_ACTION_1', 'NODE_ACTION_2'],
|
||||
'CLUSTER_ACTION_ID')
|
||||
mock_update.assert_has_calls([
|
||||
mock.call(action.context, 'NODE_ACTION_1', {'status': 'READY'}),
|
||||
mock.call(action.context, 'NODE_ACTION_2', {'status': 'READY'}),
|
||||
])
|
||||
mock_start.assert_called_once_with()
|
||||
mock_wait.assert_called_once_with()
|
||||
|
||||
def test__check_nodes_empty(self, mock_load):
|
||||
cluster = mock.Mock(id='FAKE_ID', nodes=[], status='old status',
|
||||
status_reason='old reason')
|
||||
mock_load.return_value = cluster
|
||||
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_CHECK', self.ctx)
|
||||
|
||||
# do it
|
||||
res_code, res_msg = action._check_nodes()
|
||||
|
||||
self.assertEqual(action.RES_OK, res_code)
|
||||
self.assertEqual('Nodes status checking completed.', res_msg)
|
||||
|
||||
@mock.patch.object(ao.Action, 'update')
|
||||
@mock.patch.object(ab.Action, 'create')
|
||||
@mock.patch.object(dobj.Dependency, 'create')
|
||||
@mock.patch.object(dispatcher, 'start_action')
|
||||
@mock.patch.object(ca.ClusterAction, '_wait_for_dependents')
|
||||
def test__check_nodes_failed_waiting(self, mock_wait, mock_start,
|
||||
mock_dep, mock_action, mock_update,
|
||||
mock_load):
|
||||
node = mock.Mock(id='NODE_1')
|
||||
cluster = mock.Mock(id='CLUSTER_ID', status='old status',
|
||||
status_reason='old reason')
|
||||
cluster.nodes = [node]
|
||||
mock_load.return_value = cluster
|
||||
mock_action.return_value = 'NODE_ACTION_ID'
|
||||
|
||||
action = ca.ClusterAction('FAKE_CLUSTER', 'CLUSTER_CHECK', self.ctx)
|
||||
action.id = 'CLUSTER_ACTION_ID'
|
||||
|
||||
mock_wait.return_value = (action.RES_TIMEOUT, 'Timeout!')
|
||||
|
||||
res_code, res_msg = action._check_nodes()
|
||||
|
||||
self.assertEqual(action.RES_TIMEOUT, res_code)
|
||||
self.assertEqual('Timeout!', res_msg)
|
||||
|
||||
mock_load.assert_called_once_with(self.ctx, 'FAKE_CLUSTER')
|
||||
mock_action.assert_called_once_with(
|
||||
action.context, 'NODE_1', 'NODE_CHECK',
|
||||
name='node_check_NODE_1',
|
||||
cause=consts.CAUSE_DERIVED,
|
||||
)
|
||||
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': 'READY'})
|
||||
mock_start.assert_called_once_with()
|
||||
mock_wait.assert_called_once_with()
|
|
@ -29,15 +29,14 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
self.ctx = utils.dummy_context()
|
||||
|
||||
@mock.patch.object(scaleutils, 'nodes_by_random')
|
||||
@mock.patch.object(ca.ClusterAction, '_check_nodes')
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
@mock.patch.object(no.Node, 'count_by_cluster')
|
||||
def test_do_scale_in_no_pd_no_count(self, mock_count, mock_delete,
|
||||
mock_check, mock_select, mock_load):
|
||||
mock_select, mock_load):
|
||||
cluster = mock.Mock(id='CID', min_size=1, max_size=-1)
|
||||
mock_load.return_value = cluster
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx,
|
||||
data={}, inputs={'health_check': False})
|
||||
data={}, inputs={})
|
||||
mock_count.return_value = 10
|
||||
mock_delete.return_value = (action.RES_OK, 'Life is beautiful.')
|
||||
|
||||
|
@ -49,7 +48,6 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
self.assertEqual('Cluster scaling succeeded.', res_msg)
|
||||
|
||||
# deleting 1 nodes
|
||||
self.assertFalse(mock_check.called)
|
||||
mock_count.assert_called_once_with(action.context, 'CID')
|
||||
mock_delete.assert_called_once_with(mock.ANY)
|
||||
mock_select.assert_called_once_with(cluster.nodes, 1)
|
||||
|
@ -59,12 +57,11 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
cluster.eval_status.assert_called_once_with(
|
||||
action.context, consts.CLUSTER_SCALE_IN)
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_check_nodes')
|
||||
@mock.patch.object(ca.ClusterAction, '_sleep')
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
@mock.patch.object(no.Node, 'count_by_cluster')
|
||||
def test_do_scale_in_with_pd_no_input(self, mock_count, mock_delete,
|
||||
mock_sleep, mock_check, mock_load):
|
||||
mock_sleep, mock_load):
|
||||
cluster = mock.Mock(id='CID', min_size=1, max_size=-1)
|
||||
mock_load.return_value = cluster
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx)
|
||||
|
@ -73,7 +70,6 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
'count': 2,
|
||||
'grace_period': 2,
|
||||
'candidates': ['NODE_ID_3', 'NODE_ID_4'],
|
||||
'health_check': False
|
||||
}
|
||||
}
|
||||
action.inputs = {}
|
||||
|
@ -93,8 +89,6 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
self.assertEqual(2, len(mock_delete.call_args[0][0]))
|
||||
self.assertIn('NODE_ID_3', mock_delete.call_args[0][0])
|
||||
self.assertIn('NODE_ID_4', mock_delete.call_args[0][0])
|
||||
self.assertFalse(mock_check.called)
|
||||
self.assertFalse(cluster.update_node.called)
|
||||
cluster.set_status.assert_called_once_with(
|
||||
action.context, consts.CS_RESIZING, 'Cluster scale in started.',
|
||||
desired_capacity=3)
|
||||
|
@ -103,16 +97,14 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
mock_sleep.assert_called_once_with(2)
|
||||
|
||||
@mock.patch.object(scaleutils, 'nodes_by_random')
|
||||
@mock.patch.object(ca.ClusterAction, '_check_nodes')
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
@mock.patch.object(no.Node, 'count_by_cluster')
|
||||
def test_do_scale_in_no_pd_with_input(self, mock_count, mock_delete,
|
||||
mock_check, mock_select, mock_load):
|
||||
mock_select, mock_load):
|
||||
cluster = mock.Mock(id='CID', min_size=1, max_size=-1)
|
||||
mock_load.return_value = cluster
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx,
|
||||
data={}, inputs={'count': 3,
|
||||
'health_check': False})
|
||||
data={}, inputs={'count': 3})
|
||||
mock_count.return_value = 11
|
||||
mock_delete.return_value = (action.RES_OK, 'Life is beautiful.')
|
||||
|
||||
|
@ -124,8 +116,6 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
self.assertEqual('Cluster scaling succeeded.', res_msg)
|
||||
|
||||
# deleting 3 nodes
|
||||
self.assertFalse(mock_check.called)
|
||||
self.assertFalse(cluster.update_node.called)
|
||||
mock_count.assert_called_once_with(action.context, 'CID')
|
||||
mock_delete.assert_called_once_with(mock.ANY)
|
||||
mock_select.assert_called_once_with(cluster.nodes, 3)
|
||||
|
@ -135,88 +125,6 @@ class ClusterScaleInTest(base.SenlinTestCase):
|
|||
cluster.eval_status.assert_called_once_with(
|
||||
action.context, consts.CLUSTER_SCALE_IN)
|
||||
|
||||
@mock.patch.object(scaleutils, 'nodes_by_random')
|
||||
@mock.patch.object(ca.ClusterAction, '_check_nodes')
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
@mock.patch.object(no.Node, 'count_by_cluster')
|
||||
@mock.patch.object(no.Node, 'get_all_by_cluster')
|
||||
def test_do_scale_in_health_check(self, mock_get, mock_count, mock_delete,
|
||||
mock_check, mock_select, mock_load):
|
||||
cluster = mock.Mock(id='CID', min_size=1, max_size=-1)
|
||||
mock_load.return_value = cluster
|
||||
node1 = mock.Mock(id='fake1')
|
||||
node2 = mock.Mock(id='fake2')
|
||||
node3 = mock.Mock(id='fake3')
|
||||
cluster.nodes = [node1, node2, node3]
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx,
|
||||
data={}, inputs={'count': 3,
|
||||
'health_check': True})
|
||||
mock_count.return_value = 11
|
||||
mock_delete.return_value = (action.RES_OK, 'Life is beautiful.')
|
||||
mock_check.return_value = (action.RES_OK, 'checking completed.')
|
||||
mock_get.return_value = [node1, node2, node3]
|
||||
|
||||
# do it
|
||||
res_code, res_msg = action.do_scale_in()
|
||||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_OK, res_code)
|
||||
self.assertEqual('Cluster scaling succeeded.', res_msg)
|
||||
|
||||
# deleting 3 nodes
|
||||
mock_get.assert_called_once_with(action.context, 'CID')
|
||||
mock_count.assert_called_once_with(action.context, 'CID')
|
||||
mock_delete.assert_called_once_with(mock.ANY)
|
||||
mock_select.assert_called_once_with(cluster.nodes, 3)
|
||||
mock_check.assert_called_once_with()
|
||||
cluster.update_node.assert_called_once_with([node1, node2, node3])
|
||||
cluster.set_status.assert_called_once_with(
|
||||
action.context, consts.CS_RESIZING, 'Cluster scale in started.',
|
||||
desired_capacity=8)
|
||||
cluster.eval_status.assert_called_once_with(
|
||||
action.context, consts.CLUSTER_SCALE_IN)
|
||||
|
||||
@mock.patch.object(scaleutils, 'nodes_by_random')
|
||||
@mock.patch.object(ca.ClusterAction, '_check_nodes')
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
@mock.patch.object(no.Node, 'count_by_cluster')
|
||||
@mock.patch.object(no.Node, 'get_all_by_cluster')
|
||||
def test_do_scale_in_health_check_failed(self, mock_get, mock_count,
|
||||
mock_delete, mock_check,
|
||||
mock_select, mock_load):
|
||||
cluster = mock.Mock(id='CID', min_size=1, max_size=-1)
|
||||
mock_load.return_value = cluster
|
||||
node1 = mock.Mock(id='fake1')
|
||||
node2 = mock.Mock(id='fake2')
|
||||
node3 = mock.Mock(id='fake3')
|
||||
cluster.nodes = [node1, node2, node3]
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx,
|
||||
data={}, inputs={'count': 3,
|
||||
'health_check': True})
|
||||
mock_count.return_value = 11
|
||||
mock_delete.return_value = (action.RES_OK, 'Life is beautiful.')
|
||||
mock_check.return_value = (action.RES_ERROR, 'boom!')
|
||||
|
||||
# do it
|
||||
res_code, res_msg = action.do_scale_in()
|
||||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_OK, res_code)
|
||||
self.assertEqual('Cluster scaling succeeded.', res_msg)
|
||||
|
||||
# deleting 3 nodes
|
||||
self.assertFalse(mock_get.called)
|
||||
self.assertFalse(cluster.update_node.called)
|
||||
mock_count.assert_called_once_with(action.context, 'CID')
|
||||
mock_delete.assert_called_once_with(mock.ANY)
|
||||
mock_select.assert_called_once_with(cluster.nodes, 3)
|
||||
mock_check.assert_called_once_with()
|
||||
cluster.set_status.assert_called_once_with(
|
||||
action.context, consts.CS_RESIZING, 'Cluster scale in started.',
|
||||
desired_capacity=8)
|
||||
cluster.eval_status.assert_called_once_with(
|
||||
action.context, consts.CLUSTER_SCALE_IN)
|
||||
|
||||
def test_do_scale_in_negative_count(self, mock_load):
|
||||
cluster = mock.Mock(id='CID', min_size=1, max_size=-1)
|
||||
mock_load.return_value = cluster
|
||||
|
|
|
@ -1304,34 +1304,7 @@ class ClusterTest(base.SenlinTestCase):
|
|||
name='cluster_scale_in_12345678',
|
||||
cause=consts.CAUSE_RPC,
|
||||
status=am.Action.READY,
|
||||
inputs={'count': 2, 'health_check': False},
|
||||
)
|
||||
notify.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(dispatcher, 'start_action')
|
||||
@mock.patch.object(am.Action, 'create')
|
||||
@mock.patch.object(su, 'check_size_params')
|
||||
@mock.patch.object(co.Cluster, 'find')
|
||||
def test_cluster_scale_in_full(self, mock_find, mock_check,
|
||||
mock_action, notify):
|
||||
x_cluster = mock.Mock(id='12345678ABCD', desired_capacity=4)
|
||||
mock_find.return_value = x_cluster
|
||||
mock_check.return_value = None
|
||||
mock_action.return_value = 'ACTION_ID'
|
||||
req = orco.ClusterScaleInRequest(
|
||||
identity='CLUSTER', count=2, health_check=True)
|
||||
|
||||
result = self.eng.cluster_scale_in(self.ctx, req.obj_to_primitive())
|
||||
|
||||
self.assertEqual({'action': 'ACTION_ID'}, result)
|
||||
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
|
||||
mock_check.assert_called_once_with(x_cluster, 2)
|
||||
mock_action.assert_called_once_with(
|
||||
self.ctx, '12345678ABCD', consts.CLUSTER_SCALE_IN,
|
||||
name='cluster_scale_in_12345678',
|
||||
cause=consts.CAUSE_RPC,
|
||||
status=am.Action.READY,
|
||||
inputs={'count': 2, 'health_check': True},
|
||||
inputs={'count': 2},
|
||||
)
|
||||
notify.assert_called_once_with()
|
||||
|
||||
|
@ -1368,7 +1341,7 @@ class ClusterTest(base.SenlinTestCase):
|
|||
name='cluster_scale_in_FOO',
|
||||
cause=consts.CAUSE_RPC,
|
||||
status=am.Action.READY,
|
||||
inputs={'health_check': False},
|
||||
inputs={},
|
||||
)
|
||||
notify.assert_called_once_with()
|
||||
|
||||
|
|
|
@ -333,7 +333,6 @@ class TestClusterResize(test_base.SenlinTestCase):
|
|||
self.assertFalse(sot.obj_attr_is_set('max_size'))
|
||||
self.assertFalse(sot.obj_attr_is_set('min_step'))
|
||||
self.assertFalse(sot.obj_attr_is_set('strict'))
|
||||
self.assertFalse(sot.obj_attr_is_set('health_check'))
|
||||
|
||||
def test_init_with_params(self):
|
||||
sot = clusters.ClusterResizeRequest(identity='foo',
|
||||
|
@ -352,9 +351,6 @@ class TestClusterResize(test_base.SenlinTestCase):
|
|||
self.assertEqual(1, sot.min_step)
|
||||
self.assertFalse(sot.strict)
|
||||
|
||||
sot.obj_set_defaults()
|
||||
self.assertFalse(sot.health_check)
|
||||
|
||||
def test_init_failed_type(self):
|
||||
ex = self.assertRaises(ValueError,
|
||||
clusters.ClusterResizeRequest,
|
||||
|
@ -398,15 +394,6 @@ class TestClusterResize(test_base.SenlinTestCase):
|
|||
identity='foo', strict='fake')
|
||||
self.assertIn("Unrecognized value 'fake'", six.text_type(ex))
|
||||
|
||||
def test_init_invalid_boolean(self):
|
||||
ex = self.assertRaises(ValueError,
|
||||
clusters.ClusterResizeRequest,
|
||||
identity='foo', health_check="foo")
|
||||
self.assertEqual(
|
||||
"Unrecognized value 'foo', acceptable values are: '0', '1', "
|
||||
"'f', 'false', 'n', 'no', 'off', 'on', 't', 'true', 'y', 'yes'",
|
||||
six.text_type(ex))
|
||||
|
||||
|
||||
class TestClusterScaleIn(test_base.SenlinTestCase):
|
||||
|
||||
|
@ -416,9 +403,6 @@ class TestClusterScaleIn(test_base.SenlinTestCase):
|
|||
self.assertEqual('foo', sot.identity)
|
||||
self.assertEqual(5, sot.count)
|
||||
|
||||
sot.obj_set_defaults()
|
||||
self.assertFalse(sot.health_check)
|
||||
|
||||
def test_init_failed(self):
|
||||
ex = self.assertRaises(ValueError,
|
||||
clusters.ClusterScaleInRequest,
|
||||
|
@ -426,15 +410,6 @@ class TestClusterScaleIn(test_base.SenlinTestCase):
|
|||
self.assertEqual("Value must be >= 0 for field 'count'.",
|
||||
six.text_type(ex))
|
||||
|
||||
def test_init_invalid_boolean(self):
|
||||
ex = self.assertRaises(ValueError,
|
||||
clusters.ClusterScaleInRequest,
|
||||
identity='foo', count=1, health_check="foo")
|
||||
self.assertEqual(
|
||||
"Unrecognized value 'foo', acceptable values are: '0', '1', "
|
||||
"'f', 'false', 'n', 'no', 'off', 'on', 't', 'true', 'y', 'yes'",
|
||||
six.text_type(ex))
|
||||
|
||||
|
||||
class TestClusterScaleOut(test_base.SenlinTestCase):
|
||||
|
||||
|
@ -444,9 +419,6 @@ class TestClusterScaleOut(test_base.SenlinTestCase):
|
|||
self.assertEqual('foo', sot.identity)
|
||||
self.assertEqual(5, sot.count)
|
||||
|
||||
sot.obj_set_defaults()
|
||||
self.assertFalse(sot.health_check)
|
||||
|
||||
def test_init_failed(self):
|
||||
ex = self.assertRaises(ValueError,
|
||||
clusters.ClusterScaleOutRequest,
|
||||
|
@ -454,15 +426,6 @@ class TestClusterScaleOut(test_base.SenlinTestCase):
|
|||
self.assertEqual("Value must be >= 0 for field 'count'.",
|
||||
six.text_type(ex))
|
||||
|
||||
def test_init_invalid_boolean(self):
|
||||
ex = self.assertRaises(ValueError,
|
||||
clusters.ClusterScaleOutRequest,
|
||||
identity='foo', count=1, health_check="foo")
|
||||
self.assertEqual(
|
||||
"Unrecognized value 'foo', acceptable values are: '0', '1', "
|
||||
"'f', 'false', 'n', 'no', 'off', 'on', 't', 'true', 'y', 'yes'",
|
||||
six.text_type(ex))
|
||||
|
||||
|
||||
class TestClusterAttachPolicy(test_base.SenlinTestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue