411d77392c
Python package version is changed to the 4.0.0. Templates updated. Related to blueprint external-dashboard-links-in-fuel-dashboard Change-Id: I473e409dd29d5b2c3647dc37c6051e5527ed196a
239 lines
8.4 KiB
Python
239 lines
8.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2014 Mirantis, Inc.
|
|
#
|
|
# 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.
|
|
|
|
try:
|
|
from unittest.case import TestCase
|
|
except ImportError:
|
|
# Required for python 2.6
|
|
from unittest2.case import TestCase
|
|
|
|
import mock
|
|
from StringIO import StringIO
|
|
|
|
from fuel_plugin_builder import errors
|
|
|
|
|
|
class FakeFile(StringIO):
|
|
"""It's a fake file which returns StringIO
|
|
when file opens with 'with' statement.
|
|
|
|
NOTE(eli): We cannot use mock_open from mock library
|
|
here, because it hangs when we use 'with' statement,
|
|
and when we want to read file by chunks.
|
|
"""
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *args):
|
|
pass
|
|
|
|
def writelines(self, lines):
|
|
self.write(''.join(lines))
|
|
|
|
|
|
class BaseTestCase(TestCase):
|
|
"""Base class for test cases
|
|
"""
|
|
|
|
def method_was_not_called(self, method):
|
|
"""Checks that mocked method was not called
|
|
"""
|
|
self.assertEqual(method.call_count, 0)
|
|
|
|
def called_times(self, method, count):
|
|
"""Checks that mocked method was called `count` times
|
|
"""
|
|
self.assertEqual(method.call_count, count)
|
|
|
|
def mock_open(self, text, filename='some.yaml'):
|
|
"""Mocks builtin open function.
|
|
|
|
Usage example:
|
|
|
|
with mock.patch(
|
|
'__builtin__.open',
|
|
self.mock_open('file content')
|
|
):
|
|
# call some methods that are used open() to read some
|
|
# stuff internally
|
|
"""
|
|
fileobj = FakeFile(text)
|
|
setattr(fileobj, 'name', filename)
|
|
return mock.MagicMock(return_value=fileobj)
|
|
|
|
def mock_methods(self, obj, methods):
|
|
"""Mocks methods for object
|
|
|
|
:param obj: object for mocking
|
|
:param methods: list of methods for mocking
|
|
"""
|
|
for method in methods:
|
|
setattr(obj, method, mock.MagicMock())
|
|
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils')
|
|
class BaseValidator(BaseTestCase):
|
|
|
|
__test__ = False
|
|
validator_class = None
|
|
schema_class = None
|
|
|
|
def setUp(self):
|
|
self.plugin_path = '/tmp/plugin_path'
|
|
self.validator = self.validator_class(self.plugin_path)
|
|
|
|
def test_validate(self, _, additional_mocked_methods=None):
|
|
mocked_methods = [
|
|
'check_schemas',
|
|
'check_tasks',
|
|
'check_releases_paths',
|
|
'check_compatibility',
|
|
]
|
|
mocked_methods.extend(additional_mocked_methods or [])
|
|
self.mock_methods(self.validator, mocked_methods)
|
|
self.validator.validate()
|
|
|
|
self.validator.check_tasks.assert_called_once_with()
|
|
self.validator.check_schemas.assert_called_once_with()
|
|
self.validator.check_releases_paths.assert_called_once_with()
|
|
self.validator.check_compatibility.assert_called_once_with()
|
|
|
|
def test_check_schemas(self, _):
|
|
mocked_methods = [
|
|
'check_env_config_attrs',
|
|
'validate_file_by_schema'
|
|
]
|
|
self.mock_methods(self.validator, mocked_methods)
|
|
self.validator.check_schemas()
|
|
|
|
self.assertEqual(
|
|
[mock.call(
|
|
self.schema_class().metadata_schema,
|
|
self.validator.meta_path),
|
|
mock.call(
|
|
self.schema_class().tasks_schema,
|
|
self.validator.tasks_path)],
|
|
self.validator.validate_file_by_schema.call_args_list)
|
|
self.validator.check_env_config_attrs.assert_called_once_with()
|
|
|
|
def test_check_releases_paths(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = {
|
|
'releases': [{
|
|
'deployment_scripts_path': '/tmp/deployment_scripts_path',
|
|
'repository_path': '/tmp/repository_path'}]}
|
|
|
|
utils_mock.exists.return_value = True
|
|
self.validator.check_releases_paths()
|
|
self.assertEqual(
|
|
utils_mock.exists.call_args_list,
|
|
[mock.call('/tmp/deployment_scripts_path'),
|
|
mock.call('/tmp/repository_path')])
|
|
|
|
def test_check_releases_paths_error(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = {
|
|
'releases': [{
|
|
'deployment_scripts_path': '/tmp/deployment_scripts_path',
|
|
'repository_path': '/tmp/repository_path'}]}
|
|
|
|
utils_mock.exists.return_value = False
|
|
with self.assertRaisesRegexp(
|
|
errors.ReleasesDirectoriesError,
|
|
'Cannot find directories /tmp/deployment_scripts_path'
|
|
', /tmp/repository_path for release '):
|
|
self.validator.check_releases_paths()
|
|
|
|
def test_check_env_config_attrs_do_not_fail_if_empty(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = None
|
|
self.validator.check_env_config_attrs()
|
|
|
|
def test_check_env_config_attrs_fail_if_none(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = {'attributes': None}
|
|
with self.assertRaisesRegexp(
|
|
errors.ValidationError,
|
|
"File '/tmp/plugin_path/environment_config.yaml', None "
|
|
"is not of type 'object', value path 'attributes'"):
|
|
self.validator.check_env_config_attrs()
|
|
|
|
def test_check_env_config_attrs_checks_metadata(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = {
|
|
'attributes': {'metadata': []}}
|
|
|
|
with self.assertRaisesRegexp(
|
|
errors.ValidationError,
|
|
"File '/tmp/plugin_path/environment_config.yaml', \[\] is "
|
|
"not of type 'object', value path 'attributes -> metadata'"):
|
|
self.validator.check_env_config_attrs()
|
|
|
|
def test_check_env_config_attrs_checks_attrs(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = {
|
|
'attributes': {
|
|
'key1': {
|
|
'type': True,
|
|
'label': 'text',
|
|
'value': 'text',
|
|
'weight': 1}}}
|
|
|
|
with self.assertRaisesRegexp(
|
|
errors.ValidationError,
|
|
"File '/tmp/plugin_path/environment_config.yaml', True is not "
|
|
"of type 'string', value path 'attributes -> key1 -> type'"):
|
|
self.validator.check_env_config_attrs()
|
|
|
|
def test_check_env_config_attrs_restriction_fails(self, utils_mock):
|
|
utils_mock.parse_yaml.return_value = {
|
|
'attributes': {
|
|
'key1': {
|
|
'type': 'text',
|
|
'label': 'test',
|
|
'value': 'test',
|
|
'weight': 1,
|
|
'restrictions': [
|
|
{
|
|
'condition': 'false',
|
|
'action': 'disable'
|
|
},
|
|
{
|
|
'condition': True,
|
|
'action': 'hide'
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
with self.assertRaisesRegexp(
|
|
errors.ValidationError,
|
|
"File '/tmp/plugin_path/environment_config.yaml', True is not "
|
|
"of type 'string', value path "
|
|
"'attributes -> key1 -> restrictions -> 1 -> condition"):
|
|
self.validator.check_env_config_attrs()
|
|
|
|
def check_raised_exception(self, utils_mock, mock_data,
|
|
err_msg, executed_method,
|
|
err_type=errors.ValidationError):
|
|
"""Check if the given error with given type was raised.
|
|
|
|
:param obj utils_mock: fuel_plugin_builder.utils mock
|
|
:param List[dict] mock_data: mock data
|
|
:param str err_msg: what error message is expected
|
|
:param function executed_method: what method should be executed
|
|
:param Exception err_type: what error type is expected
|
|
"""
|
|
utils_mock.parse_yaml.return_value = mock_data
|
|
|
|
with self.assertRaisesRegexp(err_type, err_msg):
|
|
executed_method()
|