Repository: incubator-ariatosca Updated Branches: refs/heads/cli-tests 7f370a9e1 -> 690547001 (forced update)
Create testing framework for the CLI, and add some tests The tests are of: service-templates show service-templates list service-templates store Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/69054700 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/69054700 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/69054700 Branch: refs/heads/cli-tests Commit: 690547001f4793c470b274d859e2783f6b9df5e4 Parents: 9df203e Author: Avia Efrat <[email protected]> Authored: Wed Apr 5 11:28:11 2017 +0300 Committer: Avia Efrat <[email protected]> Committed: Thu Apr 6 12:39:39 2017 +0300 ---------------------------------------------------------------------- aria/cli/commands/__init__.py | 11 +++ aria/cli/commands/service_templates.py | 5 +- tests/cli/base_test.py | 29 +++++- tests/cli/runner.py | 10 +- tests/cli/test_service_templates.py | 136 ++++++++++++++++++++++++++-- 5 files changed, 171 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/69054700/aria/cli/commands/__init__.py ---------------------------------------------------------------------- diff --git a/aria/cli/commands/__init__.py b/aria/cli/commands/__init__.py index ae1e83e..7777791 100644 --- a/aria/cli/commands/__init__.py +++ b/aria/cli/commands/__init__.py @@ -12,3 +12,14 @@ # 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 . import ( + executions, + logs, + node_templates, + nodes, + plugins, + service_templates, + services, + workflows +) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/69054700/aria/cli/commands/service_templates.py ---------------------------------------------------------------------- diff --git a/aria/cli/commands/service_templates.py b/aria/cli/commands/service_templates.py index a324131..e05492e 100644 --- a/aria/cli/commands/service_templates.py +++ b/aria/cli/commands/service_templates.py @@ -15,7 +15,6 @@ import os -import json from .. import utils from .. import csar @@ -66,7 +65,7 @@ def show(service_template_id, model_storage, logger): logger.info('{0}\n'.format(service_template_dict['description'].encode('UTF-8') or '')) logger.info('Existing services:') - logger.info('{0}\n'.format(json.dumps([d['name'] for d in services]))) + logger.info('{0}\n'.format([s['name'] for s in services])) @service_templates.command(name='list', @@ -121,7 +120,7 @@ def store(service_template_path, service_template_name, model_storage, resource_ service_template_name) except storage_exceptions.StorageError as e: handle_storage_exception(e, 'service template', service_template_name) - logger.info('Service template stored') + logger.info('Service template {0} stored'.format(service_template_name)) @service_templates.command(name='delete', http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/69054700/tests/cli/base_test.py ---------------------------------------------------------------------- diff --git a/tests/cli/base_test.py b/tests/cli/base_test.py index c8c574b..d5db9c2 100644 --- a/tests/cli/base_test.py +++ b/tests/cli/base_test.py @@ -6,8 +6,33 @@ from utils import setup_logger class TestCliBase(object): - logger_output = StringIO() - setup_logger(logger_name='aria.cli.main', output_stream=logger_output) + _logger_output = StringIO() + setup_logger(logger_name='aria.cli.main', output_stream=_logger_output) def invoke(self, command): + self._logger_output.truncate(0) return runner.invoke(command) + + @property + def logger_output_string(self): + return self._logger_output.getvalue() + + +def assert_exception_raised(outcome, expected_exception, expected_msg): + assert isinstance(outcome.exception, expected_exception) + assert expected_msg == str(outcome.exception) + + +# This exists as I wanted to mocked a function using monkeypatch to return a function that raises an +# exception. I tried doing that using a lambda in-place, but this can't be accomplished in a trivial +# way it seems. So I wrote this silly function instead +def raise_exception(exception, msg=''): + + def inner(*args, **kwargs): + raise exception(msg) + + return inner + + + + http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/69054700/tests/cli/runner.py ---------------------------------------------------------------------- diff --git a/tests/cli/runner.py b/tests/cli/runner.py index 26af20a..8b4294a 100644 --- a/tests/cli/runner.py +++ b/tests/cli/runner.py @@ -2,11 +2,11 @@ import aria.cli.commands as commands import click.testing -def invoke(command): - # TODO handle verbosity later - command_string = ['service_templates', 'show', '1'] - command, sub, args = command_string[0], command_string[1], command_string[2:] +def invoke(command_string): + # TODO handle verbosity and co. later + command_list = command_string.split() + command, sub, args = command_list[0], command_list[1], command_list[2:] runner = click.testing.CliRunner() outcome = runner.invoke(getattr( getattr(commands, command), sub), args) - return outcome \ No newline at end of file + return outcome http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/69054700/tests/cli/test_service_templates.py ---------------------------------------------------------------------- diff --git a/tests/cli/test_service_templates.py b/tests/cli/test_service_templates.py index 8e1fa65..d0daf59 100644 --- a/tests/cli/test_service_templates.py +++ b/tests/cli/test_service_templates.py @@ -1,27 +1,143 @@ +from aria.cli import service_template_utils from aria.cli.env import Environment -from base_test import TestCliBase -from aria.modeling.models import ServiceTemplate +from aria.cli.exceptions import AriaCliError +from aria.core import Core +from aria.storage import exceptions as storage_exceptions +from tests.cli.base_test import TestCliBase, assert_exception_raised, raise_exception +from tests.mock import models + +import pytest + + [email protected] +def mock_object(mocker): + return mocker.MagicMock() class MockStorage(object): def __init__(self): - self.service_template = MockServiceTemplateStorage() + self.service_template = MockServiceTemplateStorage class MockServiceTemplateStorage(object): - def get(self, id_): - if id_ == '1': # a service-template with no description and no services. - st = ServiceTemplate() - st.name = 'test_st' + @staticmethod + def list(**_): + return [models.create_service_template('test_st'), + models.create_service_template('test_st2')] + + @staticmethod + def get(id): + st = models.create_service_template('test_st') + if id == '1': # no services and no description. + st.services = [] + if id == '2': # no services, but an description + st.description = 'test_description' st.services = [] - return st + if id == '3': # one service, and a description + service = models.create_service(st, 'test_s') + st.description = 'test_description' + st.services = [service] + if id == '4': # one service, and a description + service = models.create_service(st, 'test_s') + st.services = [service] + return st class TestServiceTemplatesShow(TestCliBase): def test_show_no_services_no_description(self, monkeypatch): - # reroute the logger to a special location, and check it's content. + + monkeypatch.setattr(Environment, 'model_storage', MockStorage()) + self.invoke('service_templates show 1') + + assert 'Description:' not in self.logger_output_string + assert 'Existing services:\n[]' in self.logger_output_string + + def test_show_no_services_yes_description(self, monkeypatch): + monkeypatch.setattr(Environment, 'model_storage', MockStorage()) - outcome = self.invoke('service_templates show 1') + self.invoke('service_templates show 2') + + assert 'Description:\ntest_description' in self.logger_output_string + assert 'Existing services:\n[]' in self.logger_output_string + + def test_show_one_service_yes_description(self, monkeypatch): + + monkeypatch.setattr(Environment, 'model_storage', MockStorage()) + self.invoke('service_templates show 3') + + assert 'Description:\ntest_description' in self.logger_output_string + assert "Existing services:\n['test_s']" in self.logger_output_string + + def test_show_one_service_no_description(self, monkeypatch): + + monkeypatch.setattr(Environment, 'model_storage', MockStorage()) + self.invoke('service_templates show 4') + + assert 'Description:' not in self.logger_output_string + assert "Existing services:\n['test_s']" in self.logger_output_string + + def test_show_exception_raise_when_no_service_template_with_given_id(self): + + # TODO consider removing as it does not seem to test the cli but rather the message received + # from the storage + outcome = self.invoke('service_templates show 5') + assert_exception_raised( + outcome, + expected_exception=storage_exceptions.NotFoundError, + expected_msg='Requested `ServiceTemplate` with ID `5` was not found') + + +class TestServiceTemplatesList(TestCliBase): + + def test_list_one_service_template(self, monkeypatch): + + monkeypatch.setattr(Environment, 'model_storage', MockStorage()) + self.invoke('service_templates list') + assert 'test_st' in self.logger_output_string + assert 'test_st2' in self.logger_output_string + + def test_list_ascending(self, monkeypatch, mock_object): + + monkeypatch.setattr(Environment, 'model_storage', mock_object) + self.invoke('service_templates list --sort-by name') + mock_object.service_template.list.assert_called_with(sort={'name': 'asc'}) + + def test_list_descending(self, monkeypatch, mock_object): + + monkeypatch.setattr(Environment, 'model_storage', mock_object) + self.invoke('service_templates list --sort-by name --descending') + mock_object.service_template.list.assert_called_with(sort={'name': 'desc'}) + + def test_list_default_sorting(self, monkeypatch, mock_object): + + monkeypatch.setattr(Environment, 'model_storage', mock_object) + self.invoke('service_templates list') + mock_object.service_template.list.assert_called_with(sort={'created_at': 'asc'}) + + +class TestServiceTemplatesStore(TestCliBase): + + def test_store_no_exception(self, monkeypatch, mock_object): + + monkeypatch.setattr(Core, 'create_service_template', mock_object) + monkeypatch.setattr(service_template_utils, 'get', mock_object) + self.invoke('service_templates store stubpath test_st') + assert 'Service template test_st stored' in self.logger_output_string + + def test_store_raises_exception(self, monkeypatch, mock_object): + + monkeypatch.setattr(service_template_utils, 'get', mock_object) + monkeypatch.setattr(Core, + 'create_service_template', + raise_exception(storage_exceptions.NotFoundError, + msg='UNIQUE constraint failed')) + + outcome = self.invoke('service_templates store stubpath test_st') + assert_exception_raised( + outcome, + expected_exception=AriaCliError, + expected_msg='Could not store service template `test_st`\n' + 'There already a exists a service template with the same name')
