diff options
author | Vincenzo Riccobene <vincenzox.m.riccobene@intel.com> | 2015-12-23 13:26:15 +0000 |
---|---|---|
committer | Jörgen Karlsson <jorgen.w.karlsson@ericsson.com> | 2015-12-23 14:17:25 +0000 |
commit | dd7873b8bec5c3853aa0021eb452d1d6f3be0dc5 (patch) | |
tree | 0c4d03c0a25105f425a535625857ea91032188f8 | |
parent | fa490948dd370b69e821784e12f67299c7fb0f26 (diff) |
Add Deployment Unit to ApexLake
Includes the deployment unit module used for deployment by Apexlake
Also includes tests
JIRA: YARDSTICK-35
Change-Id: Ia5c89f3cd03d53b1fc4e418215955fd91aff9d03
Signed-off-by: Vincenzo Riccobene <vincenzox.m.riccobene@intel.com>
-rw-r--r-- | yardstick/vTC/apexlake/experimental_framework/deployment_unit.py | 119 | ||||
-rw-r--r-- | yardstick/vTC/apexlake/tests/deployment_unit_test.py | 272 |
2 files changed, 391 insertions, 0 deletions
diff --git a/yardstick/vTC/apexlake/experimental_framework/deployment_unit.py b/yardstick/vTC/apexlake/experimental_framework/deployment_unit.py new file mode 100644 index 000000000..186258f7d --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/deployment_unit.py @@ -0,0 +1,119 @@ +# Copyright (c) 2015 Intel Research and Development Ireland Ltd. +# +# 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 os +import time + +from experimental_framework import heat_manager +from experimental_framework import common + +MAX_RETRY = 3 + + +class DeploymentUnit: + """ + This unit is in charge to manage the deployment of the workloads under + test and any other workloads necessary to + the benchmark + """ + + def __init__(self, openstack_credentials): + self.heat_manager = heat_manager.HeatManager(openstack_credentials) + self.deployed_stacks = list() + + def destroy_heat_template(self, stack_name): + """ + Destroys a stack + :param stack_name: Stack of the name to be destroyed (sting) + :return: None + """ + try: + if self.heat_manager.check_stack_status(stack_name): + if stack_name in self.deployed_stacks: + self.deployed_stacks.remove(stack_name) + self.heat_manager.delete_stack(stack_name) + + status = self.heat_manager.check_stack_status(stack_name) + while status and 'DELETE_IN_PROGRESS' in status: + common.LOG.info(status) + time.sleep(5) + status = self.heat_manager.check_stack_status(stack_name) + return True + except: + return False + + def destroy_all_deployed_stacks(self): + """ + Destroys all the stacks currently deployed + :return: None + """ + for stack in self.deployed_stacks: + if self.heat_manager.is_stack_deployed(stack): + self.destroy_heat_template(stack) + + def deploy_heat_template(self, template_file, stack_name, parameters, + attempt=0): + """ + Deploys a heat template and in case of failure retries 3 times + :param template_file: full path file name of the heat template + :param stack_name: name of the stack to deploy + :param parameters: parameters to be given to the heat template + :param attempt: number of current attempt + :return: returns True in case the creation is completed + returns False in case the creation is failed + """ + if not os.path.isfile(template_file): + raise ValueError('The specified file does not exist ("' + + template_file + '")') + self.heat_manager.validate_heat_template(template_file) + try: + self.heat_manager.create_stack(template_file, stack_name, + parameters) + deployed = True + except: + deployed = False + + if not deployed and 'COMPLETE' in \ + self.heat_manager.check_stack_status(stack_name): + try: + self.destroy_heat_template(stack_name) + except: + pass + + status = self.heat_manager.check_stack_status(stack_name) + while status and 'CREATE_IN_PROGRESS' in status: + time.sleep(5) + status = self.heat_manager.check_stack_status(stack_name) + if status and ('FAILED' in status or 'NOT_FOUND' in status): + if attempt < MAX_RETRY: + attempt += 1 + try: + self.destroy_heat_template(stack_name) + except Exception as e: + common.LOG.debug(e.message) + pass + return self.deploy_heat_template(template_file, stack_name, + parameters, attempt) + else: + try: + self.destroy_heat_template(stack_name) + except Exception as e: + common.LOG.debug(e.message) + finally: + return False + if self.heat_manager.check_stack_status(stack_name) and \ + 'COMPLETE' in self.heat_manager.\ + check_stack_status(stack_name): + self.deployed_stacks.append(stack_name) + return True diff --git a/yardstick/vTC/apexlake/tests/deployment_unit_test.py b/yardstick/vTC/apexlake/tests/deployment_unit_test.py new file mode 100644 index 000000000..4c701024e --- /dev/null +++ b/yardstick/vTC/apexlake/tests/deployment_unit_test.py @@ -0,0 +1,272 @@ +# Copyright (c) 2015 Intel Research and Development Ireland Ltd. +# +# 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. + +__author__ = 'vmriccox' + + +import unittest +import mock +import experimental_framework.deployment_unit as mut + + +class DummyHeatManager: + + def __init__(self, param): + self.counts = 0 + pass + + def validate_heat_template(self, template_file): + return True + + def check_stack_status(self, stack_name): + # return 'CREATE_COMPLETE' + self.counts += 1 + if self.counts >= 3: + return 'CREATE_COMPLETE' + else: + return 'CREATE_IN_PROGRESS' + + def delete_stack(self, stack_name): + pass + + +class DummyHeatManagerFailed(DummyHeatManager): + + def check_stack_status(self, stack_name): + return 'CREATE_FAILED' + + def create_stack(self, template_file, stack_name, parameters): + pass + + +class DummyHeatManagerComplete(DummyHeatManager): + + def check_stack_status(self, stack_name): + return 'CREATE_COMPLETE' + + def create_stack(self, template_file, stack_name, parameters): + raise Exception() + + +class DummyHeatManagerFailedException(DummyHeatManagerFailed): + + def create_stack(self, template_file, stack_name, parameters): + raise Exception + + def check_stack_status(self, stack_name): + return '' + + +class DummyHeatManagerDestroy: + + def __init__(self, credentials): + self.delete_stack_counter = 0 + self.check_stack_status_counter = 0 + + def check_stack_status(self, stack_name): + if self.check_stack_status_counter < 2: + self.check_stack_status_counter += 1 + return 'DELETE_IN_PROGRESS' + else: + return 'DELETE_COMPLETE' + + def create_stack(self, template_file, stack_name, parameters): + pass + + def delete_stack(self, stack_name=None): + if stack_name == 'stack': + self.delete_stack_counter += 1 + else: + return self.delete_stack_counter + + def is_stack_deployed(self, stack_name): + return True + + +class DummyHeatManagerDestroyException(DummyHeatManagerDestroy): + + def delete_stack(self, stack_name=None): + raise Exception + + +class DummyHeatManagerReiteration: + + def __init__(self, param): + self.counts = 0 + + def validate_heat_template(self, template_file): + return True + + def check_stack_status(self, stack_name): + return 'CREATE_FAILED' + + def delete_stack(self, stack_name): + pass + + def create_stack(self, template_file=None, stack_name=None, + parameters=None): + if template_file == 'template_reiteration' and \ + stack_name == 'stack_reiteration' and \ + parameters == 'parameters_reiteration': + self.counts += 1 + + +class DummyDeploymentUnit(mut.DeploymentUnit): + + def destroy_heat_template(self, stack_name): + raise Exception + + +class TestDeploymentUnit(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManager) + def test_constructor_for_sanity(self, mock_heat_manager): + du = mut.DeploymentUnit(dict()) + self.assertTrue(isinstance(du.heat_manager, DummyHeatManager)) + mock_heat_manager.assert_called_once_with(dict()) + self.assertEqual(du.deployed_stacks, list()) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManager) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_failure(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = False + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + self.assertRaises(ValueError, du.deploy_heat_template, template_file, + stack_name, parameters, 0) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManager) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_success(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, True) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerComplete) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_2_for_success(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, True) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerComplete) + @mock.patch('os.path.isfile') + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit', + side_effect=DummyDeploymentUnit) + def test_deploy_heat_template_3_for_success(self, mock_dep_unit, + mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, True) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerFailed) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_success_2(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = DummyDeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, False) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerDestroy) + @mock.patch('experimental_framework.common.LOG') + def test_destroy_heat_template_for_success(self, mock_log, + mock_heat_manager): + openstack_credentials = dict() + du = mut.DeploymentUnit(openstack_credentials) + du.deployed_stacks = ['stack'] + stack_name = 'stack' + self.assertTrue(du.destroy_heat_template(stack_name)) + self.assertEqual(du.heat_manager.delete_stack(None), 1) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerDestroyException) + @mock.patch('experimental_framework.common.LOG') + def test_destroy_heat_template_for_success_2(self, mock_log, + mock_heat_manager): + openstack_credentials = dict() + du = mut.DeploymentUnit(openstack_credentials) + du.deployed_stacks = ['stack'] + stack_name = 'stack' + self.assertFalse(du.destroy_heat_template(stack_name)) + + def test_destroy_all_deployed_stacks_for_success(self): + du = DeploymentUnitDestroy() + du.destroy_all_deployed_stacks() + self.assertTrue(du.destroy_heat_template()) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerReiteration) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_success_3(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template = 'template_reiteration' + stack = 'stack_reiteration' + parameters = 'parameters_reiteration' + output = du.deploy_heat_template(template, stack, parameters, 0) + self.assertFalse(output) + self.assertEqual(du.heat_manager.counts, 4) + + +class DeploymentUnitDestroy(mut.DeploymentUnit): + + def __init__(self): + self.deployed_stacks = ['stack'] + self.heat_manager = DummyHeatManagerDestroy(dict()) + self.destroy_all_deployed_stacks_called_correctly = False + + def destroy_heat_template(self, template_name=None): + if template_name == 'stack': + self.destroy_all_deployed_stacks_called_correctly = True + return self.destroy_all_deployed_stacks_called_correctly |