summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincenzo Riccobene <vincenzox.m.riccobene@intel.com>2015-12-03 17:47:25 +0000
committerAna Cunha <ana.cunha@ericsson.com>2015-12-08 09:04:18 +0000
commit83f97fbb5ec866a055a1e7e158f53ab5f01e5b2c (patch)
treecdeaad04e7116a31395291bca70c2dd5a0e12a8c
parentaab06c7edb6ad11c6630f6a3b820373b7de273e3 (diff)
Adds Heat Manger and tests to ApexLake
Adds to ApexLake a module that manages the connection with OpenStack Heat to trigger instantiation and termination of stacks. Also Moves tests and bin directory in the right place. JIRA: YARDSTICK-35 Change-Id: I0ea407a3129625a238fb4187896c65a2bcd02700 Signed-off-by: Vincenzo Riccobene <vincenzox.m.riccobene@intel.com>
-rwxr-xr-xyardstick/vTC/apexlake/bin/run_tests.sh (renamed from yardstick/vTC/apexlake/experimental_framework/bin/run_tests.sh)0
-rw-r--r--yardstick/vTC/apexlake/experimental_framework/heat_manager.py103
-rw-r--r--yardstick/vTC/apexlake/tests/generates_template_test.py (renamed from yardstick/vTC/apexlake/experimental_framework/tests/generates_template_test.py)0
-rw-r--r--yardstick/vTC/apexlake/tests/heat_manager_test.py208
4 files changed, 311 insertions, 0 deletions
diff --git a/yardstick/vTC/apexlake/experimental_framework/bin/run_tests.sh b/yardstick/vTC/apexlake/bin/run_tests.sh
index 01592ddc7..01592ddc7 100755
--- a/yardstick/vTC/apexlake/experimental_framework/bin/run_tests.sh
+++ b/yardstick/vTC/apexlake/bin/run_tests.sh
diff --git a/yardstick/vTC/apexlake/experimental_framework/heat_manager.py b/yardstick/vTC/apexlake/experimental_framework/heat_manager.py
new file mode 100644
index 000000000..41fc585f7
--- /dev/null
+++ b/yardstick/vTC/apexlake/experimental_framework/heat_manager.py
@@ -0,0 +1,103 @@
+# 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'
+
+
+from keystoneclient.v2_0 import client as keystoneClient
+from heatclient import client as heatClient
+from heatclient.common import template_utils
+
+from experimental_framework import common
+
+
+class HeatManager:
+
+ def __init__(self, credentials):
+ self.ip_controller = credentials['ip_controller']
+ self.heat_url = credentials['heat_url']
+ self.user = credentials['user']
+ self.password = credentials['password']
+ self.auth_uri = credentials['auth_uri']
+ self.project_id = credentials['project']
+ self.heat = None
+
+ # TODO: verify that init_heat is useless in the constructor
+ # self.init_heat()
+
+ def init_heat(self):
+ keystone = keystoneClient.Client(username=self.user,
+ password=self.password,
+ tenant_name=self.project_id,
+ auth_url=self.auth_uri)
+ auth_token = keystone.auth_token
+ self.heat = heatClient.Client('1', endpoint=self.heat_url,
+ token=auth_token)
+
+ def print_stacks(self, name=None):
+ for stack in self.heat.stacks.list():
+ if (name and stack.stack_name == name) or not name:
+ common.LOG.info("Stack Name: " + stack.stack_name)
+ common.LOG.info("Stack Status: " + stack.stack_status)
+
+ def create_stack(self, template_file, stack_name, parameters):
+ self.init_heat()
+ # self.print_stacks()
+ tpl_files, template = \
+ template_utils.get_template_contents(template_file)
+
+ fields = {
+ 'template': template,
+ 'files': dict(list(tpl_files.items()))
+ }
+ self.heat.stacks.create(stack_name=stack_name, files=fields['files'],
+ template=template, parameters=parameters)
+ self.print_stacks(stack_name)
+
+ def is_stack_deployed(self, stack_name):
+ self.init_heat()
+ if stack_name in self.heat.stacks.list():
+ return True
+ return False
+
+ def check_stack_status(self, stack_name):
+ """
+ Returns a string representing the status of a stack from Heat
+ perspective
+ :param stack_name: Name of the stack to be checked (type: str)
+ :return: (type: str)
+ """
+ for stack in self.heat.stacks.list():
+ if stack.stack_name == stack_name:
+ return stack.stack_status
+ return 'NOT_FOUND'
+
+ def validate_heat_template(self, heat_template_file):
+ self.init_heat()
+ if not self.heat.stacks.validate(template=open(heat_template_file,
+ 'r').read()):
+ raise ValueError('The provided heat template "' +
+ heat_template_file +
+ '" is not in the correct format')
+
+ def delete_stack(self, stack_name):
+ self.init_heat()
+ try:
+ for stack in self.heat.stacks.list():
+ if stack.stack_name == stack_name:
+ self.heat.stacks.delete(stack.id)
+ return True
+ except:
+ pass
+ return False
diff --git a/yardstick/vTC/apexlake/experimental_framework/tests/generates_template_test.py b/yardstick/vTC/apexlake/tests/generates_template_test.py
index 85435db6a..85435db6a 100644
--- a/yardstick/vTC/apexlake/experimental_framework/tests/generates_template_test.py
+++ b/yardstick/vTC/apexlake/tests/generates_template_test.py
diff --git a/yardstick/vTC/apexlake/tests/heat_manager_test.py b/yardstick/vTC/apexlake/tests/heat_manager_test.py
new file mode 100644
index 000000000..f89835cc7
--- /dev/null
+++ b/yardstick/vTC/apexlake/tests/heat_manager_test.py
@@ -0,0 +1,208 @@
+# 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__ = 'gpetralx'
+
+
+import unittest
+from experimental_framework import heat_manager
+import mock
+
+
+def get_mock_heat(version, *args, **kwargs):
+ return MockHeat()
+
+
+class MockStacks(object):
+ def __init__(self, stacks):
+ self.stacks = stacks
+
+ def list(self):
+ list_name = list()
+ for stack in self.stacks:
+ list_name.append(stack.stack_name)
+ print list_name
+ return self.stacks
+
+ def validate(self, template=None):
+ return False
+
+ def delete(self, id):
+ for stack in self.stacks:
+ if stack.id == id:
+ return self.stacks.remove(stack)
+
+ def create(self, stack_name=None, files=None, template=None,
+ parameters=None):
+ print stack_name
+ self.stacks.append(MockStack(stack_name))
+
+
+class MockStacks_2(object):
+ def __init__(self, stacks):
+ self.stacks = stacks
+
+ def list(self):
+ raise Exception
+
+
+class MockStack(object):
+ def __init__(self, stack_name):
+ self.name = stack_name
+
+ @property
+ def stack_status(self):
+ return self.stack_name + '_status'
+
+ @property
+ def stack_name(self):
+ return self.name
+
+ @property
+ def id(self):
+ return self.name
+
+ def __eq__(self, other):
+ return self.name == other
+
+
+class MockHeat(object):
+ def __init__(self):
+ stacks = [MockStack('stack_1'), MockStack('stack_2')]
+ self.stacks_list = MockStacks(stacks)
+
+ @property
+ def stacks(self):
+ return self.stacks_list
+
+
+class MockHeat_2(MockHeat):
+ def __init__(self):
+ stacks = [MockStack('stack_1'), MockStack('stack_2')]
+ self.stacks_list = MockStacks_2(stacks)
+
+
+class HeatManagerMock(heat_manager.HeatManager):
+ def init_heat(self):
+ if self.heat is None:
+ self.heat = MockHeat()
+
+
+class HeatManagerMock_2(heat_manager.HeatManager):
+ def init_heat(self):
+ if self.heat is None:
+ self.heat = MockHeat_2()
+
+
+class TestHeatManager(unittest.TestCase):
+
+ def setUp(self):
+ credentials = dict()
+ credentials['ip_controller'] = '1.1.1.1'
+ credentials['heat_url'] = 'http://heat_url'
+ credentials['user'] = 'user'
+ credentials['password'] = 'password'
+ credentials['auth_uri'] = 'auth_uri'
+ credentials['project'] = 'project'
+ self.heat_manager = HeatManagerMock(credentials)
+ self.heat_manager.init_heat()
+
+ def tearDown(self):
+ pass
+
+ def test_is_stack_deployed_for_success(self):
+ self.assertTrue(self.heat_manager.is_stack_deployed('stack_1'))
+ self.assertFalse(self.heat_manager.is_stack_deployed('stack_n'))
+
+ def test_check_status_for_success(self):
+ self.assertEqual('stack_1_status',
+ self.heat_manager.check_stack_status('stack_1'))
+ self.assertEqual('NOT_FOUND',
+ self.heat_manager.check_stack_status('stack_x'))
+
+ def test_validate_template_for_success(self):
+ template_file = \
+ 'tests/data/test_templates/VTC_base_single_vm_wait_1.yaml'
+ with self.assertRaises(ValueError):
+ self.heat_manager.validate_heat_template(template_file)
+
+ def test_delete_stack_for_success(self):
+ self.assertTrue(self.heat_manager.delete_stack('stack_1'))
+ self.assertFalse(self.heat_manager.delete_stack('stack_x'))
+
+ def test_delete_stack_for_success_2(self):
+ self.assertTrue(self.heat_manager.delete_stack('stack_1'))
+
+ @mock.patch('heatclient.common.template_utils.get_template_contents')
+ @mock.patch('heatclient.client.Client')
+ # @mock.patch('heatclient.client.Client', side_effect=DummyHeatClient)
+ def test_create_stack_for_success(self, mock_stack_create,
+ mock_get_template_contents):
+ return_value = ({'template': 'template'}, 'template')
+ mock_get_template_contents.return_value = return_value
+ self.heat_manager.create_stack('template', 'stack_n', 'parameters')
+ self.assertTrue(self.heat_manager.is_stack_deployed('stack_n'))
+
+
+class TestHeatManager_2(unittest.TestCase):
+
+ def setUp(self):
+ credentials = dict()
+ credentials['ip_controller'] = '1.1.1.1'
+ credentials['heat_url'] = 'http://heat_url'
+ credentials['user'] = 'user'
+ credentials['password'] = 'password'
+ credentials['auth_uri'] = 'auth_uri'
+ credentials['project'] = 'project'
+ self.heat_manager = HeatManagerMock_2(credentials)
+
+ def tearDown(self):
+ pass
+
+ def test_delete_stack_for_success_2(self):
+ self.assertFalse(self.heat_manager.delete_stack('stack_1'))
+
+
+class KeystoneMock(object):
+ @property
+ def auth_token(self):
+ return 'token'
+
+
+class TestHeatInit(unittest.TestCase):
+ def setUp(self):
+ credentials = dict()
+ credentials['ip_controller'] = '1.1.1.1'
+ credentials['heat_url'] = 'http://heat_url'
+ credentials['user'] = 'user'
+ credentials['password'] = 'password'
+ credentials['auth_uri'] = 'auth_uri'
+ credentials['project'] = 'project'
+ self.heat_manager = heat_manager.HeatManager(credentials)
+
+ def tearDown(self):
+ pass
+
+ @mock.patch('heatclient.client.Client')
+ @mock.patch('keystoneclient.v2_0.client.Client')
+ def test_heat_init_for_sanity(self, keystone_client, heat_client):
+ keystone_client.return_value = KeystoneMock()
+ heat_client.return_value = MockHeat()
+ self.heat_manager.init_heat()
+ keystone_client.assert_called_once_with(username='user',
+ tenant_name='project',
+ password='password',
+ auth_url='auth_uri')
+ heat_client.assert_called_once_with('1', endpoint='http://heat_url',
+ token='token')