453 lines
16 KiB
Python
453 lines
16 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2016 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.test_validator_v4 import TestValidatorV4
|
|
from fuel_plugin_builder.validators.schemas import SchemaV5
|
|
from fuel_plugin_builder.validators.validator_v5 import ValidatorV5
|
|
|
|
|
|
class TestValidatorV5(TestValidatorV4):
|
|
|
|
__test__ = True
|
|
validator_class = ValidatorV5
|
|
schema_class = SchemaV5
|
|
package_version = '5.0.0'
|
|
|
|
def setUp(self):
|
|
super(TestValidatorV5, self).setUp()
|
|
|
|
def test_check_schemas(self):
|
|
mocked_methods = [
|
|
'check_metadata_schema',
|
|
'check_env_config_attrs',
|
|
'check_tasks_schema',
|
|
'check_deployment_tasks_schema',
|
|
'check_network_roles_schema',
|
|
'check_node_roles_schema',
|
|
'check_volumes_schema',
|
|
'check_components_schema',
|
|
'check_node_attributes_schema'
|
|
]
|
|
self.mock_methods(self.validator, mocked_methods)
|
|
self.mock_methods(
|
|
self.validator,
|
|
['validate_file_by_schema', 'check_interface_attributes_schema']
|
|
)
|
|
self.validator.check_schemas()
|
|
|
|
self.assertEqual(
|
|
[mock.call(self.validator.bond_config_path),
|
|
mock.call(self.validator.nic_config_path)],
|
|
self.validator.check_interface_attributes_schema.call_args_list)
|
|
for method in mocked_methods:
|
|
getattr(self.validator, method).assert_called_once_with()
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils')
|
|
def test_check_compatibility_failed(self, utils_mock):
|
|
fuel_version_checks = (
|
|
(['8.0', '9.0', '10.0']),
|
|
(['6.1', '7.0', '8.0']),
|
|
(['6.0', '6.1', '7.0']),
|
|
(['6.1', '7.0']),
|
|
)
|
|
|
|
for fuel_version in fuel_version_checks:
|
|
mock_data = {
|
|
'fuel_version': fuel_version,
|
|
'package_version': '5.0.0'}
|
|
err_msg = 'Current plugin format 5.0.0 is not compatible with ' \
|
|
'{0} Fuel release. Fuel version must be 9.0 or higher.' \
|
|
' Please remove {0} version from metadata.yaml file or' \
|
|
' downgrade package_version.'.format(fuel_version[0])
|
|
|
|
self.check_raised_exception(
|
|
utils_mock, mock_data,
|
|
err_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': ['9.0', '9.1', '9.2', '10.0'],
|
|
'package_version': '5.0.0'}
|
|
self.validator.check_compatibility()
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils.exists')
|
|
def test_check_interface_attributes_schema_validation_no_file(self,
|
|
exists_mock):
|
|
mocked_methods = ['validate_schema']
|
|
self.mock_methods(self.validator, mocked_methods)
|
|
exists_mock.return_value = False
|
|
self.validator.check_interface_attributes_schema(mock.ANY)
|
|
self.assertFalse(self.validator.validate_schema.called)
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils')
|
|
def test_check_interface_attributes_schema_validation_failed(self,
|
|
utils_mock):
|
|
data_sets = [
|
|
{
|
|
'123': {
|
|
'label': 'Attribute without type',
|
|
'description': 'Attribute without type',
|
|
'value': ''
|
|
}
|
|
},
|
|
{
|
|
'attribute_without_label': {
|
|
'description': 'Attribute without label',
|
|
'type': 'text',
|
|
'value': 'attribute_value'
|
|
}
|
|
}, {
|
|
'attribute_without_value': {
|
|
'label': 'Attribute without value',
|
|
'description': 'Attribute without value',
|
|
'type': 'text',
|
|
}
|
|
},
|
|
{
|
|
'attribute-1': {
|
|
'description': 'Attribute with wrong label type',
|
|
'label': 123,
|
|
'type': 'checkbox',
|
|
}
|
|
},
|
|
{
|
|
'attribute-2': {
|
|
'label': 'Attribute with wrong type type',
|
|
'type': [],
|
|
}
|
|
},
|
|
{
|
|
'attribute-3': {
|
|
'label': 'Attribute with wrong description type',
|
|
'type': 'text',
|
|
'description': False
|
|
}
|
|
},
|
|
{
|
|
'attribute-4': {
|
|
'label': 'Attribute with wrong restrictions type',
|
|
'type': 'text',
|
|
'restrictions': {}
|
|
}
|
|
},
|
|
{
|
|
'label': 'Missed attribute name. Wrong level nesting.',
|
|
'type': 'text',
|
|
'value': ''
|
|
},
|
|
{
|
|
'extra_level': {
|
|
'attribute_name': {
|
|
'label': 'Attribute with extra nesting level',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'uns@pported_letters=!n_attr_name*': {
|
|
'label': 'Attribute with wrong name',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
},
|
|
['wrong interface attributes object type']
|
|
]
|
|
|
|
for data in data_sets:
|
|
utils_mock.parse_yaml.return_value = data
|
|
self.assertRaises(errors.ValidationError,
|
|
self.validator.check_interface_attributes_schema,
|
|
mock.ANY)
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils')
|
|
def test_check_interface_attributes_schema_validation_passed(self,
|
|
utils_mock):
|
|
data_sets = [
|
|
{
|
|
'123': {
|
|
'label': 'Attribute with min required fields',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
},
|
|
{
|
|
'Attribute_1': {
|
|
'label': 'Attribute with restrictions & complex value',
|
|
'description': 'Some attribute description',
|
|
'type': 'text',
|
|
'value': {'key1': ['val_1', 'val_2']},
|
|
'restrictions': [
|
|
{
|
|
'condition': 'false',
|
|
'action': 'disable'
|
|
}
|
|
]
|
|
},
|
|
'attribute-2': {
|
|
'label': 'Attribute with additional fields',
|
|
'type': 'number',
|
|
'description': 'Some attribute description',
|
|
'value': 10,
|
|
'min': 0
|
|
},
|
|
'metadata': {
|
|
'label': 'Some metadata'
|
|
}
|
|
}
|
|
]
|
|
|
|
for data in data_sets:
|
|
utils_mock.parse_yaml.return_value = data
|
|
self.validator.check_interface_attributes_schema('nic_config_path')
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils.exists')
|
|
def test_check_node_attributes_schema_validation_no_file(self,
|
|
exists_mock):
|
|
mocked_methods = ['validate_schema']
|
|
self.mock_methods(self.validator, mocked_methods)
|
|
exists_mock.return_value = False
|
|
self.validator.check_node_attributes_schema()
|
|
self.assertFalse(self.validator.validate_schema.called)
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils')
|
|
def test_check_node_attributes_schema_validation_failed(self, utils_mock):
|
|
data_sets = [
|
|
{
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'123': {
|
|
'label': 'Attribute without type',
|
|
'description': 'Attribute without type',
|
|
'value': ''
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute_without_label': {
|
|
'description': 'Attribute without label',
|
|
'type': 'text',
|
|
'value': 'attribute_value'
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute_without_value': {
|
|
'label': 'Attribute without value',
|
|
'description': 'Attribute without value',
|
|
'type': 'text',
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute-1': {
|
|
'description': 'Attribute with wrong label type',
|
|
'label': 123,
|
|
'type': 'checkbox',
|
|
'value': ''
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute-2': {
|
|
'label': 'Attribute with wrong type type',
|
|
'type': [],
|
|
'value': ''
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute-3': {
|
|
'label': 'Attribute with wrong description type',
|
|
'type': 'text',
|
|
'value': '',
|
|
'description': False
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute-4': {
|
|
'label': 'Attribute with wrong restrictions type',
|
|
'type': 'text',
|
|
'value': '',
|
|
'restrictions': {}
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'group': 'Metadata without label'
|
|
},
|
|
'attribute_a': {
|
|
'label': 'Some label',
|
|
'type': 'text',
|
|
'value': '',
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': None,
|
|
'group': 'Metadata with wrong label type'
|
|
},
|
|
'attribute_a': {
|
|
'label': 'Some label',
|
|
'type': 'text',
|
|
'value': '',
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': None,
|
|
'group': 'Metadata with wrong restriction type',
|
|
'restrictions': 'restrictions'
|
|
},
|
|
'attribute_a': {
|
|
'label': 'Some label',
|
|
'type': 'text',
|
|
'value': '',
|
|
}
|
|
}
|
|
}, {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute': {
|
|
'label': 'Missed plugin section. Wrong level nesting.',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
}, {
|
|
'extra_level': {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute-4': {
|
|
'label': 'Attribute with extra nesting level',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'uns@pported_letters=!n_attr_name*': {
|
|
'label': 'Attribute with wrong name',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
}
|
|
}, {
|
|
'uns@pported_letters=!n_section_name': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'attribute': {
|
|
'label': 'Attribute with wrong name',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
}
|
|
},
|
|
['wrong interface attributes object type']
|
|
]
|
|
|
|
for data in data_sets:
|
|
utils_mock.parse_yaml.return_value = data
|
|
self.assertRaises(errors.ValidationError,
|
|
self.validator.check_node_attributes_schema)
|
|
|
|
@mock.patch('fuel_plugin_builder.validators.base.utils')
|
|
def test_check_node_attributes_schema_validation_passed(self, utils_mock):
|
|
data_sets = [
|
|
{
|
|
'plugin_section': {
|
|
'metadata': {
|
|
'label': 'Some label'
|
|
},
|
|
'123': {
|
|
'label': 'Attribute with min required fields',
|
|
'type': 'text',
|
|
'value': ''
|
|
}
|
|
},
|
|
'plugin_section123': {
|
|
'Attribute_1': {
|
|
'label': 'Attribute with restrictions & complex value',
|
|
'description': 'Some attribute description',
|
|
'type': 'text',
|
|
'value': {'key1': ['val_1', 'val_2']},
|
|
'restrictions': [
|
|
{
|
|
'condition': 'false',
|
|
'action': 'disable'
|
|
}
|
|
]
|
|
},
|
|
'attribute-2': {
|
|
'label': 'Attribute with additional fields',
|
|
'type': 'number',
|
|
'description': 'Some attribute description',
|
|
'value': 10,
|
|
'min': 0
|
|
},
|
|
'metadata': {
|
|
'label': 'Metadata with extra field & restrictions',
|
|
'restrictions': [
|
|
{
|
|
'condition': 'false',
|
|
'action': 'disable'
|
|
}
|
|
],
|
|
'group': 'group A'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
|
|
for data in data_sets:
|
|
utils_mock.parse_yaml.return_value = data
|
|
self.validator.check_node_attributes_schema()
|