diff options
Diffstat (limited to 'ice_validator/tests/test_environment_file_parameters.py')
-rw-r--r-- | ice_validator/tests/test_environment_file_parameters.py | 621 |
1 files changed, 621 insertions, 0 deletions
diff --git a/ice_validator/tests/test_environment_file_parameters.py b/ice_validator/tests/test_environment_file_parameters.py new file mode 100644 index 0000000..547ab5b --- /dev/null +++ b/ice_validator/tests/test_environment_file_parameters.py @@ -0,0 +1,621 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software 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. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# 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. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# + +""" environment file structure +""" +import re +import pytest + +from .helpers import validates, get_environment_pair + + +VERSION = '1.0.0' + +# pylint: disable=invalid-name + + +def check_parameter_exists(pattern, parameters): + if not parameters: + return False + + for param in parameters: + if pattern.search(param): + return True + + return False + + +def check_param_in_env_file(environment_pair, param, DESIRED): + + if not environment_pair: + pytest.skip("No heat/env pair could be identified") + + env_file = environment_pair.get("eyml") + + pattern = re.compile(r'^{}$'.format(param)) + + if "parameters" not in env_file: + pytest.skip("No parameters specified in the environment file") + + return check_parameter_exists(pattern, + env_file.get("parameters", {}) + ) is not DESIRED + + +""" +This function supports this structure, deviations +may or may not work without enhancement + +resource_id: + type: <resource_type> + properties: + prop0: { get_param: parameter_0 } + prop1: # this is a list of dicts + - nested_prop_0: { get_param: parameter_1 } + - nested_prop_1: { get_param: [parameter_2, {index}] } + prop2: # this is a dict of dicts + nested_prop_0: { get_param: parameter_1 } +""" + + +def check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + resource_type_inverse=False, + nested_prop='', + exclude_resource=''): + + if not environment_pair: + pytest.skip("No heat/env pair could be identified") + + env_file = environment_pair.get("eyml") + template_file = environment_pair.get("yyml") + + if "parameters" not in env_file: + pytest.skip("No parameters specified in the environment file") + + invalid_parameters = [] + + if template_file: + for resource, resource_prop in template_file.get("resources", {}).items(): + + if exclude_resource and re.match(exclude_resource, resource): + continue + + if resource_prop.get("type") == resource_type or \ + (resource_prop.get("type") != resource_type + and resource_type_inverse): + + pattern = False + + if not resource_prop.get("properties"): + continue + + resource_parameter = resource_prop.get("properties").get(prop) + + if not resource_parameter: + continue + + if isinstance(resource_parameter, list) and nested_prop: + for param in resource_parameter: + + nested_param = param.get(nested_prop) + if not nested_param: + continue + + pattern = nested_param.get("get_param") + + if not pattern: + continue + + if isinstance(pattern, list): + pattern = pattern[0] + + elif isinstance(resource_parameter, dict): + + if nested_prop and nested_prop in resource_parameter: + resource_parameter = resource_parameter.get(nested_prop) + + pattern = resource_parameter.get("get_param") + + else: + continue + + if not pattern: + continue + + if check_param_in_env_file(environment_pair, pattern, DESIRED): + invalid_parameters.append(pattern) + + return set(invalid_parameters) + + +@validates('R-91125') +def test_nova_server_image_parameter_exists_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "image" + DESIRED = True + resource_type = "OS::Nova::Server" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type) + + assert not invalid_parameters, ("OS::Nova::Server {} parameters not" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-69431') +def test_nova_server_flavor_parameter_exists_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "flavor" + DESIRED = True + resource_type = "OS::Nova::Server" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type) + + assert not invalid_parameters, ("OS::Nova::Server {} parameters not" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-22838') +def test_nova_server_name_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "name" + DESIRED = False + resource_type = "OS::Nova::Server" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type) + + assert not invalid_parameters, ("OS::Nova::Server {} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-59568') +def test_nova_server_az_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "availability_zone" + DESIRED = False + resource_type = "OS::Nova::Server" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type) + + assert not invalid_parameters, ("OS::Nova::Server {} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-20856') +def test_nova_server_vnf_id_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "vnf_id" + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-72871') +def test_nova_server_vf_module_id_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "vf_module_id" + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-36542') +def test_nova_server_vnf_name_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "vnf_name" + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-80374') +def test_nova_server_vf_module_name_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "vf_module_name" + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-02691') +def test_nova_server_workload_context_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "workload_context" + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-13194') +def test_nova_server_environment_context_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "environment_context" + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-29872') +def test_nova_server_network_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "networks" + nested_prop = "network" + DESIRED = False + resource_type = "OS::Nova::Server" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + nested_prop=nested_prop) + + assert not invalid_parameters, ("{} {} parameters" + " found in {} environment file {}" + .format(resource_type, + nested_prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-39841', + 'R-87123', + 'R-28795', + 'R-97201', + 'R-62590', + 'R-93496', + 'R-98905', + 'R-93030', + 'R-90206', + 'R-98569', + 'R-62590', + 'R-93496') +def test_neutron_port_fixedips_ipaddress_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "fixed_ips" + nested_prop = "ip_address" + DESIRED = False + resource_type = "OS::Neutron::Port" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + nested_prop=nested_prop) + + assert not invalid_parameters, ("{} {} parameters" + " found in {} environment file {}" + .format(resource_type, + nested_prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-83677', + 'R-80829', + 'R-69634', + 'R-22288') +def test_neutron_port_fixedips_subnet_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "fixed_ips" + nested_prop = "subnet_id" + DESIRED = False + resource_type = "OS::Neutron::Port" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + nested_prop=nested_prop) + + assert not invalid_parameters, ("{} {} parameters" + " found in {} environment file {}" + .format(resource_type, + nested_prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-83412', + 'R-83418') +def test_neutron_port_aap_ip_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "allowed_address_pairs" + nested_prop = "ip_address" + DESIRED = False + resource_type = "OS::Neutron::Port" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + nested_prop=nested_prop) + + assert not invalid_parameters, ("{} {} parameters" + " found in {} environment file {}" + .format(resource_type, + nested_prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-99812') +def test_non_nova_server_name_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "name" + DESIRED = False + resource_type = "OS::Nova::Server" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + resource_type_inverse=True) + + assert not invalid_parameters, ("non-{} {} parameters" + " found in {} environment file {}" + .format(resource_type, + prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-92193') +def test_network_fqdn_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = r'^(.+?)_net_fqdn$' + DESIRED = False + + invalid_parameters = check_param_in_env_file(environment_pair, + prop, + DESIRED) + + assert not invalid_parameters, ("{} parameters" + " found in {} environment file {}" + .format(prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-76682') +def test_contrail_route_prefixes_parameter_doesnt_exist_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "interface_route_table_routes" + nested_prop = "interface_route_table_routes_route" + DESIRED = False + resource_type = "OS::ContrailV2::InterfaceRouteTable" + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + nested_prop=nested_prop) + + assert not invalid_parameters, ("{} {} parameters" + " found in {} environment file {}" + .format(resource_type, + nested_prop, + environment_pair.get("name"), + invalid_parameters)) + + +@validates('R-50011') +def test_heat_rg_count_parameter_exists_in_environment_file(heat_template): + + if pytest.config.getoption("validation_profile") == "heat_only": + pytest.skip("skipping test because validation profile is heat only") + + environment_pair = get_environment_pair(heat_template) + + prop = "count" + DESIRED = True + resource_type = "OS::Heat::ResourceGroup" + exclude_resource = re.compile(r'^(.+?)_subint_(.+?)_port_(.+?)_subinterfaces$') + + invalid_parameters = check_resource_parameter(environment_pair, + prop, + DESIRED, + resource_type, + exclude_resource=exclude_resource) + + assert not invalid_parameters, ("{} {} parameters not" + " found in {} environment file {}" + .format(resource_type, + prop, + environment_pair.get("name"), + invalid_parameters)) |