deb-sahara/sahara/tests/unit/service/test_ops.py
Li, Chen e1f5bcf08c Add CLUSTER_STATUS
We should define a set of CLUSTER_STATUS in stead of using direct string
in code.

1. Add cluster.py in utils/
2. Add cluster status.
3. move cluster operation related methods from general.py to cluster.py

Change-Id: Id95d982a911ab5d0f789265e03bff2256cf75856
2015-08-03 09:12:36 +08:00

182 lines
7.3 KiB
Python

# Copyright (c) 2014 Mirantis Inc.
#
# 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 sahara.plugins import base as base_plugins
from sahara.service import ops
from sahara.tests.unit import base
class FakeCluster(object):
id = 'id'
status = "Some_status"
name = "Fake_cluster"
class FakeNodeGroup(object):
id = 'id'
count = 2
instances = [1, 2]
class FakePlugin(mock.Mock):
node_groups = [FakeNodeGroup()]
is_transient = False
def update_infra(self, cluster):
TestOPS.SEQUENCE.append('update_infra')
def configure_cluster(self, cluster):
TestOPS.SEQUENCE.append('configure_cluster')
def start_cluster(self, cluster):
TestOPS.SEQUENCE.append('start_cluster')
def on_terminate_cluster(self, cluster):
TestOPS.SEQUENCE.append('on_terminate_cluster')
def decommission_nodes(self, cluster, instances_to_delete):
TestOPS.SEQUENCE.append('decommission_nodes')
def scale_cluster(self, cluster, node_group_id_map):
TestOPS.SEQUENCE.append('plugin.scale_cluster')
def cluster_destroy(self, ctx, cluster):
TestOPS.SEQUENCE.append('cluster_destroy')
class FakeINFRA(object):
def create_cluster(self, cluster):
TestOPS.SEQUENCE.append('create_cluster')
def scale_cluster(self, cluster, node_group_id_map):
TestOPS.SEQUENCE.append('INFRA.scale_cluster')
return True
def shutdown_cluster(self, cluster):
TestOPS.SEQUENCE.append('shutdown_cluster')
def rollback_cluster(self, cluster, reason):
TestOPS.SEQUENCE.append('rollback_cluster')
class TestOPS(base.SaharaWithDbTestCase):
SEQUENCE = []
@mock.patch('sahara.utils.cluster.change_cluster_status_description',
return_value=FakeCluster())
@mock.patch('sahara.service.ops._update_sahara_info')
@mock.patch('sahara.service.ops._prepare_provisioning',
return_value=(mock.Mock(), mock.Mock(), FakePlugin()))
@mock.patch('sahara.utils.cluster.change_cluster_status')
@mock.patch('sahara.conductor.API.cluster_get')
@mock.patch('sahara.service.ops.CONF')
@mock.patch('sahara.service.trusts.create_trust_for_cluster')
@mock.patch('sahara.conductor.API.job_execution_get_all')
@mock.patch('sahara.service.edp.job_manager.run_job')
def test_provision_cluster(self, p_run_job, p_job_exec, p_create_trust,
p_conf, p_cluster_get, p_change_status,
p_prep_provisioning, p_update_sahara_info,
p_change_cluster_status_desc):
del self.SEQUENCE[:]
ops.INFRA = FakeINFRA()
ops._provision_cluster('123')
# checking that order of calls is right
self.assertEqual(['update_infra', 'create_cluster',
'configure_cluster', 'start_cluster'], self.SEQUENCE,
'Order of calls is wrong')
@mock.patch('sahara.service.ntp_service.configure_ntp')
@mock.patch('sahara.service.ops.CONF')
@mock.patch('sahara.service.ops._prepare_provisioning',
return_value=(mock.Mock(), mock.Mock(), FakePlugin()))
@mock.patch('sahara.utils.cluster.change_cluster_status',
return_value=FakePlugin())
@mock.patch('sahara.utils.cluster.get_instances')
def test_provision_scaled_cluster(self, p_get_instances, p_change_status,
p_prep_provisioning, p_conf, p_ntp):
del self.SEQUENCE[:]
ops.INFRA = FakeINFRA()
p_conf.use_identity_api_v3 = True
ops._provision_scaled_cluster('123', {'id': 1})
# checking that order of calls is right
self.assertEqual(['decommission_nodes', 'INFRA.scale_cluster',
'plugin.scale_cluster'], self.SEQUENCE,
'Order of calls is wrong')
@mock.patch('sahara.service.ops.CONF')
@mock.patch('sahara.service.trusts.delete_trust_from_cluster')
@mock.patch('sahara.context.ctx')
def test_terminate_cluster(self, p_ctx, p_delete_trust, p_conf):
del self.SEQUENCE[:]
base_plugins.PLUGINS = FakePlugin()
base_plugins.PLUGINS.get_plugin.return_value = FakePlugin()
ops.INFRA = FakeINFRA()
ops.conductor = FakePlugin()
ops.terminate_cluster('123')
# checking that order of calls is right
self.assertEqual(['on_terminate_cluster', 'shutdown_cluster',
'cluster_destroy'], self.SEQUENCE,
'Order of calls is wrong')
@mock.patch('sahara.utils.cluster.change_cluster_status_description')
@mock.patch('sahara.service.ops._prepare_provisioning')
@mock.patch('sahara.utils.cluster.change_cluster_status')
@mock.patch('sahara.service.ops._rollback_cluster')
@mock.patch('sahara.conductor.API.cluster_get')
def test_ops_error_hadler_success_rollback(
self, p_cluster_get, p_rollback_cluster, p_change_cluster_status,
p__prepare_provisioning, p_change_cluster_status_desc):
# Test scenario: failed scaling -> success_rollback
fake_cluster = FakeCluster()
p_change_cluster_status_desc.return_value = FakeCluster()
p_rollback_cluster.return_value = True
p_cluster_get.return_value = fake_cluster
p__prepare_provisioning.side_effect = ValueError('error1')
expected = [
mock.call(fake_cluster, 'Active',
'Scaling cluster failed for the following '
'reason(s): error1')
]
ops._provision_scaled_cluster(fake_cluster.id, {'id': 1})
self.assertEqual(expected, p_change_cluster_status.call_args_list)
@mock.patch('sahara.utils.cluster.change_cluster_status_description')
@mock.patch('sahara.service.ops._prepare_provisioning')
@mock.patch('sahara.utils.cluster.change_cluster_status')
@mock.patch('sahara.service.ops._rollback_cluster')
@mock.patch('sahara.conductor.API.cluster_get')
def test_ops_error_hadler_failed_rollback(
self, p_cluster_get, p_rollback_cluster, p_change_cluster_status,
p__prepare_provisioning, p_change_cluster_status_desc):
# Test scenario: failed scaling -> failed_rollback
fake_cluster = FakeCluster()
p_change_cluster_status_desc.return_value = FakeCluster()
p__prepare_provisioning.side_effect = ValueError('error1')
p_rollback_cluster.side_effect = ValueError('error2')
p_cluster_get.return_value = fake_cluster
expected = [
mock.call(
fake_cluster, 'Error', 'Scaling cluster failed for the '
'following reason(s): error1, error2')
]
ops._provision_scaled_cluster(fake_cluster.id, {'id': 1})
self.assertEqual(expected, p_change_cluster_status.call_args_list)