From a9469dec6b423092dc8137ca1d7213345ffc3a3c Mon Sep 17 00:00:00 2001 From: Marina Koushnir Date: Wed, 6 Jul 2016 10:06:59 +0000 Subject: [PATCH] add tempest tests for template list/validate/show api's Change-Id: Ib89b3bed9e407d514f75aa806d8ad45ac492025f --- .../tests/api/templates/__init__.py | 15 ++ .../tests/api/templates/base.py | 163 ++++++++++++++++++ .../tests/api/templates/test_template.py | 129 ++++++++++++++ .../templates/api/corrupted_template.yaml | 27 +++ .../api/host_aodh_alarm_for_rca.yaml | 2 +- .../api/nagios_alarm_for_alarms.yaml | 2 +- 6 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 vitrage_tempest_tests/tests/api/templates/__init__.py create mode 100644 vitrage_tempest_tests/tests/api/templates/base.py create mode 100644 vitrage_tempest_tests/tests/api/templates/test_template.py create mode 100644 vitrage_tempest_tests/tests/resources/templates/api/corrupted_template.yaml diff --git a/vitrage_tempest_tests/tests/api/templates/__init__.py b/vitrage_tempest_tests/tests/api/templates/__init__.py new file mode 100644 index 000000000..dd32b852f --- /dev/null +++ b/vitrage_tempest_tests/tests/api/templates/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2016 - Nokia +# +# 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__ = 'stack' diff --git a/vitrage_tempest_tests/tests/api/templates/base.py b/vitrage_tempest_tests/tests/api/templates/base.py new file mode 100644 index 000000000..cb157a65b --- /dev/null +++ b/vitrage_tempest_tests/tests/api/templates/base.py @@ -0,0 +1,163 @@ +# Copyright 2016 Nokia +# +# 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 json + +from oslo_log import log as logging + +from vitrage import clients +from vitrage_tempest_tests.tests.api.base import BaseApiTest +import vitrage_tempest_tests.tests.utils as utils + +LOG = logging.getLogger(__name__) + + +class BaseTemplateTest(BaseApiTest): + """Template test class for Vitrage API tests.""" + + DEFAULT_PATH = '/etc/vitrage/templates/' + TEST_PATH = '/opt/stack/vitrage/vitrage_tempest_tests/' \ + + 'tests/resources/templates/api/' + + NON_EXIST_FILE = 'non_exist_file.yaml' + ERROR_FILE = 'corrupted_template.yaml' + OK_FILE = 'nagios_alarm_for_alarms.yaml' + + ERROR_STATUS = 'validation failed' + OK_STATUS = 'validation OK' + OK_MSG = 'Template validation is OK' + + @classmethod + def setUpClass(cls): + super(BaseTemplateTest, cls).setUpClass() + cls.ceilometer_client = clients.ceilometer_client(cls.conf) + + def _compare_template_lists(self, api_templates, cli_templates): + self.assertNotEqual(len(api_templates), 0, + 'The template list taken from api is empty') + self.assertIsNotNone(cli_templates, + 'The template list taken from cli is empty') + + LOG.debug("The template list taken from cli is : %s", cli_templates) + LOG.debug("The template list taken by api is : %s", + json.dumps(api_templates)) + + self._validate_templates_list_length(api_templates, cli_templates) + self._validate_passed_templates_length(api_templates, cli_templates) + self._compare_each_template_in_list(api_templates, cli_templates) + self._validate_templates_existence_in_default_folder(api_templates) + + def _compare_template_validations(self, api_templates, cli_templates): + self.assertNotEqual(len(api_templates), 0, + 'The template validations taken from api is empty') + self.assertIsNotNone( + cli_templates, 'The template validations taken from cli is empty') + + LOG.debug("The template validations taken from cli is : %s", + cli_templates) + LOG.debug("The template validations taken by api is : %s", + json.dumps(api_templates)) + + parsed_topology = json.loads(cli_templates) + sorted_cli_templates = sorted(parsed_topology.items()) + sorted_api_templates = sorted(api_templates.items()) + self.assertEqual(sorted_api_templates, sorted_cli_templates) + + def _validate_templates_list_length(self, api_templates, cli_templates): + self.assertEqual(len(cli_templates.splitlines()), + len(api_templates) + 4) + + def _validate_passed_templates_length(self, api_templates, cli_templates): + api_passes_templates = self._filter_list_by_pairs_parameters( + api_templates, ['status details'], [self.OK_MSG]) + cli_passes_templates = cli_templates.count(' ' + self.OK_MSG + ' ') + self.assertEqual(cli_passes_templates, len(api_passes_templates)) + + def _compare_each_template_in_list(self, api_templates, cli_templates): + counter = 0 + for api_item in api_templates: + for line in cli_templates.splitlines(): + name_start = line.count(' ' + api_item['name'] + ' ') + status_start = line.count(' ' + api_item['status'] + ' ') + if name_start > 0 and status_start > 0: + counter += 1 + break + self.assertEqual(counter, len(api_templates)) + + def _validate_templates_existence_in_default_folder(self, templates_list): + counter = 0 + text_out = utils.get_from_terminal('ls ' + self.DEFAULT_PATH) + for item in templates_list: + name_start = text_out.count(' ' + item['name'] + ' ') + if name_start > -1: + counter += 1 + self.assertEqual(counter, len(templates_list)) + + def _run_default_template_validation( + self, template, validation, path): + self.assertNotEqual(len(validation), 0, + 'The template validation is empty') + self.assertEqual(validation['file path'], path) + self.assertEqual(validation['status code'], 0) + self.assertEqual(validation['status'], self.OK_STATUS) + self.assertEqual(validation['message'], self.OK_MSG) + self.assertEqual(validation['message'], template['status details']) + + def _run_template_validation( + self, validation, path, negative=False): + self.assertIn(path, validation['file path']) + + if negative: + self.assertEqual(validation['status code'], 3) + self.assertEqual(validation['status'], self.ERROR_STATUS) + self.assertNotEqual(validation['message'], self.OK_MSG) + return + + self.assertEqual(validation['status code'], 0) + self.assertEqual(validation['status'], self.OK_STATUS) + self.assertEqual(validation['message'], self.OK_MSG) + + def _compare_template_show(self, api_templates, cli_templates): + self.assertNotEqual(len(api_templates), 0, + 'The template validations taken from api is empty') + self.assertIsNotNone( + cli_templates, 'The template validations taken from cli is empty') + + LOG.debug("The template validations taken from cli is : %s", + cli_templates) + LOG.debug("The template validations taken by api is : %s", + json.dumps(api_templates)) + + parsed_topology = json.loads(cli_templates) + sorted_cli_templates = sorted(parsed_topology.items()) + sorted_api_templates = sorted(api_templates.items()) + self.assertEqual(sorted_api_templates, sorted_cli_templates) + + def _validate_template_structure(self, template_item, template_show): + self.assertEqual( + template_item['name'], template_show['metadata']['name']) + template_content = utils.get_from_terminal( + 'cat ' + self.DEFAULT_PATH + template_item['name'] + '*') + + entities = template_content.count('entity:') + relationships = template_content.count('relationship:') + scenarios = template_content.count('scenario:') + + self.assertIn( + template_show['metadata']['name'], template_content) + self.assertEqual( + len(template_show['definitions']['entities']), entities) + self.assertEqual( + len(template_show['definitions']['relationships']), relationships) + self.assertEqual( + len(template_show['scenarios']), scenarios) diff --git a/vitrage_tempest_tests/tests/api/templates/test_template.py b/vitrage_tempest_tests/tests/api/templates/test_template.py new file mode 100644 index 000000000..f5a6d1456 --- /dev/null +++ b/vitrage_tempest_tests/tests/api/templates/test_template.py @@ -0,0 +1,129 @@ +# Copyright 2016 - Nokia +# +# 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. + +from oslo_log import log as logging + +from vitrage_tempest_tests.tests.api.templates.base import BaseTemplateTest +import vitrage_tempest_tests.tests.utils as utils + +LOG = logging.getLogger(__name__) + + +class TestValidate(BaseTemplateTest): + """Template test class for Vitrage API tests.""" + + @classmethod + def setUpClass(cls): + super(TestValidate, cls).setUpClass() + + def test_templates_list(self): + """template_list test + + There test validate correctness of template list, + compare templates files existence with default folder + and between cli via api ... + """ + api_template_list = self.vitrage_client.template.list() + cli_template_list = utils.run_vitrage_command( + 'vitrage template list', self.conf) + + self._compare_template_lists(api_template_list, cli_template_list) + + def test_compare_templates_validation(self): + """template_validate test + + There test validate correctness of template validation, + compare templates files validation between cli via api + """ + path = self.DEFAULT_PATH + api_template_validation = \ + self.vitrage_client.template.validate(path=path) + cli_template_validation = utils.run_vitrage_command( + 'vitrage template validate --path ' + path, self.conf) + + self._compare_template_validations( + api_template_validation, cli_template_validation) + + def test_templates_validate_default_templates(self): + """templates_validate test + + There test validate correctness of list of uploaded template files + (in /etc/vitrage/templates folder) + """ + path = self.DEFAULT_PATH + validation = self.vitrage_client.template.validate(path=path) + self.assertNotEqual(len(validation), 0) + for item in validation['results']: + self._run_template_validation(item, path) + + def test_templates_validate_non_exist_template(self): + """templates_validate test + + There negative test - validate error message + in case of non-exist template file + """ + try: + path = self.TEST_PATH + self.NON_EXIST_FILE + validation = self.vitrage_client.template.validate(path=path) + self.assertIsNone(validation) + except Exception as up: + self.assertEqual(up.strerror, 'No such file or directory') + self.assertEqual(up.errno, 2) + + def test_templates_validate_corrupted_templates(self): + """templates_validate test + + There negative test - validate correctness of error + message in case of corrupted template file + """ + try: + path = self.TEST_PATH + self.ERROR_FILE + validation = self.vitrage_client.template.validate(path=path) + self.assertEqual(len(validation['results']), 1) + self._run_template_validation( + validation['results'][0], path, negative=True) + except Exception: + LOG.error('Failed to get validation of corrupted template file') + + def test_templates_validate_correct_template(self): + """templates_validate test + + There test validate correctness of template file + """ + try: + path = self.TEST_PATH + self.OK_FILE + validation = self.vitrage_client.template.validate(path=path) + self.assertEqual(len(validation['results']), 1) + self._run_template_validation( + validation['results'][0], path) + except Exception: + LOG.error('Failed to get validation of template file') + + def test_compare_template_show(self): + """templates_show test + + There test validate correctness of uploaded template files + one by one with full details + (in /etc/vitrage/templates folder) + """ + template_list = self.vitrage_client.template.list() + self.assertNotEqual(len(template_list), 0) + for item in template_list: + api_template_show = self.vitrage_client.template.show(item['uuid']) + cli_template_show = utils.run_vitrage_command( + 'vitrage template show ' + item['uuid'], self.conf) + + self._compare_template_show( + api_template_show, cli_template_show) + self._validate_template_structure(item, api_template_show) diff --git a/vitrage_tempest_tests/tests/resources/templates/api/corrupted_template.yaml b/vitrage_tempest_tests/tests/resources/templates/api/corrupted_template.yaml new file mode 100644 index 000000000..c5d06eff1 --- /dev/null +++ b/vitrage_tempest_tests/tests/resources/templates/api/corrupted_template.yaml @@ -0,0 +1,27 @@ +metadata: + name: corrupted_template +definitions: + entities: + - entity: + category: RESOURCE + type: nova.host + template_id: host + - entity: + category: RESOURCE + type: nova.instance + template_id: instance + relationships: + - relationship: + source: host + target: instance + relationship_type: contains + template_id: host_contains_instance +scenarios: + - scenario: + condition: alarm_on_host and host_contains_instance and alarm_on_instance + actions: + - action: + action_type: add_causal_relationship + action_target: + source: host_alarm + target: instance_alarm diff --git a/vitrage_tempest_tests/tests/resources/templates/api/host_aodh_alarm_for_rca.yaml b/vitrage_tempest_tests/tests/resources/templates/api/host_aodh_alarm_for_rca.yaml index 4beb20c2f..c69464ab3 100644 --- a/vitrage_tempest_tests/tests/resources/templates/api/host_aodh_alarm_for_rca.yaml +++ b/vitrage_tempest_tests/tests/resources/templates/api/host_aodh_alarm_for_rca.yaml @@ -1,5 +1,5 @@ metadata: - id: host_aodh_alarm + name: host_aodh_alarm definitions: entities: - entity: diff --git a/vitrage_tempest_tests/tests/resources/templates/api/nagios_alarm_for_alarms.yaml b/vitrage_tempest_tests/tests/resources/templates/api/nagios_alarm_for_alarms.yaml index bd0bf5d82..b739eb023 100644 --- a/vitrage_tempest_tests/tests/resources/templates/api/nagios_alarm_for_alarms.yaml +++ b/vitrage_tempest_tests/tests/resources/templates/api/nagios_alarm_for_alarms.yaml @@ -1,5 +1,5 @@ metadata: - id: first_deduced_alarm_ever_nagios + name: first_deduced_alarm_ever_nagios definitions: entities: - entity: