diff --git a/vitrage_tempest_plugin/tests/api/templates/base.py b/vitrage_tempest_plugin/tests/api/templates/base.py index 3a83330..9f028f6 100644 --- a/vitrage_tempest_plugin/tests/api/templates/base.py +++ b/vitrage_tempest_plugin/tests/api/templates/base.py @@ -20,24 +20,24 @@ from vitrage.common.exception import VitrageError from vitrage_tempest_plugin.tests.base import BaseVitrageTempest from vitrage_tempest_plugin.tests.base import IsNotEmpty from vitrage_tempest_plugin.tests.common import general_utils as g_utils +from vitrage_tempest_plugin.tests.common.general_utils\ + import tempest_resources_dir from vitrage_tempest_plugin.tests.common import vitrage_utils - LOG = logging.getLogger(__name__) class BaseTemplateTest(BaseVitrageTempest): """Template test class for Vitrage API tests.""" - TEST_PATH = '/opt/stack/vitrage/vitrage_tempest_plugin/' \ - + 'tests/resources/templates/api/' + TEST_PATH = tempest_resources_dir() + '/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' + VALIDATION_FAILED = 'validation failed' + VALIDATION_OK = 'validation OK' OK_MSG = 'Template validation is OK' def _compare_template_lists(self, api_templates, cli_templates): @@ -100,23 +100,30 @@ class BaseTemplateTest(BaseVitrageTempest): 'The template validation is empty') self.assertEqual(path, validation['file path']) self.assertEqual(0, validation['status code']) - self.assertEqual(self.OK_STATUS, validation['status']) + self.assertEqual(self.VALIDATION_OK, validation['status']) self.assertEqual(self.OK_MSG, validation['message']) self.assertEqual(validation['message'], template['status details']) - def _run_template_validation( - self, validation, path, negative=False): - self.assertIn(path, validation['file path']) + def _assert_validate_result(self, validation, path, negative=False, + status_code=0): + self.assertThat(validation['results'], matchers.HasLength(1)) + result = validation['results'][0] + self.assertIn(path, result['file path']) if negative: - self.assertEqual(3, validation['status code']) - self.assertEqual(self.ERROR_STATUS, validation['status']) - self.assertNotEqual(validation['message'], self.OK_MSG) + self.assertEqual(status_code, result['status code']) + self.assertEqual(self.VALIDATION_FAILED, result['status']) + self.assertNotEqual(result['message'], self.OK_MSG) return - self.assertEqual(0, validation['status code']) - self.assertEqual(self.OK_STATUS, validation['status']) - self.assertEqual(self.OK_MSG, validation['message']) + self.assertEqual(0, result['status code']) + self.assertEqual(self.VALIDATION_OK, result['status']) + self.assertEqual(self.OK_MSG, result['message']) + + def _assert_add_result(self, result, status, message): + self.assertThat(result, matchers.HasLength(1)) + self.assertEqual(status, result[0]['status']) + self.assertEqual(message, result[0]['status details']) def _compare_template_show(self, api_templates, cli_templates): self.assertThat(api_templates, IsNotEmpty(), @@ -134,7 +141,8 @@ class BaseTemplateTest(BaseVitrageTempest): sorted_api_templates = sorted(api_templates.items()) self.assertEqual(sorted_api_templates, sorted_cli_templates) - def _rollback_to_default(self, templates): + @staticmethod + def _rollback_to_default(templates): try: for t in templates: db_row = vitrage_utils.get_first_template(name=t) diff --git a/vitrage_tempest_plugin/tests/api/templates/test_template.py b/vitrage_tempest_plugin/tests/api/templates/test_template.py index 56fd4a9..8ffb7e4 100644 --- a/vitrage_tempest_plugin/tests/api/templates/test_template.py +++ b/vitrage_tempest_plugin/tests/api/templates/test_template.py @@ -89,8 +89,8 @@ class TestValidate(BaseTemplateTest): path = self.TEST_PATH + self.ERROR_FILE validation = self.vitrage_client.template.validate(path=path) self.assertThat(validation['results'], matchers.HasLength(1)) - self._run_template_validation( - validation['results'][0], path, negative=True) + self._assert_validate_result( + validation, path, negative=True, status_code=3) except Exception: LOG.error('Failed to get validation of corrupted template file') @@ -103,8 +103,7 @@ class TestValidate(BaseTemplateTest): path = self.TEST_PATH + self.OK_FILE validation = self.vitrage_client.template.validate(path=path) self.assertThat(validation['results'], matchers.HasLength(1)) - self._run_template_validation( - validation['results'][0], path) + self._assert_validate_result(validation, path) except Exception: LOG.error('Failed to get validation of template file') diff --git a/vitrage_tempest_plugin/tests/api/templates/test_template_v2.py b/vitrage_tempest_plugin/tests/api/templates/test_template_v2.py index 64b6b8d..9bbfdf8 100644 --- a/vitrage_tempest_plugin/tests/api/templates/test_template_v2.py +++ b/vitrage_tempest_plugin/tests/api/templates/test_template_v2.py @@ -13,7 +13,6 @@ # under the License. from oslo_log import log as logging -from testtools import matchers from vitrage_tempest_plugin.tests.api.templates.base import BaseTemplateTest @@ -23,39 +22,87 @@ EXECUTE_MISTRAL_TEMPLATE = 'v2_execute_mistral.yaml' EQUIVALENCE_TEMPLATE = 'v2_equivalence_templates.yaml' DEFINITION_TEMPLATE = 'v2_definition_template.yaml' NO_TYPE_TEMPLATE = 'v2_no_type_template.yaml' - -FAKE_UUID = 'ade68276-0fe9-42cd-9ec2-e7f20470a771' +WITH_PARAMS_TEMPLATE = 'v2_with_params.yaml' -class TestValidateV2(BaseTemplateTest): +class TestTemplatesV2(BaseTemplateTest): + """Template test class for Vitrage API tests.""" + FAILED_TO_RESOLVE_PARAM = 'Failed to resolve parameter' + ERROR_STATUS = 'ERROR' + LOADING_STATUS = 'LOADING' + TEMPLATE_VALIDATION_OK = 'Template validation is OK' + + def tearDown(self): + super(TestTemplatesV2, self).tearDown() + self._delete_templates() def test_templates_validate_no_type_templates(self): - try: - path = self.TEST_PATH + NO_TYPE_TEMPLATE - validation = self.vitrage_client.template.validate(path=path) - self.assertThat(validation['results'], matchers.HasLength(1)) - self._run_template_validation( - validation['results'][0], path, negative=True) - except Exception: - LOG.error('Failed to get validation of corrupted template file') + path = self.TEST_PATH + NO_TYPE_TEMPLATE + validation = self.vitrage_client.template.validate(path=path) + self._assert_validate_result( + validation, path, negative=True, status_code='') def test_templates_validate_standard_template(self): - try: - path = self.TEST_PATH + EXECUTE_MISTRAL_TEMPLATE - validation = self.vitrage_client.template.validate(path=path) - self.assertThat(validation['results'], matchers.HasLength(1)) - self._run_template_validation( - validation['results'][0], path) - except Exception: - LOG.error('Failed to get validation of standard template file') + path = self.TEST_PATH + EXECUTE_MISTRAL_TEMPLATE + validation = self.vitrage_client.template.validate(path=path) + self._assert_validate_result(validation, path) def test_templates_validate_definition_template(self): - try: - path = self.TEST_PATH + DEFINITION_TEMPLATE - validation = self.vitrage_client.template.validate(path=path) - self.assertThat(validation['results'], matchers.HasLength(1)) - self._run_template_validation( - validation['results'][0], path) - except Exception: - LOG.error('Failed to get validation of definition template file') + path = self.TEST_PATH + DEFINITION_TEMPLATE + validation = self.vitrage_client.template.validate(path=path) + self._assert_validate_result(validation, path) + + def test_template_validate_with_missing_parameters(self): + path = self.TEST_PATH + WITH_PARAMS_TEMPLATE + validation = self.vitrage_client.template.validate(path=path) + self._assert_validate_result( + validation, path, negative=True, status_code=163) + + def test_template_validate_with_missing_parameter(self): + path = self.TEST_PATH + WITH_PARAMS_TEMPLATE + params = {'template_name': 'My template 1', + 'new_state': 'SUBOPTIMAL'} + validation = \ + self.vitrage_client.template.validate(path=path, params=params) + self._assert_validate_result( + validation, path, negative=True, status_code=163) + + def test_template_validate_with_parameters(self): + path = self.TEST_PATH + WITH_PARAMS_TEMPLATE + params = {'template_name': 'My template 1', + 'alarm_type': 'Monitor1', + 'alarm_name': 'My alarm', + 'new_state': 'SUBOPTIMAL'} + validation = \ + self.vitrage_client.template.validate(path=path, params=params) + self._assert_validate_result(validation, path) + + def test_template_add_with_missing_parameters(self): + path = self.TEST_PATH + WITH_PARAMS_TEMPLATE + result = self.vitrage_client.template.add(path=path) + self._assert_add_result(result, self.ERROR_STATUS, + self.FAILED_TO_RESOLVE_PARAM) + + def test_template_add_with_missing_parameter(self): + path = self.TEST_PATH + WITH_PARAMS_TEMPLATE + params = {'template_name': 'My template 1', + 'new_state': 'SUBOPTIMAL'} + result = self.vitrage_client.template.add(path=path, params=params) + self._assert_add_result(result, self.ERROR_STATUS, + self.FAILED_TO_RESOLVE_PARAM) + + def test_template_add_with_parameters(self): + path = self.TEST_PATH + WITH_PARAMS_TEMPLATE + params = {'template_name': 'My template 1', + 'alarm_type': 'Monitor1', + 'alarm_name': 'My alarm', + 'new_state': 'SUBOPTIMAL'} + result = self.vitrage_client.template.add(path=path, params=params) + self._assert_add_result(result, self.LOADING_STATUS, + self.TEMPLATE_VALIDATION_OK) + + def _delete_templates(self): + templates = self.vitrage_client.template.list() + template_ids = [template['uuid'] for template in templates] + self.vitrage_client.template.delete(template_ids) diff --git a/vitrage_tempest_plugin/tests/resources/templates/api/v2_with_params.yaml b/vitrage_tempest_plugin/tests/resources/templates/api/v2_with_params.yaml new file mode 100644 index 0000000..b64f3fe --- /dev/null +++ b/vitrage_tempest_plugin/tests/resources/templates/api/v2_with_params.yaml @@ -0,0 +1,41 @@ +metadata: + version: 2 + type: standard + name: get_param(template_name) + description: template with parameters +parameters: + template_name: + description: the name of the template + default: template_with_params + alarm_type: + description: the type of the alarm + alarm_name: + new_state: + default: ERROR +definitions: + entities: + - entity: + category: ALARM + type: get_param(alarm_type) + name: get_param(alarm_name) + template_id: alarm + - entity: + category: RESOURCE + type: nova.host + template_id: resource + relationships: + - relationship: + source: alarm + target: resource + relationship_type: on + template_id : alarm_on_host +scenarios: + - scenario: + condition: alarm_on_host + actions: + - action: + action_type: set_state + properties: + state: get_param(new_state) + action_target: + target: resource