tasks.yaml, network_roles.yaml are optional files for V3

For V3:
 - tasks.yaml and network_roles.yaml are not mandatory,
 - validation is skipped if optional file is not exists,
 - unit test class TestValidatorV3 added,
 - tests for validators V1, V2 extracted to separate files.

Added error messages for empty and not exist files.
Fixed error for task without parameters for V1, V2.

Change-Id: I3eaf12a7a22a35067bae04b6bb5cc81a6835cfd5
Closes-Bug: #1477128
This commit is contained in:
Alexander Kislitsky 2015-07-23 13:12:13 +03:00 committed by Alexander Kislitsky
parent 9237356b18
commit d6017cc5c2
11 changed files with 616 additions and 267 deletions

View File

@ -33,6 +33,20 @@ class ValidationError(FuelPluginException):
pass
class FileIsEmpty(ValidationError):
def __init__(self, file_path):
super(FileIsEmpty, self).__init__(
"File '{0}' is empty".format(file_path)
)
class FileDoesNotExist(ValidationError):
def __init__(self, file_path):
super(FileDoesNotExist, self).__init__(
"File '{0}' does not exist".format(file_path)
)
class WrongPackageVersionError(FuelPluginException):
pass

View File

@ -21,9 +21,10 @@ except ImportError:
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
@ -81,3 +82,140 @@ class BaseTestCase(TestCase):
"""
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, _):
mocked_methods = [
'check_schemas',
'check_tasks',
'check_releases_paths',
'check_compatibility',
]
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()

View File

@ -89,6 +89,16 @@ class TestBaseValidator(BaseTestCase):
self.validator.validate_schema(
data, schema, 'file_path', value_path=[0, 'path2'])
@mock.patch(
'fuel_plugin_builder.validators.base.BaseValidator.validate_schema')
def test_validate_file_by_schema_failed(self, utils_mock):
utils_mock.parse_yaml.return_value = self.data
with self.assertRaisesRegexp(
errors.FileDoesNotExist,
"File '/tmp/plugin_path' does not exist"):
self.validator.validate_file_by_schema(
self.schema, self.plugin_path)
@mock.patch('fuel_plugin_builder.validators.base.utils')
@mock.patch(
'fuel_plugin_builder.validators.base.BaseValidator.validate_schema')
@ -98,6 +108,17 @@ class TestBaseValidator(BaseTestCase):
utils_mock.parse_yaml.assert_called_once_with(self.plugin_path)
validate_mock(self.data, self.schema, self.plugin_path)
@mock.patch('fuel_plugin_builder.validators.base.utils')
@mock.patch('fuel_plugin_builder.validators.base.utils.exists')
def test_error_message_on_empty_file(self, exists_mock, utils_mock):
utils_mock.parse_yaml.return_value = None
exists_mock.return_value = True
with self.assertRaisesRegexp(
errors.ValidationError,
"File '/tmp/plugin_path' is empty"):
self.validator.validate_file_by_schema(
self.schema, self.plugin_path)
def test_validate_schema_with_subschemas(self):
schema_object = {
'key': {

View File

@ -1,250 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2015 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.
import mock
from fuel_plugin_builder import errors
from fuel_plugin_builder.tests.base import BaseTestCase
from fuel_plugin_builder.validators import ValidatorV1
from fuel_plugin_builder.validators import ValidatorV2
from fuel_plugin_builder.validators.schemas.v1 import SchemaV1
from fuel_plugin_builder.validators.schemas.v2 import SchemaV2
@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, _):
mocked_methods = [
'check_schemas',
'check_tasks',
'check_releases_paths',
'check_compatibility',
]
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()
class TestValidatorV1(BaseValidator):
__test__ = True
validator_class = ValidatorV1
schema_class = SchemaV1
@mock.patch('fuel_plugin_builder.validators.validator_v1.utils')
def test_check_tasks(self, utils_mock):
mocked_methods = [
'validate_schema'
]
self.mock_methods(self.validator, mocked_methods)
utils_mock.parse_yaml.return_value = [
{'type': 'puppet', 'parameters': 'param1'},
{'type': 'shell', 'parameters': 'param2'}]
self.validator.check_tasks()
self.assertEqual(
[mock.call('param1', self.schema_class().puppet_parameters,
self.validator.tasks_path,
value_path=[0, 'parameters']),
mock.call('param2', self.schema_class().shell_parameters,
self.validator.tasks_path,
value_path=[1, 'parameters'])],
self.validator.validate_schema.call_args_list)
@mock.patch('fuel_plugin_builder.validators.base.utils')
def test_check_compatibility(self, utils_mock):
utils_mock.parse_yaml.return_value = {
'fuel_version': ['5.1', '6.0', '6.1'],
'package_version': '1.0.0'}
with self.assertRaisesRegexp(
errors.ValidationError,
'Current plugin format 1.0.0 is not compatible with 5.1 Fuel'
' release. Fuel version must be 6.0 or higher.'
' Please remove 5.1 version from metadata.yaml file or'
' downgrade package_version.'):
self.validator.check_compatibility()
class TestValidatorV2(BaseValidator):
__test__ = True
validator_class = ValidatorV2
schema_class = SchemaV2
@mock.patch('fuel_plugin_builder.validators.validator_v2.utils')
def test_check_tasks(self, utils_mock):
mocked_methods = [
'validate_schema'
]
self.mock_methods(self.validator, mocked_methods)
utils_mock.parse_yaml.return_value = [
{'type': 'puppet', 'parameters': 'param1'},
{'type': 'shell', 'parameters': 'param2'},
{'type': 'reboot', 'parameters': 'param3'}]
self.validator.check_tasks()
self.assertEqual(
[mock.call('param1', self.schema_class().puppet_parameters,
self.validator.tasks_path,
value_path=[0, 'parameters']),
mock.call('param2', self.schema_class().shell_parameters,
self.validator.tasks_path,
value_path=[1, 'parameters']),
mock.call('param3', self.schema_class().reboot_parameters,
self.validator.tasks_path,
value_path=[2, 'parameters'])],
self.validator.validate_schema.call_args_list)
@mock.patch('fuel_plugin_builder.validators.base.utils')
def test_check_compatibility(self, utils_mock):
utils_mock.parse_yaml.return_value = {
'fuel_version': ['6.0', '6.1'],
'package_version': '2.0.0'}
with self.assertRaisesRegexp(
errors.ValidationError,
'Current plugin format 2.0.0 is not compatible with 6.0 Fuel'
' release. Fuel version must be 6.1 or higher.'
' Please remove 6.0 version from metadata.yaml file or'
' downgrade package_version.'):
self.validator.check_compatibility()

View File

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
# Copyright 2015 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.
import mock
from fuel_plugin_builder import errors
from fuel_plugin_builder.tests.base import BaseValidator
from fuel_plugin_builder.validators.schemas.v1 import SchemaV1
from fuel_plugin_builder.validators.validator_v1 import ValidatorV1
class TestValidatorV1(BaseValidator):
__test__ = True
validator_class = ValidatorV1
schema_class = SchemaV1
@mock.patch('fuel_plugin_builder.validators.validator_v1.utils')
def test_check_tasks(self, utils_mock):
mocked_methods = [
'validate_schema'
]
self.mock_methods(self.validator, mocked_methods)
utils_mock.parse_yaml.return_value = [
{'type': 'puppet', 'parameters': 'param1'},
{'type': 'shell', 'parameters': 'param2'}]
self.validator.check_tasks()
self.assertEqual(
[mock.call('param1', self.schema_class().puppet_parameters,
self.validator.tasks_path,
value_path=[0, 'parameters']),
mock.call('param2', self.schema_class().shell_parameters,
self.validator.tasks_path,
value_path=[1, 'parameters'])],
self.validator.validate_schema.call_args_list)
@mock.patch('fuel_plugin_builder.validators.validator_v1.utils')
def test_check_tasks_no_parameters_not_failed(self, utils_mock):
mocked_methods = [
'validate_schema'
]
self.mock_methods(self.validator, mocked_methods)
utils_mock.parse_yaml.return_value = [
{'type': 'puppet'},
]
self.validator.check_tasks()
self.assertEqual(
[mock.call(None, self.schema_class().puppet_parameters,
self.validator.tasks_path,
value_path=[0, 'parameters'])],
self.validator.validate_schema.call_args_list)
@mock.patch('fuel_plugin_builder.validators.base.utils')
def test_check_compatibility(self, utils_mock):
utils_mock.parse_yaml.return_value = {
'fuel_version': ['5.1', '6.0', '6.1'],
'package_version': '1.0.0'}
with self.assertRaisesRegexp(
errors.ValidationError,
'Current plugin format 1.0.0 is not compatible with 5.1 Fuel'
' release. Fuel version must be 6.0 or higher.'
' Please remove 5.1 version from metadata.yaml file or'
' downgrade package_version.'):
self.validator.check_compatibility()

View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
# Copyright 2015 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.
import mock
from fuel_plugin_builder import errors
from fuel_plugin_builder.tests.base import BaseValidator
from fuel_plugin_builder.validators.schemas.v2 import SchemaV2
from fuel_plugin_builder.validators.validator_v2 import ValidatorV2
class TestValidatorV2(BaseValidator):
__test__ = True
validator_class = ValidatorV2
schema_class = SchemaV2
@mock.patch('fuel_plugin_builder.validators.validator_v2.utils')
def test_check_tasks(self, utils_mock):
mocked_methods = [
'validate_schema'
]
self.mock_methods(self.validator, mocked_methods)
utils_mock.parse_yaml.return_value = [
{'type': 'puppet', 'parameters': 'param1'},
{'type': 'shell', 'parameters': 'param2'},
{'type': 'reboot', 'parameters': 'param3'}]
self.validator.check_tasks()
self.assertEqual(
[mock.call('param1', self.schema_class().puppet_parameters,
self.validator.tasks_path,
value_path=[0, 'parameters']),
mock.call('param2', self.schema_class().shell_parameters,
self.validator.tasks_path,
value_path=[1, 'parameters']),
mock.call('param3', self.schema_class().reboot_parameters,
self.validator.tasks_path,
value_path=[2, 'parameters'])],
self.validator.validate_schema.call_args_list)
@mock.patch('fuel_plugin_builder.validators.base.utils')
def test_check_compatibility(self, utils_mock):
utils_mock.parse_yaml.return_value = {
'fuel_version': ['6.0', '6.1'],
'package_version': '2.0.0'}
with self.assertRaisesRegexp(
errors.ValidationError,
'Current plugin format 2.0.0 is not compatible with 6.0 Fuel'
' release. Fuel version must be 6.1 or higher.'
' Please remove 6.0 version from metadata.yaml file or'
' downgrade package_version.'):
self.validator.check_compatibility()
@mock.patch('fuel_plugin_builder.validators.validator_v2.utils')
def test_check_tasks_no_parameters_not_failed(self, utils_mock):
mocked_methods = [
'validate_schema'
]
self.mock_methods(self.validator, mocked_methods)
utils_mock.parse_yaml.return_value = [
{'type': 'puppet'},
]
self.validator.check_tasks()
self.assertEqual(
[mock.call(None, self.schema_class().puppet_parameters,
self.validator.tasks_path,
value_path=[0, 'parameters'])],
self.validator.validate_schema.call_args_list)

View File

@ -0,0 +1,222 @@
# -*- coding: utf-8 -*-
# Copyright 2015 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.
import mock
from fuel_plugin_builder import errors
from fuel_plugin_builder.tests.base import BaseValidator
from fuel_plugin_builder.validators.schemas.v3 import SchemaV3
from fuel_plugin_builder.validators.validator_v3 import ValidatorV3
class TestValidatorV3(BaseValidator):
__test__ = True
validator_class = ValidatorV3
schema_class = SchemaV3
def test_check_tasks_schema_validation_failed(self):
data_sets = [
{
'type': 'shell',
'parameters': {
'timeout': 3
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'puppet',
'parameters': {
'timeout': 3
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'puppet',
'parameters': {
'timeout': 3,
'cmd': 'xx'
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'shell',
'parameters': {
'timeout': 3,
'puppet_manifest': 'xx',
'puppet_modules': 'yy',
},
'stage': 'post_deployment',
'role': '*'
}
]
with mock.patch.object(self.validator, '_parse_tasks') as \
parse_tasks_mock:
for data in data_sets:
parse_tasks_mock.return_value = [data]
self.assertRaises(errors.ValidationError,
self.validator.check_tasks)
def test_check_tasks_schema_validation_passed(self):
data_sets = [
[
{
'type': 'shell',
'parameters': {
'timeout': 3,
'cmd': 'xx'
},
'stage': 'post_deployment',
'role': '*'
},
],
[
{
'type': 'shell',
'parameters': {
'timeout': 3,
'cmd': 'xx'
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'puppet',
'parameters': {
'timeout': 3,
'puppet_manifest': 'xx',
'puppet_modules': 'xxx'
},
'stage': 'post_deployment',
'role': '*'
},
],
[
{
'type': 'reboot',
'parameters': {
'timeout': 3,
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'shell',
'parameters': {
'timeout': 3,
'cmd': 'xx'
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'puppet',
'parameters': {
'timeout': 3,
'puppet_manifest': 'xx',
'puppet_modules': 'xxx'
},
'stage': 'post_deployment',
'role': '*'
}
],
[
{
'type': 'reboot',
'parameters': {
'timeout': 3,
'cmd': 'xx'
},
'stage': 'post_deployment',
'role': '*'
},
{
'type': 'reboot',
'parameters': {
'timeout': 3,
'puppet_manifest': 'xx',
'puppet_modules': 'yy',
},
'stage': 'post_deployment',
'role': '*'
}
]
]
with mock.patch.object(self.validator, '_parse_tasks') as \
parse_tasks_mock:
for data in data_sets:
parse_tasks_mock.return_value = data
self.validator.check_tasks()
@mock.patch('fuel_plugin_builder.validators.base.utils.exists')
def test_check_tasks_no_file(self, exists_mock):
mocked_methods = ['validate_schema']
self.mock_methods(self.validator, mocked_methods)
exists_mock.return_value = False
self.validator.check_tasks()
self.assertFalse(self.validator.validate_schema.called)
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, check_file_exists=False),
mock.call(self.schema_class().network_roles_schema,
self.validator.network_roles_path,
check_file_exists=False)],
self.validator.validate_file_by_schema.call_args_list)
self.validator.check_env_config_attrs.assert_called_once_with()
@mock.patch('fuel_plugin_builder.validators.base.utils')
def test_check_compatibility_failed(self, utils_mock):
fuel_version_checks = (
(['6.0', '6.1', '7.0']),
(['6.1', '7.0']),
)
for fuel_version in fuel_version_checks:
version_in_msg = fuel_version[0]
utils_mock.parse_yaml.return_value = {
'fuel_version': fuel_version,
'package_version': '3.0.0'}
with self.assertRaisesRegexp(
errors.ValidationError,
'Current plugin format 3.0.0 is not compatible with {0}'
' Fuel release. Fuel version must be 7.0 or higher.'
' Please remove {0} version from metadata.yaml file or'
' downgrade package_version.'.format(version_in_msg)):
self.validator.check_compatibility()
@mock.patch('fuel_plugin_builder.validators.base.utils')
def test_check_compatibility_passed(self, utils_mock):
utils_mock.parse_yaml.return_value = {
'fuel_version': ['7.0'],
'package_version': '3.0.0'}
self.validator.check_compatibility()

View File

@ -73,8 +73,21 @@ class BaseValidator(object):
return error_msg
def validate_file_by_schema(self, schema, file_path):
def validate_file_by_schema(self, schema, file_path,
check_file_exists=True):
if not check_file_exists and not utils.exists(file_path):
logger.debug('No file "%s". Skipping check.',
self.network_roles_path)
return
if not utils.exists(file_path):
raise errors.FileDoesNotExist(file_path)
data = utils.parse_yaml(file_path)
if data is None:
raise errors.FileIsEmpty(file_path)
self.validate_schema(data, schema, file_path)
@abc.abstractmethod

View File

@ -15,7 +15,6 @@
# under the License.
import logging
from os.path import join as join_path
from fuel_plugin_builder import utils
@ -61,7 +60,7 @@ class ValidatorV1(BaseValidator):
for idx, task in enumerate(tasks):
self.validate_schema(
task['parameters'],
task.get('parameters'),
schemas[task['type']],
self.tasks_path,
value_path=[idx, 'parameters'])

View File

@ -15,7 +15,6 @@
# under the License.
import logging
from os.path import join as join_path
from fuel_plugin_builder import utils
@ -47,13 +46,18 @@ class ValidatorV2(BaseValidator):
self.check_releases_paths()
self.check_compatibility()
def _parse_tasks(self):
return utils.parse_yaml(self.tasks_path)
def check_tasks(self):
"""Json schema doesn't have any conditions, so we have
to make sure here, that puppet task is really puppet,
shell or reboot tasks are correct too
"""
logger.debug('Start tasks checking "%s"', self.tasks_path)
tasks = utils.parse_yaml(self.tasks_path)
tasks = self._parse_tasks()
if tasks is None:
return
schemas = {
'puppet': self.schema.puppet_parameters,
@ -62,7 +66,7 @@ class ValidatorV2(BaseValidator):
for idx, task in enumerate(tasks):
self.validate_schema(
task['parameters'],
task.get('parameters'),
schemas[task['type']],
self.tasks_path,
value_path=[idx, 'parameters'])

View File

@ -14,14 +14,18 @@
# License for the specific language governing permissions and limitations
# under the License.
import logging
from os.path import join as join_path
from fuel_plugin_builder import errors
from fuel_plugin_builder import utils
from fuel_plugin_builder.validators.schemas import v3
from fuel_plugin_builder.validators import validator_v2
from fuel_plugin_builder.validators import ValidatorV2
logger = logging.getLogger(__name__)
class ValidatorV3(validator_v2.ValidatorV2):
class ValidatorV3(ValidatorV2):
schema = v3.SchemaV3()
@ -34,12 +38,28 @@ class ValidatorV3(validator_v2.ValidatorV2):
def basic_version(self):
return '7.0'
def validate(self):
super(ValidatorV3, self).validate()
self.check_network_roles()
def check_schemas(self):
logger.debug('Start schema checking "%s"', self.plugin_path)
self.validate_file_by_schema(
self.schema.metadata_schema,
self.meta_path)
self.validate_file_by_schema(
self.schema.tasks_schema,
self.tasks_path,
check_file_exists=False
)
self.validate_file_by_schema(
self.schema.network_roles_schema,
self.network_roles_path,
check_file_exists=False
)
self.check_env_config_attrs()
def check_network_roles(self):
network_roles = utils.parse_yaml(self.network_roles_path)
self.validate_schema(
network_roles, self.schema.network_roles_schema,
self.network_roles_path)
def _parse_tasks(self):
if utils.exists(self.tasks_path):
tasks = utils.parse_yaml(self.tasks_path)
# Tasks schema is not checked in check_schemas, thus
# we perform manual check on parsing tasks file
if tasks is None:
raise errors.FileIsEmpty(self.tasks_path)
return None