diff --git a/tox.ini b/tox.ini index 79e89ab..bf0abba 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,7 @@ install_command = pip install -U {opts} {packages} setenv = VIRTUAL_ENV={envdir} + OS_TEST_PATH=./watcherclient/tests/unit deps = -r{toxinidir}/test-requirements.txt commands = python setup.py testr --slowest --testr-args='{posargs}' diff --git a/watcherclient/tests/README.rst b/watcherclient/tests/README.rst new file mode 100644 index 0000000..56d04ad --- /dev/null +++ b/watcherclient/tests/README.rst @@ -0,0 +1,61 @@ +.. + Except where otherwise noted, this document is licensed under Creative + Commons Attribution 3.0 License. You can view the license at: + + https://creativecommons.org/licenses/by/3.0/ + +======= +Testing +======= + +.. _functional_tests: + +Functional tests +================ + +The following procedure gets you started with Tempest testing but you can also +refer to the `Tempest documentation`_ for more details. + +.. _Tempest documentation: http://docs.openstack.org/developer/tempest/ + + +Tempest installation +-------------------- + +You need to install virtualenv, create a virtual environment and activate it:: + + $ pip install virtualenv + $ virtualenv watcher-env + $ source watcher-env/bin/activate + +Then, to install Tempest you can issue the following commands:: + + $ git clone https://github.com/openstack/tempest/ + $ pip install tempest/ + +There should be set environment variables using the OpenStack RC file. If +you don't have RC file yet, create ``admin-openrc`` file and fill it using +the following example:: + + export OS_PROJECT_DOMAIN_NAME=default + export OS_USER_DOMAIN_NAME=default + export OS_PROJECT_NAME=admin + export OS_USERNAME=admin + export OS_PASSWORD=admin + export OS_AUTH_URL=http://controller:35357/v3 + export OS_IDENTITY_API_VERSION=3 + export OS_IMAGE_API_VERSION=2 + +Then, save file and execute ``source admin-openrc`` to set environment +variables. + +To run functional tests you need to go to python-watcherclient folder, install +all requirements and execute ``tempest run`` command:: + + $ pip install -r requirements.txt test-requirements.txt + $ pip install . + $ tempest run --regex watcherclient.tests.functional + +You can run specified test(s) by using regular expression:: + + $ tempest run --regex watcherclient.tests.functional.v1.test_action.ActionTests.test_action_list diff --git a/watcherclient/tests/common/__init__.py b/watcherclient/tests/functional/__init__.py similarity index 100% rename from watcherclient/tests/common/__init__.py rename to watcherclient/tests/functional/__init__.py diff --git a/watcherclient/tests/v1/__init__.py b/watcherclient/tests/functional/v1/__init__.py similarity index 100% rename from watcherclient/tests/v1/__init__.py rename to watcherclient/tests/functional/v1/__init__.py diff --git a/watcherclient/tests/functional/v1/base.py b/watcherclient/tests/functional/v1/base.py new file mode 100644 index 0000000..7f53139 --- /dev/null +++ b/watcherclient/tests/functional/v1/base.py @@ -0,0 +1,108 @@ +# 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 re +import shlex +import subprocess +import testtools + +import six +from tempest.lib.cli import output_parser +from tempest.lib import exceptions + + +def execute(cmd, fail_ok=False, merge_stderr=False): + """Executes specified command for the given action.""" + cmdlist = shlex.split(cmd) + 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('^\+\-[\+\-]+\-\+$') + + @classmethod + def watcher(cls, cmd, fail_ok=False): + """Executes watcherclient command for the given action.""" + return execute('watcher {0}'.format(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) diff --git a/watcherclient/tests/functional/v1/test_action.py b/watcherclient/tests/functional/v1/test_action.py new file mode 100644 index 0000000..c87a164 --- /dev/null +++ b/watcherclient/tests/functional/v1/test_action.py @@ -0,0 +1,72 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.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_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'] + + @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 = output[0].keys()[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')) + action_uuid = action_list[0].keys()[0] + action = self.watcher('action show ' + action_uuid) + self.assertIn(action_uuid, action) + self.assert_table_structure([action], + self.detailed_list_fields) diff --git a/watcherclient/tests/functional/v1/test_action_plan.py b/watcherclient/tests/functional/v1/test_action_plan.py new file mode 100644 index 0000000..3f95c58 --- /dev/null +++ b/watcherclient/tests/functional/v1/test_action_plan.py @@ -0,0 +1,123 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.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'] + 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'] + + @classmethod + def tearDownClass(cls): + # Delete action plan + output = cls.parse_show( + cls.watcher('actionplan list --audit %s' % cls.audit_uuid)) + action_plan_uuid = output[0].keys()[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 = action_plan_list[0].keys()[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 = output[0].keys()[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) + + +class ActionPlanActiveTests(base.TestCase): + + audit_uuid = None + audit_template_name = 'b' + uuidutils.generate_uuid() + + list_fields = ['UUID', 'Audit', 'State', 'Updated At', 'Global efficacy'] + detailed_list_fields = list_fields + ['Created At', 'Deleted At', + 'Strategy', 'Efficacy indicators'] + + def _delete_action_plan(self): + output = self.parse_show( + self.watcher('actionplan list --audit %s' % self.audit_uuid)) + action_plan_uuid = output[0].keys()[0] + raw_output = self.watcher('actionplan delete %s' % action_plan_uuid) + self.assertOutput('', raw_output) + + def _delete_audit(self): + raw_output = self.watcher('audit delete %s' % self.audit_uuid) + self.assertOutput('', raw_output) + + def _delete_audit_template(self): + raw_output = self.watcher( + 'audittemplate delete %s' % self.audit_template_name) + self.assertOutput('', raw_output) + + def _create_audit_template(self): + template_raw_output = self.watcher( + 'audittemplate create %s dummy -s dummy' + % self.audit_template_name) + template_output = self.parse_show_as_object(template_raw_output) + return template_output + + def test_action_plan_create(self): + template_output = self._create_audit_template() + action_plan = self.watcher( + 'actionplan create -a %s' % template_output['Name']) + self.audit_uuid = self.parse_show_as_object(action_plan)['UUID'] + self.assert_table_structure([action_plan], self.detailed_list_fields) + self._delete_action_plan() + self._delete_audit() + self._delete_audit_template() diff --git a/watcherclient/tests/functional/v1/test_audit.py b/watcherclient/tests/functional/v1/test_audit.py new file mode 100644 index 0000000..b5d02dc --- /dev/null +++ b/watcherclient/tests/functional/v1/test_audit.py @@ -0,0 +1,114 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.functional.v1 import base + + +class AuditTests(base.TestCase): + """Functional tests for audit.""" + + dummy_name = 'dummy' + list_fields = ['UUID', '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() + 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'] + + @classmethod + def tearDownClass(cls): + output = cls.parse_show( + cls.watcher('actionplan list --audit %s' % cls.audit_uuid)) + action_plan_uuid = output[0].keys()[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 AuditActiveTests(base.TestCase): + + list_fields = ['UUID', '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() + audit_uuid = None + + def _create_audit(self): + raw_output = self.watcher('audittemplate create %s dummy -s dummy' + % self.audit_template_name) + template_output = self.parse_show_as_object(raw_output) + self.audit_uuid = self.parse_show_as_object( + self.watcher('audit create -a %s' + % template_output['Name']))['UUID'] + + def _delete_audit(self): + output = self.parse_show( + self.watcher('actionplan list --audit %s' % self.audit_uuid)) + action_plan_uuid = output[0].keys()[0] + self.watcher('actionplan delete %s' % action_plan_uuid) + self.watcher('audit delete %s' % self.audit_uuid) + self.watcher('audittemplate delete %s' % self.audit_template_name) + + def test_create_audit(self): + raw_output = self.watcher('audittemplate create %s dummy -s dummy' + % self.audit_template_name) + template_output = self.parse_show_as_object(raw_output) + audit = self.watcher('audit create -a %s' % template_output['Name']) + self.audit_uuid = self.parse_show_as_object(audit)['UUID'] + self.assert_table_structure([audit], self.detailed_list_fields) + self._delete_audit() + + def test_delete_audit(self): + self._create_audit() + raw_output = self.watcher('audit delete %s' % self.audit_uuid) + self.assertOutput('', raw_output) + output = self.parse_show( + self.watcher('actionplan list --audit %s' % self.audit_uuid)) + action_plan_uuid = output[0].keys()[0] + self.watcher('actionplan delete %s' % action_plan_uuid) + self.watcher('audittemplate delete %s' % self.audit_template_name) diff --git a/watcherclient/tests/functional/v1/test_audit_template.py b/watcherclient/tests/functional/v1/test_audit_template.py new file mode 100644 index 0000000..b00a912 --- /dev/null +++ b/watcherclient/tests/functional/v1/test_audit_template.py @@ -0,0 +1,90 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.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/watcherclient/tests/functional/v1/test_goal.py b/watcherclient/tests/functional/v1/test_goal.py new file mode 100644 index 0000000..7005e0b --- /dev/null +++ b/watcherclient/tests/functional/v1/test_goal.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.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/watcherclient/tests/functional/v1/test_scoring_engine.py b/watcherclient/tests/functional/v1/test_scoring_engine.py new file mode 100644 index 0000000..5c46be5 --- /dev/null +++ b/watcherclient/tests/functional/v1/test_scoring_engine.py @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.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/watcherclient/tests/functional/v1/test_service.py b/watcherclient/tests/functional/v1/test_service.py new file mode 100644 index 0000000..8c4ebb7 --- /dev/null +++ b/watcherclient/tests/functional/v1/test_service.py @@ -0,0 +1,46 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.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): + 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/watcherclient/tests/functional/v1/test_strategy.py b/watcherclient/tests/functional/v1/test_strategy.py new file mode 100644 index 0000000..329c382 --- /dev/null +++ b/watcherclient/tests/functional/v1/test_strategy.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- +# 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 watcherclient.tests.functional.v1 import base + + +class StrategyTests(base.TestCase): + """Functional tests for strategy.""" + + dummy_name = 'dummy' + list_fields = ['UUID', 'Name', 'Display name', 'Goal'] + + 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) diff --git a/watcherclient/tests/unit/__init__.py b/watcherclient/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/watcherclient/tests/unit/common/__init__.py b/watcherclient/tests/unit/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/watcherclient/tests/common/test_api_versioning.py b/watcherclient/tests/unit/common/test_api_versioning.py similarity index 99% rename from watcherclient/tests/common/test_api_versioning.py rename to watcherclient/tests/unit/common/test_api_versioning.py index 29b42a7..b524b6d 100644 --- a/watcherclient/tests/common/test_api_versioning.py +++ b/watcherclient/tests/unit/common/test_api_versioning.py @@ -17,7 +17,7 @@ import mock from watcherclient.common import api_versioning from watcherclient import exceptions -from watcherclient.tests import utils +from watcherclient.tests.unit import utils class APIVersionTestCase(utils.BaseTestCase): diff --git a/watcherclient/tests/keystone_client_fixtures.py b/watcherclient/tests/unit/keystone_client_fixtures.py similarity index 100% rename from watcherclient/tests/keystone_client_fixtures.py rename to watcherclient/tests/unit/keystone_client_fixtures.py diff --git a/watcherclient/tests/test_client.py b/watcherclient/tests/unit/test_client.py similarity index 99% rename from watcherclient/tests/test_client.py rename to watcherclient/tests/unit/test_client.py index d824713..d788f1b 100644 --- a/watcherclient/tests/test_client.py +++ b/watcherclient/tests/unit/test_client.py @@ -17,7 +17,7 @@ from keystoneauth1 import loading as kaloading from watcherclient import client as watcherclient from watcherclient.common import httpclient from watcherclient import exceptions -from watcherclient.tests import utils +from watcherclient.tests.unit import utils class ClientTest(utils.BaseTestCase): diff --git a/watcherclient/tests/test_import.py b/watcherclient/tests/unit/test_import.py similarity index 96% rename from watcherclient/tests/test_import.py rename to watcherclient/tests/unit/test_import.py index 27b6fca..1ae89e9 100644 --- a/watcherclient/tests/test_import.py +++ b/watcherclient/tests/unit/test_import.py @@ -11,7 +11,7 @@ # License for the specific language governing permissions and limitations # under the License. -from watcherclient.tests import utils +from watcherclient.tests.unit import utils module_str = 'watcherclient' diff --git a/watcherclient/tests/test_utils.py b/watcherclient/tests/unit/test_utils.py similarity index 99% rename from watcherclient/tests/test_utils.py rename to watcherclient/tests/unit/test_utils.py index b966ab2..badcdcd 100644 --- a/watcherclient/tests/test_utils.py +++ b/watcherclient/tests/unit/test_utils.py @@ -18,7 +18,7 @@ import mock from watcherclient.common.apiclient import exceptions as exc from watcherclient.common import utils -from watcherclient.tests import utils as test_utils +from watcherclient.tests.unit import utils as test_utils class UtilsTest(test_utils.BaseTestCase): diff --git a/watcherclient/tests/utils.py b/watcherclient/tests/unit/utils.py similarity index 100% rename from watcherclient/tests/utils.py rename to watcherclient/tests/unit/utils.py diff --git a/watcherclient/tests/unit/v1/__init__.py b/watcherclient/tests/unit/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/watcherclient/tests/v1/base.py b/watcherclient/tests/unit/v1/base.py similarity index 98% rename from watcherclient/tests/v1/base.py rename to watcherclient/tests/unit/v1/base.py index 350a863..d8bec08 100644 --- a/watcherclient/tests/v1/base.py +++ b/watcherclient/tests/unit/v1/base.py @@ -20,7 +20,7 @@ import mock from osc_lib import utils as oscutils from watcherclient.common import httpclient -from watcherclient.tests import utils +from watcherclient.tests.unit import utils class CommandTestCase(utils.BaseTestCase): diff --git a/watcherclient/tests/v1/test_action.py b/watcherclient/tests/unit/v1/test_action.py similarity index 99% rename from watcherclient/tests/v1/test_action.py rename to watcherclient/tests/unit/v1/test_action.py index cfec21f..195f34e 100644 --- a/watcherclient/tests/v1/test_action.py +++ b/watcherclient/tests/unit/v1/test_action.py @@ -16,7 +16,7 @@ import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.action ACTION1 = { diff --git a/watcherclient/tests/v1/test_action_plan.py b/watcherclient/tests/unit/v1/test_action_plan.py similarity index 99% rename from watcherclient/tests/v1/test_action_plan.py rename to watcherclient/tests/unit/v1/test_action_plan.py index cdc0707..8049e83 100644 --- a/watcherclient/tests/v1/test_action_plan.py +++ b/watcherclient/tests/unit/v1/test_action_plan.py @@ -18,7 +18,7 @@ import copy import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.action_plan ACTION_PLAN1 = { diff --git a/watcherclient/tests/v1/test_action_plan_shell.py b/watcherclient/tests/unit/v1/test_action_plan_shell.py similarity index 99% rename from watcherclient/tests/v1/test_action_plan_shell.py rename to watcherclient/tests/unit/v1/test_action_plan_shell.py index a0fc6cf..d36de96 100644 --- a/watcherclient/tests/v1/test_action_plan_shell.py +++ b/watcherclient/tests/unit/v1/test_action_plan_shell.py @@ -14,13 +14,12 @@ # limitations under the License. import datetime - import mock import six from watcherclient import exceptions from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_action_shell.py b/watcherclient/tests/unit/v1/test_action_shell.py similarity index 99% rename from watcherclient/tests/v1/test_action_shell.py rename to watcherclient/tests/unit/v1/test_action_shell.py index 4afe646..cb259e3 100644 --- a/watcherclient/tests/v1/test_action_shell.py +++ b/watcherclient/tests/unit/v1/test_action_shell.py @@ -14,13 +14,12 @@ # under the License. import datetime - import mock import six from watcherclient import exceptions from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_audit.py b/watcherclient/tests/unit/v1/test_audit.py similarity index 99% rename from watcherclient/tests/v1/test_audit.py rename to watcherclient/tests/unit/v1/test_audit.py index 8f67c06..b4b755b 100644 --- a/watcherclient/tests/v1/test_audit.py +++ b/watcherclient/tests/unit/v1/test_audit.py @@ -18,7 +18,7 @@ import copy import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.audit diff --git a/watcherclient/tests/v1/test_audit_shell.py b/watcherclient/tests/unit/v1/test_audit_shell.py similarity index 99% rename from watcherclient/tests/v1/test_audit_shell.py rename to watcherclient/tests/unit/v1/test_audit_shell.py index d4fe518..c2d17ae 100644 --- a/watcherclient/tests/v1/test_audit_shell.py +++ b/watcherclient/tests/unit/v1/test_audit_shell.py @@ -14,13 +14,12 @@ # under the License. import datetime - import mock import six from watcherclient import exceptions from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_audit_template.py b/watcherclient/tests/unit/v1/test_audit_template.py similarity index 99% rename from watcherclient/tests/v1/test_audit_template.py rename to watcherclient/tests/unit/v1/test_audit_template.py index 4c06715..4037677 100644 --- a/watcherclient/tests/v1/test_audit_template.py +++ b/watcherclient/tests/unit/v1/test_audit_template.py @@ -18,7 +18,7 @@ import copy from six.moves.urllib import parse as urlparse from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.audit_template AUDIT_TMPL1 = { diff --git a/watcherclient/tests/v1/test_audit_template_shell.py b/watcherclient/tests/unit/v1/test_audit_template_shell.py similarity index 99% rename from watcherclient/tests/v1/test_audit_template_shell.py rename to watcherclient/tests/unit/v1/test_audit_template_shell.py index 6eecbf9..c957b17 100644 --- a/watcherclient/tests/v1/test_audit_template_shell.py +++ b/watcherclient/tests/unit/v1/test_audit_template_shell.py @@ -14,12 +14,11 @@ # under the License. import datetime - import mock import six from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_goal.py b/watcherclient/tests/unit/v1/test_goal.py similarity index 99% rename from watcherclient/tests/v1/test_goal.py rename to watcherclient/tests/unit/v1/test_goal.py index 505ad45..7f4fd3a 100644 --- a/watcherclient/tests/v1/test_goal.py +++ b/watcherclient/tests/unit/v1/test_goal.py @@ -17,7 +17,7 @@ import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.goal GOAL1 = { diff --git a/watcherclient/tests/v1/test_goal_shell.py b/watcherclient/tests/unit/v1/test_goal_shell.py similarity index 99% rename from watcherclient/tests/v1/test_goal_shell.py rename to watcherclient/tests/unit/v1/test_goal_shell.py index d4b5584..1e9ffd8 100644 --- a/watcherclient/tests/v1/test_goal_shell.py +++ b/watcherclient/tests/unit/v1/test_goal_shell.py @@ -14,12 +14,11 @@ # limitations under the License. import datetime - import mock import six from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_scoring_engine.py b/watcherclient/tests/unit/v1/test_scoring_engine.py similarity index 99% rename from watcherclient/tests/v1/test_scoring_engine.py rename to watcherclient/tests/unit/v1/test_scoring_engine.py index 6a248fb..f6b1b43 100644 --- a/watcherclient/tests/v1/test_scoring_engine.py +++ b/watcherclient/tests/unit/v1/test_scoring_engine.py @@ -17,7 +17,7 @@ import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.scoring_engine SE1 = { diff --git a/watcherclient/tests/v1/test_scoring_engine_shell.py b/watcherclient/tests/unit/v1/test_scoring_engine_shell.py similarity index 99% rename from watcherclient/tests/v1/test_scoring_engine_shell.py rename to watcherclient/tests/unit/v1/test_scoring_engine_shell.py index d13dbb1..5f7ce85 100644 --- a/watcherclient/tests/v1/test_scoring_engine_shell.py +++ b/watcherclient/tests/unit/v1/test_scoring_engine_shell.py @@ -14,12 +14,11 @@ # limitations under the License. import datetime - import mock import six from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_service.py b/watcherclient/tests/unit/v1/test_service.py similarity index 99% rename from watcherclient/tests/v1/test_service.py rename to watcherclient/tests/unit/v1/test_service.py index 38e8a8c..2609954 100644 --- a/watcherclient/tests/v1/test_service.py +++ b/watcherclient/tests/unit/v1/test_service.py @@ -17,7 +17,7 @@ import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.service SERVICE1 = { diff --git a/watcherclient/tests/v1/test_service_shell.py b/watcherclient/tests/unit/v1/test_service_shell.py similarity index 98% rename from watcherclient/tests/v1/test_service_shell.py rename to watcherclient/tests/unit/v1/test_service_shell.py index 0800535..1d4ad60 100644 --- a/watcherclient/tests/v1/test_service_shell.py +++ b/watcherclient/tests/unit/v1/test_service_shell.py @@ -14,12 +14,11 @@ # limitations under the License. import datetime - import mock import six from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields diff --git a/watcherclient/tests/v1/test_strategy.py b/watcherclient/tests/unit/v1/test_strategy.py similarity index 99% rename from watcherclient/tests/v1/test_strategy.py rename to watcherclient/tests/unit/v1/test_strategy.py index 02d6f2d..a3ed2cd 100644 --- a/watcherclient/tests/v1/test_strategy.py +++ b/watcherclient/tests/unit/v1/test_strategy.py @@ -17,7 +17,7 @@ import testtools from testtools import matchers -from watcherclient.tests import utils +from watcherclient.tests.unit import utils import watcherclient.v1.strategy STRATEGY1 = { diff --git a/watcherclient/tests/v1/test_strategy_shell.py b/watcherclient/tests/unit/v1/test_strategy_shell.py similarity index 99% rename from watcherclient/tests/v1/test_strategy_shell.py rename to watcherclient/tests/unit/v1/test_strategy_shell.py index b541d3b..dc897e9 100644 --- a/watcherclient/tests/v1/test_strategy_shell.py +++ b/watcherclient/tests/unit/v1/test_strategy_shell.py @@ -14,12 +14,11 @@ # limitations under the License. import datetime - import mock import six from watcherclient import shell -from watcherclient.tests.v1 import base +from watcherclient.tests.unit.v1 import base from watcherclient import v1 as resource from watcherclient.v1 import resource_fields