murano/murano/tests/unit/cmd/test_manage.py

232 lines
9.1 KiB
Python

# Copyright (c) 2016 AT&T Corp
# All Rights Reserved.
#
# 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 unittest import mock
from oslo_config import cfg
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from murano.cmd import manage
from murano.db.catalog import api as db_catalog_api
from murano.db import models
from murano.db import session as db_session
from murano.tests.unit import base as test_base
CONF = cfg.CONF
class TestManage(test_base.MuranoWithDBTestCase):
def setUp(self):
super(TestManage, self).setUp()
session = db_session.get_session()
# Create environment.
self.test_environment = models.Environment(
name=b'test_environment', tenant_id=b'test_tenant_id',
version=1
)
# Create categories.
self.test_categories = [
models.Category(name=b'test_category_1'),
models.Category(name=b'test_category_2')
]
# Create tags.
self.test_tags = [
models.Tag(name=b'test_tag_1'),
models.Tag(name=b'test_tag_2')
]
# Add environment, categories and tags to DB.
with session.begin():
session.add(self.test_environment)
session.add_all(self.test_categories)
session.add_all(self.test_tags)
# Create package.
self.test_package = models.Package(
fully_qualified_name=b'test_fqn', name=b'test_name',
logo=b'test_logo', supplier_logo=b'test_supplier_logo',
type=b'test_type', description=b'test_desc', is_public=True,
archive=b'test_archive', ui_definition=b'test_ui_definition',
categories=self.test_categories, tags=self.test_tags,
owner_id=self.test_environment.tenant_id,)
# Add the package to the DB.
with session.begin():
session.add(self.test_package)
# Create class definitions and assign their FKs to test_package.id.
self.test_class_definitions = [
models.Class(name=b'test_class_definition_1',
package_id=self.test_package.id),
models.Class(name=b'test_class_definition_2',
package_id=self.test_package.id)
]
# Add the class definitions to the DB and update the FK reference for
# test_package.class_definitions.
with session.begin():
session.add_all(self.test_class_definitions)
self.test_package.class_definitions = self.test_class_definitions
session.add(self.test_package)
# Create mock object that resembles loaded package from
# load_utils.load_from_dir
self.mock_loaded_package = mock.MagicMock(
full_name=self.test_package.fully_qualified_name,
display_name=self.test_package.name,
package_type=self.test_package.type,
author=self.test_package.author,
supplier=self.test_package.supplier,
description=self.test_package.description,
tags=[tag.name for tag in self.test_package.tags],
classes=[cls.name for cls in self.test_package.class_definitions],
logo=self.test_package.logo,
supplier_logo=self.test_package.supplier_logo,
ui=self.test_package.ui_definition,
blob=self.test_package.archive)
@mock.patch('murano.cmd.manage.LOG')
@mock.patch('murano.cmd.manage.load_utils')
def test_do_import_package(self, mock_load_utils, mock_log):
manage.CONF = mock.MagicMock()
manage.CONF.command = mock.MagicMock(
directory='test_dir',
categories=[cat.name for cat in self.test_package.categories],
update=True)
mock_load_utils.load_from_dir.return_value = self.mock_loaded_package
manage.do_import_package()
# Assert that the function ran to completion.
self.assertIn("Finished import of package",
str(mock_log.info.mock_calls[0]))
# Check that the package was uploaded to the DB.
filter_params = {
'name': self.test_package.name,
'fully_qualified_name': self.test_package.fully_qualified_name,
'type': self.test_package.type,
'description': self.test_package.description
}
retrieved_package = None
session = db_session.get_session()
with session.begin():
retrieved_package = session.query(models.Package)\
.filter_by(**filter_params).first()
self.assertIsNotNone(retrieved_package)
self.assertNotEqual(self.test_package.id, retrieved_package.id)
@mock.patch('murano.cmd.manage.LOG')
@mock.patch('murano.cmd.manage.load_utils')
@mock.patch('murano.cmd.manage.db_catalog_api')
def test_do_import_package_without_update(self, mock_db_catalog_api,
mock_load_utils, mock_log):
mock_db_catalog_api.package_search.return_value =\
[self.test_package]
mock_load_utils.load_from_dir.return_value =\
mock.MagicMock(full_name='test_full_name')
manage.CONF = mock.MagicMock()
manage.CONF.command = mock.MagicMock(
directory='test_dir',
categories=[],
update=False)
manage.do_import_package()
mock_log.error.assert_called_once_with(
"Package '{name}' exists ({pkg_id}). Use --update."
.format(name='test_full_name', pkg_id=self.test_package.id))
@mock.patch('sys.stdout', new_callable=StringIO)
def test_do_list_categories(self, mock_stdout):
expected_output = ">> Murano package categories:* "\
"test_category_1* test_category_2"
manage.do_list_categories()
self.assertEqual(expected_output,
mock_stdout.getvalue().replace('\n', '')
.replace('b\'', '').replace('\'', ''))
@mock.patch('murano.cmd.manage.db_catalog_api')
@mock.patch('sys.stdout', new_callable=StringIO)
def test_do_list_categories_with_no_categories(self, mock_stdout,
mock_db_catalog_api):
mock_db_catalog_api.category_get_names.return_value = []
expected_output = "No categories were found"
manage.do_list_categories()
self.assertEqual(
expected_output, mock_stdout.getvalue().replace('\n', ''))
@mock.patch('sys.stdout', new_callable=StringIO)
def test_do_add_category(self, mock_stdout):
manage.CONF = mock.MagicMock()
manage.CONF.command.category_name = 'test_category_name'
expected_output = ">> Successfully added category test_category_name"
manage.do_add_category()
self.assertEqual(expected_output,
mock_stdout.getvalue().replace('\n', ''))
@mock.patch('sys.stdout', new_callable=StringIO)
def test_do_add_category_except_duplicate_error(self, mock_stdout):
manage.CONF = mock.MagicMock()
manage.CONF.command.category_name = 'test_category_name'
expected_output = ">> ERROR: Category \'test_category_name\' already "\
"exists"
db_catalog_api.category_add('test_category_name')
manage.do_add_category()
self.assertEqual(expected_output,
mock_stdout.getvalue().replace('\n', ''))
def test_add_command_parsers(self):
mock_parser = mock.MagicMock()
mock_subparsers = mock.MagicMock()
mock_subparsers.add_parser.return_value = mock_parser
manage.add_command_parsers(mock_subparsers)
mock_subparsers.add_parser.assert_any_call('import-package')
mock_subparsers.add_parser.assert_any_call('category-list')
mock_subparsers.add_parser.assert_any_call('category-add')
mock_parser.set_defaults.assert_any_call(func=manage.do_import_package)
mock_parser.set_defaults.assert_any_call(
func=manage.do_list_categories)
mock_parser.set_defaults.assert_any_call(func=manage.do_add_category)
self.assertEqual(4, mock_parser.add_argument.call_count)
@mock.patch('murano.cmd.manage.CONF')
def test_main_except_runtime_error(self, mock_conf):
mock_conf.side_effect = RuntimeError
with self.assertRaisesRegex(SystemExit, 'ERROR:'):
manage.main()
@mock.patch('murano.cmd.manage.CONF')
def test_main_except_general_exception(self, mock_conf):
mock_conf.command.func.side_effect = Exception
expected_err_msg = "murano-manage command failed:"
with self.assertRaisesRegex(SystemExit, expected_err_msg):
manage.main()