From 33fb684fa24b54cbbe5680c286ca26997e63a399 Mon Sep 17 00:00:00 2001 From: zhurong Date: Thu, 14 Mar 2019 16:52:32 +0800 Subject: [PATCH] Move client function test to watcher-tempest-plugin Change-Id: I79fcaded18471d2df4d49a526ad3024e55488f96 --- .../tests/client_functional/__init__.py | 0 .../tests/client_functional/v1/__init__.py | 0 .../tests/client_functional/v1/base.py | 152 ++++++++++++++ .../tests/client_functional/v1/test_action.py | 81 ++++++++ .../client_functional/v1/test_action_plan.py | 97 +++++++++ .../tests/client_functional/v1/test_audit.py | 190 ++++++++++++++++++ .../v1/test_audit_template.py | 89 ++++++++ .../tests/client_functional/v1/test_goal.py | 41 ++++ .../v1/test_scoring_engine.py | 40 ++++ .../client_functional/v1/test_service.py | 47 +++++ .../client_functional/v1/test_strategy.py | 48 +++++ 11 files changed, 785 insertions(+) create mode 100644 watcher_tempest_plugin/tests/client_functional/__init__.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/__init__.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/base.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_action.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_action_plan.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_audit.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_audit_template.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_goal.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_scoring_engine.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_service.py create mode 100644 watcher_tempest_plugin/tests/client_functional/v1/test_strategy.py diff --git a/watcher_tempest_plugin/tests/client_functional/__init__.py b/watcher_tempest_plugin/tests/client_functional/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/watcher_tempest_plugin/tests/client_functional/v1/__init__.py b/watcher_tempest_plugin/tests/client_functional/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/watcher_tempest_plugin/tests/client_functional/v1/base.py b/watcher_tempest_plugin/tests/client_functional/v1/base.py new file mode 100644 index 0000000..84a04cf --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/base.py @@ -0,0 +1,152 @@ +# 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 re +import shlex +import subprocess +import testtools + +import six +from tempest import clients +from tempest.common import credentials_factory as creds_factory +from tempest.lib.cli import output_parser +from tempest.lib import exceptions + + +def credentials(): + # You can get credentials either from tempest.conf file or + # from OS environment. + tempest_creds = clients.get_auth_provider( + creds_factory.get_configured_admin_credentials()) + creds = tempest_creds.credentials + creds_dict = { + '--os-username': os.environ.get('OS_USERNAME', creds.username), + '--os-password': os.environ.get('OS_PASSWORD', creds.password), + '--os-project-name': os.environ.get('OS_PROJECT_NAME', + creds.project_name), + '--os-auth-url': os.environ.get('OS_AUTH_URL', + tempest_creds.auth_url), + '--os-project-domain-name': os.environ.get('OS_PROJECT_DOMAIN_ID', + creds.project_domain_name), + '--os-user-domain-name': os.environ.get('OS_USER_DOMAIN_ID', + creds.user_domain_name), + } + return [x for sub in creds_dict.items() for x in sub] + + +def execute(cmd, fail_ok=False, merge_stderr=False): + """Executes specified command for the given action.""" + cmdlist = shlex.split(cmd) + cmdlist.extend(credentials()) + stdout = subprocess.PIPE + stderr = subprocess.STDOUT if merge_stderr else subprocess.PIPE + proc = subprocess.Popen(cmdlist, stdout=stdout, stderr=stderr) + result, result_err = proc.communicate() + result = result.decode('utf-8') + if not fail_ok and proc.returncode != 0: + raise exceptions.CommandFailed(proc.returncode, cmd, result, + result_err) + return result + + +class TestCase(testtools.TestCase): + + delimiter_line = re.compile('^\+\-[\+\-]+\-\+$') + + api_version = 1.0 + + @classmethod + def watcher(cls, cmd, fail_ok=False): + """Executes watcherclient command for the given action.""" + return execute( + 'openstack optimize --os-infra-optim-api-version {0} {1}'.format( + cls.api_version, cmd), fail_ok=fail_ok) + + @classmethod + def get_opts(cls, fields, format='value'): + return ' -f {0} {1}'.format(format, + ' '.join(['-c ' + it for it in fields])) + + @classmethod + def assertOutput(cls, expected, actual): + if expected != actual: + raise Exception('{0} != {1}'.format(expected, actual)) + + @classmethod + def assertInOutput(cls, expected, actual): + if expected not in actual: + raise Exception('{0} not in {1}'.format(expected, actual)) + + def assert_table_structure(self, items, field_names): + """Verify that all items have keys listed in field_names.""" + for item in items: + for field in field_names: + self.assertIn(field, item) + + def assert_show_fields(self, items, field_names): + """Verify that all items have keys listed in field_names.""" + for item in items: + for key in six.iterkeys(item): + self.assertIn(key, field_names) + + def assert_show_structure(self, items, field_names): + """Verify that all field_names listed in keys of all items.""" + if isinstance(items, list): + o = {} + for d in items: + o.update(d) + else: + o = items + item_keys = o.keys() + for field in field_names: + self.assertIn(field, item_keys) + + @staticmethod + def parse_show_as_object(raw_output): + """Return a dict with values parsed from cli output.""" + items = TestCase.parse_show(raw_output) + o = {} + for item in items: + o.update(item) + return o + + @staticmethod + def parse_show(raw_output): + """Return list of dicts with item values parsed from cli output.""" + + items = [] + table_ = output_parser.table(raw_output) + for row in table_['values']: + item = {} + item[row[0]] = row[1] + items.append(item) + return items + + def parse_listing(self, raw_output): + """Return list of dicts with basic item parsed from cli output.""" + return output_parser.listing(raw_output) + + def has_actionplan_succeeded(self, ap_uuid): + return self.parse_show_as_object( + self.watcher('actionplan show %s' % ap_uuid) + )['State'] == 'SUCCEEDED' + + @classmethod + def has_audit_created(cls, audit_uuid): + audit = cls.parse_show_as_object( + cls.watcher('audit show %s' % audit_uuid)) + if audit['Audit Type'] == 'ONESHOT': + return audit['State'] == 'SUCCEEDED' + else: + return audit['State'] == 'ONGOING' diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_action.py b/watcher_tempest_plugin/tests/client_functional/v1/test_action.py new file mode 100644 index 0000000..6526cf0 --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_action.py @@ -0,0 +1,81 @@ +# Copyright (c) 2016 Servionica +# +# 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_utils import uuidutils + +import functools + +from tempest.lib.common.utils import test_utils + +from watcher_tempest_plugin.tests.client_functional.v1 import base + + +class ActionTests(base.TestCase): + """Functional tests for action.""" + + dummy_name = 'dummy' + list_fields = ['UUID', 'Parents', 'State', 'Action Plan', 'Action'] + detailed_list_fields = list_fields + ['Created At', 'Updated At', + 'Deleted At', 'Parameters'] + audit_template_name = 'a' + uuidutils.generate_uuid() + audit_uuid = None + + @classmethod + def setUpClass(cls): + template_raw_output = cls.watcher( + 'audittemplate create %s dummy -s dummy' % cls.audit_template_name) + template_output = cls.parse_show_as_object(template_raw_output) + audit_output = cls.parse_show_as_object(cls.watcher( + 'audit create -a %s' % template_output['Name'])) + cls.audit_uuid = audit_output['UUID'] + audit_created = test_utils.call_until_true( + func=functools.partial(cls.has_audit_created, cls.audit_uuid), + duration=600, + sleep_for=2) + if not audit_created: + raise Exception('Audit has not been succeeded') + + @classmethod + def tearDownClass(cls): + # Delete Action Plan and all related actions. + output = cls.parse_show( + cls.watcher('actionplan list --audit %s' % cls.audit_uuid)) + action_plan_uuid = list(output[0])[0] + raw_output = cls.watcher('actionplan delete %s' % action_plan_uuid) + cls.assertOutput('', raw_output) + # Delete audit + raw_output = cls.watcher('audit delete %s' % cls.audit_uuid) + cls.assertOutput('', raw_output) + # Delete Template + raw_output = cls.watcher( + 'audittemplate delete %s' % cls.audit_template_name) + cls.assertOutput('', raw_output) + + def test_action_list(self): + raw_output = self.watcher('action list') + self.assert_table_structure([raw_output], self.list_fields) + + def test_action_detailed_list(self): + raw_output = self.watcher('action list --detail') + self.assert_table_structure([raw_output], self.detailed_list_fields) + + def test_action_show(self): + action_list = self.parse_show(self.watcher('action list --audit %s' + % self.audit_uuid)) + action_uuid = list(action_list[0])[0] + action = self.watcher('action show %s' % action_uuid) + self.assertIn(action_uuid, action) + self.assert_table_structure([action], + self.detailed_list_fields) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_action_plan.py b/watcher_tempest_plugin/tests/client_functional/v1/test_action_plan.py new file mode 100644 index 0000000..e37b0d0 --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_action_plan.py @@ -0,0 +1,97 @@ +# Copyright (c) 2016 Servionica +# +# 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_utils import uuidutils + +import functools + +from tempest.lib.common.utils import test_utils + +from watcher_tempest_plugin.tests.client_functional.v1 import base + + +class ActionPlanTests(base.TestCase): + """Functional tests for action plan.""" + + dummy_name = 'dummy' + list_fields = ['UUID', 'Audit', 'State', 'Updated At', 'Global efficacy'] + detailed_list_fields = list_fields + ['Created At', 'Deleted At', + 'Strategy', 'Efficacy indicators', + 'Hostname'] + audit_template_name = 'a' + uuidutils.generate_uuid() + audit_uuid = None + + @classmethod + def setUpClass(cls): + template_raw_output = cls.watcher( + 'audittemplate create %s dummy -s dummy' % cls.audit_template_name) + template_output = cls.parse_show_as_object(template_raw_output) + audit_raw_output = cls.watcher('audit create -a %s' + % template_output['Name']) + audit_output = cls.parse_show_as_object(audit_raw_output) + cls.audit_uuid = audit_output['UUID'] + audit_created = test_utils.call_until_true( + func=functools.partial(cls.has_audit_created, cls.audit_uuid), + duration=600, + sleep_for=2) + if not audit_created: + raise Exception('Audit has not been succeeded') + + @classmethod + def tearDownClass(cls): + # Delete action plan + output = cls.parse_show( + cls.watcher('actionplan list --audit %s' % cls.audit_uuid)) + action_plan_uuid = list(output[0])[0] + raw_output = cls.watcher('actionplan delete %s' % action_plan_uuid) + cls.assertOutput('', raw_output) + # Delete audit + raw_output = cls.watcher('audit delete %s' % cls.audit_uuid) + cls.assertOutput('', raw_output) + # Delete Template + raw_output = cls.watcher( + 'audittemplate delete %s' % cls.audit_template_name) + cls.assertOutput('', raw_output) + + def test_action_plan_list(self): + raw_output = self.watcher('actionplan list') + self.assert_table_structure([raw_output], self.list_fields) + + def test_action_plan_detailed_list(self): + raw_output = self.watcher('actionplan list --detail') + self.assert_table_structure([raw_output], self.detailed_list_fields) + + def test_action_plan_show(self): + action_plan_list = self.parse_show(self.watcher('actionplan list')) + action_plan_uuid = list(action_plan_list[0])[0] + actionplan = self.watcher('actionplan show %s' % action_plan_uuid) + self.assertIn(action_plan_uuid, actionplan) + self.assert_table_structure([actionplan], + self.detailed_list_fields) + + def test_action_plan_start(self): + output = self.parse_show(self.watcher('actionplan list --audit %s' + % self.audit_uuid)) + action_plan_uuid = list(output[0])[0] + self.watcher('actionplan start %s' % action_plan_uuid) + raw_output = self.watcher('actionplan show %s' % action_plan_uuid) + self.assert_table_structure([raw_output], self.detailed_list_fields) + + self.assertTrue(test_utils.call_until_true( + func=functools.partial( + self.has_actionplan_succeeded, action_plan_uuid), + duration=600, + sleep_for=2 + )) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_audit.py b/watcher_tempest_plugin/tests/client_functional/v1/test_audit.py new file mode 100644 index 0000000..11fde8c --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_audit.py @@ -0,0 +1,190 @@ +# Copyright (c) 2016 Servionica +# +# 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 datetime import datetime +from dateutil import tz +import functools + +from oslo_utils import uuidutils +from tempest.lib.common.utils import test_utils + +from watcher_tempest_plugin.tests.client_functional.v1 import base + + +class AuditTests(base.TestCase): + """Functional tests for audit.""" + + dummy_name = 'dummy' + list_fields = ['UUID', 'Name', 'Audit Type', 'State', 'Goal', 'Strategy'] + detailed_list_fields = list_fields + ['Created At', 'Updated At', + 'Deleted At', 'Parameters', + 'Interval', 'Audit Scope', + 'Next Run Time', 'Hostname'] + audit_template_name = 'a' + uuidutils.generate_uuid() + audit_uuid = None + + @classmethod + def setUpClass(cls): + raw_output = cls.watcher('audittemplate create %s dummy -s dummy' + % cls.audit_template_name) + template_output = cls.parse_show_as_object(raw_output) + audit_raw_output = cls.watcher( + 'audit create -a %s' % template_output['Name']) + audit_output = cls.parse_show_as_object(audit_raw_output) + cls.audit_uuid = audit_output['UUID'] + audit_created = test_utils.call_until_true( + func=functools.partial(cls.has_audit_created, cls.audit_uuid), + duration=600, + sleep_for=2) + if not audit_created: + raise Exception('Audit has not been succeeded') + + @classmethod + def tearDownClass(cls): + output = cls.parse_show( + cls.watcher('actionplan list --audit %s' % cls.audit_uuid)) + action_plan_uuid = list(output[0])[0] + cls.watcher('actionplan delete %s' % action_plan_uuid) + cls.watcher('audit delete %s' % cls.audit_uuid) + cls.watcher('audittemplate delete %s' % cls.audit_template_name) + + def test_audit_list(self): + raw_output = self.watcher('audit list') + self.assert_table_structure([raw_output], self.list_fields) + + def test_audit_detailed_list(self): + raw_output = self.watcher('audit list --detail') + self.assert_table_structure([raw_output], self.detailed_list_fields) + + def test_audit_show(self): + audit = self.watcher('audit show ' + self.audit_uuid) + self.assertIn(self.audit_uuid, audit) + self.assert_table_structure([audit], self.detailed_list_fields) + + def test_audit_update(self): + audit_raw_output = self.watcher('audit update %s add interval=2' + % self.audit_uuid) + audit_output = self.parse_show_as_object(audit_raw_output) + assert int(audit_output['Interval']) == 2 + + +class AuditTestsV11(AuditTests): + """This class tests v1.1 of Watcher API""" + + api_version = 1.1 + + detailed_list_fields = AuditTests.list_fields + [ + 'Created At', 'Updated At', 'Deleted At', 'Parameters', 'Interval', + 'Audit Scope', 'Next Run Time', 'Hostname', 'Start Time', 'End Time'] + + def test_audit_detailed_list(self): + raw_output = self.watcher('audit list --detail') + self.assert_table_structure([raw_output], self.detailed_list_fields) + + def test_audit_show(self): + audit = self.watcher('audit show ' + self.audit_uuid) + self.assertIn(self.audit_uuid, audit) + self.assert_table_structure([audit], self.detailed_list_fields) + + def test_audit_update(self): + local_time = datetime.now(tz.tzlocal()) + local_time_str = local_time.strftime("%Y-%m-%dT%H:%M:%S") + utc_time = (local_time - local_time.utcoffset()) + utc_time_str = utc_time.strftime("%Y-%m-%dT%H:%M:%S") + audit_raw_output = self.watcher( + 'audit update {0} replace end_time="{1}"'.format(self.audit_uuid, + local_time_str)) + audit_output = self.parse_show_as_object(audit_raw_output) + assert audit_output['End Time'] == utc_time_str + + +class AuditActiveTests(base.TestCase): + + list_fields = ['UUID', 'Name', 'Audit Type', 'State', 'Goal', 'Strategy'] + detailed_list_fields = list_fields + ['Created At', 'Updated At', + 'Deleted At', 'Parameters', + 'Interval', 'Audit Scope'] + audit_template_name = 'a' + uuidutils.generate_uuid() + + @classmethod + def setUpClass(cls): + cls.watcher('audittemplate create %s dummy -s dummy' + % cls.audit_template_name) + + @classmethod + def tearDownClass(cls): + cls.watcher('audittemplate delete %s' % cls.audit_template_name) + + def _create_audit(self): + return self.parse_show_as_object( + self.watcher('audit create -a %s' + % self.audit_template_name))['UUID'] + + def _delete_audit(self, audit_uuid): + self.assertTrue(test_utils.call_until_true( + func=functools.partial( + self.has_audit_created, audit_uuid), + duration=600, + sleep_for=2 + )) + output = self.parse_show( + self.watcher('actionplan list --audit %s' % audit_uuid)) + action_plan_uuid = list(output[0])[0] + self.watcher('actionplan delete %s' % action_plan_uuid) + self.watcher('audit delete %s' % audit_uuid) + + def test_create_oneshot_audit(self): + audit = self.watcher('audit create -a %s' % self.audit_template_name) + audit_uuid = self.parse_show_as_object(audit)['UUID'] + self.assert_table_structure([audit], self.detailed_list_fields) + self._delete_audit(audit_uuid) + + def test_delete_oneshot_audit(self): + audit_uuid = self._create_audit() + self.assertTrue(test_utils.call_until_true( + func=functools.partial( + self.has_audit_created, audit_uuid), + duration=600, + sleep_for=2 + )) + raw_output = self.watcher('audit delete %s' % audit_uuid) + self.assertOutput('', raw_output) + output = self.parse_show( + self.watcher('actionplan list --audit %s' % audit_uuid)) + action_plan_uuid = list(output[0])[0] + self.watcher('actionplan delete %s' % action_plan_uuid) + + def test_continuous_audit(self): + audit = self.watcher('audit create -a %s -t CONTINUOUS -i 600' + % self.audit_template_name) + audit_uuid = self.parse_show_as_object(audit)['UUID'] + self.assert_table_structure([audit], self.detailed_list_fields) + self.assertTrue(test_utils.call_until_true( + func=functools.partial( + self.has_audit_created, audit_uuid), + duration=600, + sleep_for=2 + )) + audit_state = self.parse_show_as_object( + self.watcher('audit show %s' % audit_uuid))['State'] + if audit_state == 'ONGOING': + self.watcher('audit update %s replace state=CANCELLED' + % audit_uuid) + raw_output = self.watcher('audit delete %s' % audit_uuid) + self.assertOutput('', raw_output) + outputs = self.parse_listing( + self.watcher('actionplan list --audit %s' % audit_uuid)) + for actionplan in outputs: + self.watcher('actionplan delete %s' % actionplan['UUID']) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_audit_template.py b/watcher_tempest_plugin/tests/client_functional/v1/test_audit_template.py new file mode 100644 index 0000000..4c77f86 --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_audit_template.py @@ -0,0 +1,89 @@ +# Copyright (c) 2016 Servionica +# +# 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_utils import uuidutils + +from watcher_tempest_plugin.tests.client_functional.v1 import base + + +class AuditTemplateTests(base.TestCase): + """Functional tests for audit template.""" + + dummy_name = 'dummy' + list_fields = ['UUID', 'Name', 'Goal', 'Strategy'] + detailed_list_fields = list_fields + ['Created At', 'Updated At', + 'Deleted At', 'Description', + 'Audit Scope'] + audit_template_name = 'a' + uuidutils.generate_uuid() + + @classmethod + def setUpClass(cls): + cls.watcher('audittemplate create %s dummy -s dummy' + % cls.audit_template_name) + + @classmethod + def tearDownClass(cls): + cls.watcher('audittemplate delete %s' % cls.audit_template_name) + + def test_audit_template_list(self): + raw_output = self.watcher('audittemplate list') + self.assert_table_structure([raw_output], self.list_fields) + + def test_audit_template_detailed_list(self): + raw_output = self.watcher('audittemplate list --detail') + self.assert_table_structure([raw_output], self.detailed_list_fields) + + def test_audit_template_show(self): + audit_template = self.watcher( + 'audittemplate show %s' % self.audit_template_name) + self.assertIn(self.audit_template_name, audit_template) + self.assert_table_structure([audit_template], + self.detailed_list_fields) + + def test_audit_template_update(self): + raw_output = self.watcher('audittemplate update %s replace ' + 'description="Updated Desc"' + % self.audit_template_name) + audit_template_output = self.parse_show_as_object(raw_output) + assert audit_template_output['Description'] == 'Updated Desc' + + +class AuditTemplateActiveTests(base.TestCase): + + audit_template_name = 'b' + uuidutils.generate_uuid() + list_fields = ['UUID', 'Name', 'Goal', 'Strategy'] + detailed_list_fields = list_fields + ['Created At', 'Updated At', + 'Deleted At', 'Description', + 'Audit Scope'] + + def _create_audit_template(self): + self.watcher('audittemplate create %s dummy -s dummy ' + '-d "Test Audit Template"' % self.audit_template_name) + + def _delete_audit_template(self): + self.watcher('audittemplate delete %s' % self.audit_template_name) + + def test_create_audit_template(self): + raw_output = self.watcher('audittemplate create %s dummy ' + '-s dummy -d "Test Audit Template"' + % self.audit_template_name) + self.assert_table_structure([raw_output], self.detailed_list_fields) + self._delete_audit_template() + + def test_delete_audit_template(self): + self._create_audit_template() + raw_output = self.watcher('audittemplate delete %s' + % self.audit_template_name) + self.assertOutput('', raw_output) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_goal.py b/watcher_tempest_plugin/tests/client_functional/v1/test_goal.py new file mode 100644 index 0000000..7c25a1f --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_goal.py @@ -0,0 +1,41 @@ +# Copyright (c) 2016 Servionica +# +# 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 watcher_tempest_plugin.tests.client_functional.v1 import base + + +class GoalTests(base.TestCase): + """Functional tests for goal.""" + + dummy_name = 'dummy' + list_fields = ['UUID', 'Name', 'Display name'] + + def test_goal_list(self): + raw_output = self.watcher('goal list') + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], self.list_fields) + + def test_goal_detailed_list(self): + raw_output = self.watcher('goal list --detail') + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure( + [raw_output], self.list_fields + ['Efficacy specification']) + + def test_goal_show(self): + raw_output = self.watcher('goal show %s' % self.dummy_name) + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure( + [raw_output], self.list_fields + ['Efficacy specification']) + self.assertNotIn('server_consolidation', raw_output) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_scoring_engine.py b/watcher_tempest_plugin/tests/client_functional/v1/test_scoring_engine.py new file mode 100644 index 0000000..34bd855 --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_scoring_engine.py @@ -0,0 +1,40 @@ +# Copyright (c) 2016 Servionica +# +# 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 watcher_tempest_plugin.tests.client_functional.v1 import base + + +class ScoringEngineTests(base.TestCase): + """Functional tests for scoring engine.""" + + dummy_name = 'dummy_scorer' + list_fields = ['UUID', 'Name', 'Description'] + detailed_list_fields = list_fields + ['Metainfo'] + + def test_scoringengine_list(self): + raw_output = self.watcher('scoringengine list') + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], self.list_fields) + + def test_scoringengine_detailed_list(self): + raw_output = self.watcher('scoringengine list --detail') + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], self.detailed_list_fields) + + def test_scoringengine_show(self): + raw_output = self.watcher('scoringengine show %s' % self.dummy_name) + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], self.detailed_list_fields) + self.assertNotIn('dummy_avg_scorer', raw_output) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_service.py b/watcher_tempest_plugin/tests/client_functional/v1/test_service.py new file mode 100644 index 0000000..1252b15 --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_service.py @@ -0,0 +1,47 @@ +# Copyright (c) 2016 Servionica +# +# 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 watcher_tempest_plugin.tests.client_functional.v1 import base + + +class ServiceTests(base.TestCase): + """Functional tests for service.""" + + decision_engine_name = 'watcher-decision-engine' + applier_name = 'watcher-applier' + list_fields = ['ID', 'Name', 'Host', 'Status'] + + def test_service_list(self): + raw_output = self.watcher('service list') + self.assertIn(self.decision_engine_name, raw_output) + self.assertIn(self.applier_name, raw_output) + self.assert_table_structure([raw_output], self.list_fields) + + def test_service_detailed_list(self): + raw_output = self.watcher('service list --detail') + self.assertIn(self.decision_engine_name, raw_output) + self.assertIn(self.applier_name, raw_output) + self.assert_table_structure([raw_output], + self.list_fields + ['Last seen up']) + + def test_service_show(self): + # TODO(alexchadin): this method should be refactored since Watcher will + # get HA support soon. + raw_output = self.watcher('service show %s' + % self.decision_engine_name) + self.assertIn(self.decision_engine_name, raw_output) + self.assert_table_structure([raw_output], + self.list_fields + ['Last seen up']) + self.assertNotIn(self.applier_name, raw_output) diff --git a/watcher_tempest_plugin/tests/client_functional/v1/test_strategy.py b/watcher_tempest_plugin/tests/client_functional/v1/test_strategy.py new file mode 100644 index 0000000..cbc1e21 --- /dev/null +++ b/watcher_tempest_plugin/tests/client_functional/v1/test_strategy.py @@ -0,0 +1,48 @@ +# Copyright (c) 2016 Servionica +# +# 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 watcher_tempest_plugin.tests.client_functional.v1 import base + + +class StrategyTests(base.TestCase): + """Functional tests for strategy.""" + + dummy_name = 'dummy' + basic_strategy = 'basic' + list_fields = ['UUID', 'Name', 'Display name', 'Goal'] + state_fields = ['Datasource', 'Metrics', 'CDM', 'Name'] + + def test_strategy_list(self): + raw_output = self.watcher('strategy list') + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], self.list_fields) + + def test_strategy_detailed_list(self): + raw_output = self.watcher('strategy list --detail') + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], + self.list_fields + ['Parameters spec']) + + def test_strategy_show(self): + raw_output = self.watcher('strategy show %s' % self.dummy_name) + self.assertIn(self.dummy_name, raw_output) + self.assert_table_structure([raw_output], + self.list_fields + ['Parameters spec']) + self.assertNotIn('basic', raw_output) + + def test_strategy_state(self): + raw_output = self.watcher('strategy state %s' % self.basic_strategy) + self.assertIn(self.basic_strategy, raw_output) + self.assert_table_structure([raw_output], self.state_fields)