From 48a07b6942d3956666d30947372653feb702fdae Mon Sep 17 00:00:00 2001 From: "stark, steven" Date: Mon, 28 Jan 2019 14:59:01 -0800 Subject: [PATCH] [VVP] stand alone tool, script updates 1) Validation script updates: Various bug fixes and script enhancements New tests for: R-18683 R-94669 R-304011 R-01455 R-86476 R-708564 R-85734 R-18683 R-94669 R-304011 R-01455 R-86476 R-86476 R-589037 Removed tests for: R-75202 R-62954 R-22441 R-49177 R-16576 R-86237 R-44491 R-70757 R-01896 R-26124 2) Stand Alone tool introduced 3) Added optional "categories" capability Change-Id: I193cd5c267750791d97b350e91fc36faa72d8d5f Issue-ID: VVP-143 Signed-off-by: stark, steven --- README.rst | 22 +- .../no_unused_param.env => app_tests/__init__.py} | 8 +- .../no_unused_param.yaml => app_tests/test_app.py} | 37 +- ice_validator/app_tests/test_app_config.py | 143 ++++ .../vvp-config.yaml} | 40 +- ice_validator/heat_requirements.json | 70 +- ice_validator/make_exe.bat | 1 + ice_validator/tests/conftest.py | 160 +++-- .../fail/fail.yaml | 40 ++ .../pass/pass.yaml | 40 ++ .../fail/fail.env | 40 ++ .../fail/fail.yaml | 40 ++ .../pass/pass.env | 40 ++ .../pass/pass.yaml | 40 ++ .../fail/STARKDB-nested.yaml | 103 ++- .../test_environment_file_parameters/fail/fail.env | 40 ++ .../fail/fail.yaml | 40 ++ .../pass/STARKDB-nested.yaml | 40 ++ .../test_environment_file_parameters/pass/pass.env | 46 +- .../pass/pass.yaml | 40 ++ .../fail/parent.yaml | 55 ++ .../fail/testvm.yaml | 7 +- .../pass/test_vm.yaml | 2 +- .../test_nested_parameters/pass/heat_template.yaml | 4 +- .../fail/fail.yaml | 40 ++ .../pass/pass.yaml | 40 ++ .../fixtures/test_no_image_files/fail/pass.sh | 40 ++ .../fixtures/test_no_image_files/fail/pass.yaml | 40 ++ .../fixtures/test_no_image_files/pass/pass.sh | 40 ++ .../fixtures/test_no_image_files/pass/pass.yaml | 40 ++ .../fixtures/test_no_image_files/pass/settings | 40 ++ .../fixtures/test_non_server_name/fail/fail0.yaml | 14 +- .../fixtures/test_non_server_name/fail/fail1.yaml | 129 ---- .../fixtures/test_non_server_name/fail/fail2.yaml | 133 ---- .../fixtures/test_non_server_name/fail/fail3.yaml | 135 ---- .../fixtures/test_non_server_name/pass/pass0.yaml | 12 +- .../test_oam_address_outputs/fail/base_fail.yaml | 45 ++ .../test_oam_address_outputs/fail/module_fail.yaml | 45 ++ .../test_oam_address_outputs/pass/base_pass.yaml | 41 ++ .../test_oam_address_outputs/pass/module_pass.yaml | 41 ++ .../fail/base_mod.yaml | 40 ++ .../pass/base_mod.yaml | 40 ++ .../fail/fail.yaml | 49 ++ .../pass/pass.yaml | 49 ++ .../test_vm_class_has_unique_type/fail/fail.yaml | 69 ++ .../test_vm_class_has_unique_type/pass/pass.yaml | 75 ++ .../test_vm_role_value/fail/fail_parameter.env | 39 + .../test_vm_role_value/fail/fail_parameter.yaml | 53 ++ .../test_vm_role_value/pass/pass_hardcoded.yaml | 43 ++ .../test_vm_role_value/pass/pass_parameter.env | 39 + .../test_vm_role_value/pass/pass_parameter.yaml | 47 ++ ice_validator/tests/helpers.py | 56 +- ice_validator/tests/report.html.jinja2 | 4 +- ice_validator/tests/structures.py | 731 +++++++++++-------- .../tests/test_all_parameters_used_in_template.py | 51 +- .../tests/test_contrail_instance_ip_resource_id.py | 24 +- ice_validator/tests/test_contrail_resource_id.py | 31 +- .../tests/test_contrail_vmi_resource_id.py | 22 +- .../tests/test_contrail_vn_resource_id.py | 8 +- .../test_env_parameters_defined_in_template.py | 6 +- .../tests/test_environment_file_parameters.py | 551 ++++----------- .../tests/test_filename_is_vmtype_dot_yaml.py | 34 +- ice_validator/tests/test_nested_parameters.py | 99 +-- .../tests/test_neutron_net_resource_id.py | 11 +- ice_validator/tests/test_neutron_port_addresses.py | 26 +- ice_validator/tests/test_neutron_port_fixed_ips.py | 6 +- .../tests/test_neutron_port_internal_network.py | 3 +- ..._unused_parameters_between_env_and_templates.py | 93 --- ice_validator/tests/test_non_server_name.py | 34 +- .../tests/test_nova_server_resource_id.py | 13 +- .../tests/test_nova_servers_resource_ids.py | 8 +- ice_validator/tests/test_nova_servers_vm_types.py | 14 +- ice_validator/tests/test_oam_address_outputs.py | 65 ++ ice_validator/tests/test_port_resource_ids.py | 4 +- .../tests/test_server_and_port_vm_indices_match.py | 84 +++ .../tests/test_servers_have_required_metadata.py | 7 +- .../tests/test_vm_class_has_unique_type.py | 155 ++++ ice_validator/tests/test_vm_role_value.py | 99 +++ ice_validator/tests/test_volume_module_naming.py | 5 +- ice_validator/tests/test_volume_resource_ids.py | 5 +- ice_validator/tests/utils/vm_types.py | 20 +- .../fail/unused_param.env => version.py} | 13 +- ice_validator/vvp-config.yaml | 51 ++ ice_validator/vvp.py | 781 +++++++++++++++++++++ requirements.txt | 3 +- tox.ini | 8 +- 86 files changed, 4027 insertions(+), 1614 deletions(-) rename ice_validator/{tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.env => app_tests/__init__.py} (95%) rename ice_validator/{tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.yaml => app_tests/test_app.py} (76%) create mode 100644 ice_validator/app_tests/test_app_config.py rename ice_validator/{tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.yaml => app_tests/vvp-config.yaml} (73%) create mode 100644 ice_validator/make_exe.bat create mode 100644 ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/parent.yaml delete mode 100644 ice_validator/tests/fixtures/test_non_server_name/fail/fail1.yaml delete mode 100644 ice_validator/tests/fixtures/test_non_server_name/fail/fail2.yaml delete mode 100644 ice_validator/tests/fixtures/test_non_server_name/fail/fail3.yaml create mode 100644 ice_validator/tests/fixtures/test_oam_address_outputs/fail/base_fail.yaml create mode 100644 ice_validator/tests/fixtures/test_oam_address_outputs/fail/module_fail.yaml create mode 100644 ice_validator/tests/fixtures/test_oam_address_outputs/pass/base_pass.yaml create mode 100644 ice_validator/tests/fixtures/test_oam_address_outputs/pass/module_pass.yaml create mode 100644 ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/fail/fail.yaml create mode 100644 ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/pass/pass.yaml create mode 100644 ice_validator/tests/fixtures/test_vm_class_has_unique_type/fail/fail.yaml create mode 100644 ice_validator/tests/fixtures/test_vm_class_has_unique_type/pass/pass.yaml create mode 100644 ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.env create mode 100644 ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.yaml create mode 100644 ice_validator/tests/fixtures/test_vm_role_value/pass/pass_hardcoded.yaml create mode 100644 ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.env create mode 100644 ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.yaml delete mode 100644 ice_validator/tests/test_no_unused_parameters_between_env_and_templates.py create mode 100644 ice_validator/tests/test_oam_address_outputs.py create mode 100644 ice_validator/tests/test_server_and_port_vm_indices_match.py create mode 100644 ice_validator/tests/test_vm_class_has_unique_type.py create mode 100644 ice_validator/tests/test_vm_role_value.py rename ice_validator/{tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.env => version.py} (91%) create mode 100644 ice_validator/vvp-config.yaml create mode 100644 ice_validator/vvp.py diff --git a/README.rst b/README.rst index 87348ea..397285d 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,6 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 -.. Copyright 2018 AT&T Intellectual Property. All rights reserved. +.. Copyright 2019 AT&T Intellectual Property. All rights reserved. Manual Heat Template Validation =============================== @@ -239,8 +239,8 @@ such as the ``yaml_file``, the parameter the test was checking, etc... If the assert statement fails, the failure is collected by ``pytest``, and the associated requirements and error_message are included in the final report. -Optional: Pytest Markers and Validation Profiles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Optional: Pytest Markers and Validation Categories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The VVP test suite has the concept of a ``base`` test. These are used as sanity tests and are executed before the other tests, and if they fail the @@ -255,14 +255,14 @@ test like this: @validates("R-123456") def test_my_new_requirement(): -The VVP test suite also has the concept of a ``validation profile`` to -define what set of tests to execute. The way it works is by using ``pytest`` -markers. +The VVP test suite also has the concept of a ``category`` to +define what additional set of optional tests to execute. The way it works +is by using ``categories`` decorator. -By default, all ``base`` tests and non-marked tests are executed. If you want -an additional profile to run, pass the command line argument: +By default, all ``base`` tests and tests with no category are executed. +If you want an additional category to run, pass the command line argument: -``--validation-profile=`` +``--category=`` This will execute all ``base`` tests, non-marked tests, and tests marked like the following: @@ -271,12 +271,12 @@ and tests marked like the following: import pytest - @pytest.mark. # this is an additional pytest marker + @categories("") # substitue with the category name @validates("R-123456") def test_my_new_requirement(): This should be used sparingly, and in practice consider reviewing a requirement -with the VNF Requirements team before adding a test to a validation profile. +with the VNF Requirements team before adding a test to a category. Self-Test Suite ~~~~~~~~~~~~~~~ diff --git a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.env b/ice_validator/app_tests/__init__.py similarity index 95% rename from ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.env rename to ice_validator/app_tests/__init__.py index 9477fac..4a18fb6 100644 --- a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.env +++ b/ice_validator/app_tests/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf8 -*- -# ============LICENSE_START======================================================= +# ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== # Copyright © 2017 AT&T Intellectual Property. All rights reserved. @@ -37,9 +37,3 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # ---- -parameters: - out: 2 - res: 3 - indexed: 4 - indx: 1 \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.yaml b/ice_validator/app_tests/test_app.py similarity index 76% rename from ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.yaml rename to ice_validator/app_tests/test_app.py index dc48c50..89798a5 100644 --- a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/pass/no_unused_param.yaml +++ b/ice_validator/app_tests/test_app.py @@ -1,5 +1,5 @@ # -*- coding: utf8 -*- -# ============LICENSE_START======================================================= +# ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== # Copyright © 2017 AT&T Intellectual Property. All rights reserved. @@ -37,29 +37,16 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # ---- -parameters: - out: - type: string - description: test for output - res: - type: string - description: test for resources - indexed: - type: comma_delimited_list - description: test for indexed param - indx: - type: number - description: Index of the current instance -resources: - test: - type: abc - properties: - test_res: {get_param: res} - test_ind_param: { get_param: [ indexed, { get_param: indx } ] } +from threading import Thread -outputs: - test_out: - description: test getting output param - value: {get_param: out} \ No newline at end of file +from vvp import ValidatorApp, VERSION + + +def test_app_starts(): + app = ValidatorApp() + assert "VNF Validation Tool" in app.title + assert VERSION in app.title + app_thread = Thread(target=app.start, args=()) + app_thread.daemon = True + app.config.command_queue.put("SHUTDOWN") diff --git a/ice_validator/app_tests/test_app_config.py b/ice_validator/app_tests/test_app_config.py new file mode 100644 index 0000000..d9a8567 --- /dev/null +++ b/ice_validator/app_tests/test_app_config.py @@ -0,0 +1,143 @@ +# -*- 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. +# + +from io import StringIO + +import pytest +import yaml + +import vvp + +DEFAULT_CONFIG = """ +ui: + app-name: VNF Validation Tool +categories: + - name: Environment File Compliance. (Required to Onboard) + category: environment_file + description: + Checks certain parameters are excluded from the .env file, per HOT Requirements. + Required for ASDC onboarding, not needed for manual Openstack testing. +settings: + polling-freqency: 1000 + default-verbosity: Standard +""" + + +# noinspection PyShadowingNames +@pytest.fixture(scope="module") +def config(): + return vvp.Config(yaml.load(StringIO(DEFAULT_CONFIG))) + + +def test_app_name(config): + assert "VNF Validation Tool" in config.app_name + assert vvp.VERSION in config.app_name + + +def test_categories_names_length(config): + names = config.category_names + assert len(names) == 1 + assert names[0] == "Environment File Compliance. (Required to Onboard)" + + +def test_polling_frequency(config): + assert config.polling_frequency == 1000 + + +def test_get_category_when_other(config): + assert ( + config.get_category("Environment File Compliance. (Required to Onboard)") + == "environment_file" + ) + + +def test_default_verbosity(config): + assert config.default_verbosity(vvp.ValidatorApp.VERBOSITY_LEVELS) == "More (-vv)" + + +def test_queues(config): + assert config.log_queue.empty(), "Log should start empty" + config.log_file.write("Test") + assert config.log_queue.get() == "Test" + + assert config.status_queue.empty(), "status should start empty" + config.status_queue.put((True, None)) + assert config.status_queue.get() == (True, None) + + +MISSING_CATEGORY_FIELD = """ +ui: + app-name: VNF Validation Tool +categories: + - description: | + Runs all default validations that apply to all VNF packages + regardless of deployment environment +settings: + polling-freqency: 1000 +""" + + +def test_missing_category_fields(): + settings = yaml.load(StringIO(MISSING_CATEGORY_FIELD)) + with pytest.raises(RuntimeError) as e: + vvp.Config(settings) + assert "Missing: name" in str(e) + + +def test_default_output_format(config): + assert config.default_report_format == "HTML" + + +def test_output_formats(config): + for format in ["CSV", "HTML", "Excel"]: + assert format in config.report_formats + + +def test_category_names(config): + assert "Environment File Compliance. (Required to Onboard)" in config.category_names + + +def test_default_input_format(config): + assert "Directory (Uncompressed)" == config.default_input_format + + +def test_input_formats(config): + assert "Directory (Uncompressed)" in config.input_formats + assert "ZIP File" in config.input_formats diff --git a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.yaml b/ice_validator/app_tests/vvp-config.yaml similarity index 73% rename from ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.yaml rename to ice_validator/app_tests/vvp-config.yaml index 51cacba..147eae0 100644 --- a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.yaml +++ b/ice_validator/app_tests/vvp-config.yaml @@ -1,5 +1,5 @@ # -*- coding: utf8 -*- -# ============LICENSE_START======================================================= +# ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== # Copyright © 2017 AT&T Intellectual Property. All rights reserved. @@ -37,31 +37,15 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # ---- -parameters: - out: - type: string - description: test for output - res: - type: string - description: test for resources - indexed: - type: comma_delimited_list - description: test for indexed param - indx: - type: number - description: Index of the current instance - unused_yaml: - type: number - description: unused param in yaml file -resources: - test: - type: abc - properties: - test_res: {get_param: res} - test_ind_param: { get_param: [ indexed, { get_param: indx } ] } -outputs: - test_out: - description: test getting output param - value: {get_param: out} \ No newline at end of file +ui: + app-name: VNF Validation Tool +categories: + - name: Environment File Compliance. (Required to Onboard) + category: environment_file + description: + Checks certain parameters are excluded from the .env file, per HOT Requirements. + Required for ASDC onboarding, not needed for manual Openstack testing. +settings: + polling-freqency: 1000 + default-verbosity: Standard diff --git a/ice_validator/heat_requirements.json b/ice_validator/heat_requirements.json index 5ddc4f5..dd8da5f 100644 --- a/ice_validator/heat_requirements.json +++ b/ice_validator/heat_requirements.json @@ -1,5 +1,5 @@ { - "created": "2018-12-19T19:29:53.158345", + "created": "2019-01-25T23:15:47.976656", "current_version": "dublin", "project": "", "versions": { @@ -45910,7 +45910,7 @@ "needs_amount": 789 }, "dublin": { - "created": "2018-12-19T19:29:53.158326", + "created": "2019-01-25T23:15:47.976584", "needs": { "R-00011": { "description": "A VNF's Heat Orchestration Template's parameter defined\nin a nested YAML file\n**SHOULD NOT** have a parameter constraint defined.", @@ -47308,7 +47308,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-05257": { "description": "A VNF's Heat Orchestration Template's **MUST NOT**\ncontain the Resource ``OS::Neutron::FloatingIP``.", @@ -48259,7 +48259,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-11200": { "description": "A VNF's Cinder Volume Module, when it exists, **MUST** be 1:1\nwith a Base module or Incremental module.", @@ -50826,7 +50826,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-21511": { "description": "A VNF's Heat Orchestration Template's use of ``{network-role}``\nin all Resource IDs **MUST** be the same case.", @@ -50857,7 +50857,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-21558": { "description": "The VNF **SHOULD** use intelligent routing by having knowledge\nof multiple downstream/upstream endpoints that are exposed to it, to\nensure there is no dependency on external services (such as load balancers)\nto switch to alternate endpoints.", @@ -56834,7 +56834,7 @@ "type_name": "Requirement", "updated": "", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-43740": { "description": "VNF's Heat Orchestration Template's Resource **MAY** declare the\nattribute ``deletion_policy:``.", @@ -57392,7 +57392,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-45719": { "description": "The VNF **MUST**, if not integrated with the Operator's Identity and Access\nManagement system, or enforce a configurable \"terminate idle sessions\"\npolicy by terminating the session after a configurable period of inactivity.", @@ -57619,7 +57619,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-465236": { "description": "The VNF **SHOULD** provide the capability of maintaining the integrity of\nits static files using a cryptographic method.", @@ -58493,7 +58493,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-48917": { "description": "The VNF **MUST** monitor for and alert on (both sender and\nreceiver) errant, running longer than expected and missing file transfers,\nso as to minimize the impact due to file transfer errors.", @@ -58558,7 +58558,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-49036": { "description": "The xNF **SHOULD** conform its YANG model to RFC 7277,\n\"A YANG Data Model for IP Management\".", @@ -59002,7 +59002,7 @@ "introduced": "", "is_need": true, "is_part": false, - "keyword": "MAY", + "keyword": "MUST", "links": [], "notes": "", "parts": {}, @@ -59249,7 +59249,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-52499": { "description": "The VNF **MUST** meet their own resiliency goals and not rely\non the Network Cloud.", @@ -59838,7 +59838,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-54520": { "description": "The VNF **MUST** log successful and unsuccessful authentication\nattempts, e.g., authentication associated with a transaction,\nauthentication to create a session, authentication to assume elevated\nprivilege.", @@ -60224,7 +60224,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-56385": { "description": "The xNF **MUST** support APPC ``Audit`` command.", @@ -60577,7 +60577,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-57617": { "description": "The VNF **MUST** include the field \"success/failure\" in the\nSecurity alarms (where applicable and technically feasible).", @@ -60867,7 +60867,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-58670": { "description": "The VNF's Heat Orchestration Template's Resource ``OS::Nova::Server``\nproperty\n``image`` parameter name **MUST** follow the naming convention\n``{vm-type}_image_name``.", @@ -61093,7 +61093,7 @@ "type_name": "Requirement", "updated": "", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-59568": { "description": "The VNF's Heat Orchestration Template's Resource ``OS::Nova::Server``\nproperty\n``availability_zone`` parameter **MUST NOT** be enumerated in the Heat\nOrchestration\nTemplate's Environment File.", @@ -61354,7 +61354,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-61354": { "description": "The VNF **MUST** provide a mechanism (e.g., access control list) to\npermit and/or restrict access to services on the VNF by source,\ndestination, protocol, and/or port.", @@ -62574,7 +62574,7 @@ "introduced": "casablanca", "is_need": true, "is_part": false, - "keyword": "MUST", + "keyword": "MAY", "links": [], "notes": "", "parts": {}, @@ -62691,7 +62691,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-67895": { "description": "The VNFD provided by VNF vendor may use the below described TOSCA\ncapabilities. An on-boarding entity (ONAP SDC) **MUST** support them.\n\n **tosca.capabilities.nfv.VirtualBindable**\n\n A node type that includes the VirtualBindable capability indicates\n that it can be pointed by **tosca.relationships.nfv.VirtualBindsTo**\n relationship type.\n\n **tosca.capabilities.nfv.VirtualLinkable**\n\n A node type that includes the VirtualLinkable capability indicates\n that it can be pointed by **tosca.relationships.nfv.VirtualLinksTo**\n relationship.\n\n **tosca.capabilities.nfv.ExtVirtualLinkable**\n\n A node type that includes the ExtVirtualLinkable capability\n indicates that it can be pointed by\n **tosca.relationships.nfv.VirtualLinksTo** relationship.\n\n **Note**: This capability type is used in Casablanca how it does\n not exist in the last SOL001 draft\n\n **tosca.capabilities.nfv.VirtualCompute** and\n **tosca.capabilities.nfv.VirtualStorage** includes flavours of VDU", @@ -62768,7 +62768,7 @@ "introduced": "", "is_need": true, "is_part": false, - "keyword": "SHOULD", + "keyword": "MUST", "links": [], "notes": "", "parts": {}, @@ -63082,7 +63082,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-69431": { "description": "The VNF's Heat Orchestration Template's Resource ``OS::Nova::Server``\nproperty\n``flavor`` parameter **MUST** be enumerated in the Heat Orchestration\nTemplate's Environment File and a value **MUST** be assigned.", @@ -63178,7 +63178,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-69610": { "description": "The VNF **MUST** provide the capability of using X.509 certificates\nissued by an external Certificate Authority.", @@ -63665,7 +63665,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-71152": { "description": "The VNF's Heat Orchestration Template's Resource ``OS::Nova::Server``\nproperty\n``image`` parameter **MUST** be declared as type: ``string``.", @@ -65906,7 +65906,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-82134": { "description": "A VNF's Heat Orchestration Template's ``OS::Nova::Server`` resource property\n``metadata`` key/value pair ``vf_module_id`` parameter **MUST**\nbe declared as ``vf_module_id`` and the parameter **MUST**\nbe defined as type: ``string``.", @@ -66096,7 +66096,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-82732": { "description": "A VNF Heat Orchestration Template's Cinder Volume Module **MUST**\nbe named identical to the base or incremental module it is supporting with\n``_volume`` appended.", @@ -66389,7 +66389,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-83790": { "description": "The xNF **MUST** implement the ``:validate`` capability.", @@ -66617,7 +66617,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-84366": { "description": "The xNF Package **MUST** include documentation describing\nxNF Functional APIs that are utilized to build network and\napplication services. This document describes the externally exposed\nfunctional inputs and outputs for the xNF, including interface\nformat and protocols supported.", @@ -68002,7 +68002,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-88536": { "description": "A VNF's Heat Orchestration Template's OS::Nova::Server\nResource **SHOULD** contain the metadata map value parameter\n'environment_context'.", @@ -69763,7 +69763,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-96554": { "description": "The xNF **MUST** implement the protocol operation:\n``unlock(target)`` - Unlock the configuration data store target.", @@ -69860,7 +69860,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-97102": { "description": "The VNF Package **MUST** include VM requirements via a Heat\ntemplate that provides the necessary data for VM specifications\nfor all VNF components - for hypervisor, CPU, memory, storage.", @@ -70155,7 +70155,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-978752": { "description": "The xNF providers **MUST** provide the Service Provider the following\nartifacts to support the delivery of high-volume xNF telemetry to\nDCAE via GPB over TLS/TCP:\n\n * A valid VES Event .proto definition file, to be used validate and\n decode an event\n * A valid high volume measurement .proto definition file, to be used for\n processing high volume events\n * A supporting PM content metadata file to be used by analytics\n applications to process high volume measurement events", @@ -70251,7 +70251,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-981585": { "description": "The pnfRegistration VES event periodicity **MUST** be configurable.\n\nNote: The PNF uses the service configuration request as a semaphore to\nstop sending the pnfRegistration sent. See the requirement PNP-5360\nrequirement.", @@ -70894,7 +70894,7 @@ "type_name": "Requirement", "updated": "casablanca", "validated_by": "", - "validation_mode": "static" + "validation_mode": "none" }, "R-99798": { "description": "A VNF's Heat Orchestration Template's Virtual Machine\n(i.e., ``OS::Nova::Server`` resource) **MAY** boot from an image or\n**MAY** boot from a Cinder Volume.", diff --git a/ice_validator/make_exe.bat b/ice_validator/make_exe.bat new file mode 100644 index 0000000..efd4ae8 --- /dev/null +++ b/ice_validator/make_exe.bat @@ -0,0 +1 @@ +pyinstaller --onedir vvp.spec \ No newline at end of file diff --git a/ice_validator/tests/conftest.py b/ice_validator/tests/conftest.py index 5184fb6..5621354 100644 --- a/ice_validator/tests/conftest.py +++ b/ice_validator/tests/conftest.py @@ -58,6 +58,8 @@ from more_itertools import partition import xlsxwriter from six import string_types +import version + __path__ = [os.path.dirname(os.path.abspath(__file__))] DEFAULT_OUTPUT_DIR = "{}/../output".format(__path__[0]) @@ -312,9 +314,7 @@ def pytest_runtest_makereport(item, call): msg = "!!Base Test Failure!! Halting test suite execution...\n{}".format( result.error_message ) - pytest.exit( - "{}\n{}\n{}".format(msg, result.files, result.test_case) - ) + pytest.exit("{}\n{}\n{}".format(msg, result.files, result.test_case)) def make_timestamp(): @@ -339,12 +339,17 @@ def pytest_sessionfinish(session, exitstatus): """ if not session.config.option.template_dir: return - template_path = os.path.abspath(session.config.option.template_dir[0]) - profile_name = session.config.option.validation_profile_name or "" + + if session.config.option.template_source: + template_source = session.config.option.template_source[0] + else: + template_source = os.path.abspath(session.config.option.template_dir[0]) + + categories_selected = session.config.option.test_categories or "" generate_report( get_output_dir(session.config), - template_path, - profile_name, + template_source, + categories_selected, session.config.option.report_format, ) @@ -352,33 +357,33 @@ def pytest_sessionfinish(session, exitstatus): # noinspection PyUnusedLocal def pytest_collection_modifyitems(session, config, items): """ - Selects tests based on the validation profile requested. Tests without - pytest markers will always be executed. + Selects tests based on the categories requested. Tests without + categories will always be executed. """ - allowed_marks = ["xfail", "base"] - profile = config.option.validation_profile - - for item in items: - markers = set(m.name for m in item.iter_markers()) - if not profile and markers and set(markers).isdisjoint(allowed_marks): - item.add_marker( - pytest.mark.skip( - reason="No validation profile selected. " - "Skipping tests with marks." - ) - ) - if ( - profile - and markers - and profile not in markers - and set(markers).isdisjoint(allowed_marks) - ): - item.add_marker( - pytest.mark.skip(reason="Doesn't match selection " "validation profile") - ) - + config.traceability_items = list(items) # save all items for traceability + if not config.option.self_test: + for item in items: + # checking if test belongs to a category + if hasattr(item.function, "categories"): + if config.option.test_categories: + test_categories = getattr(item.function, "categories") + passed_categories = config.option.test_categories + if not all( + category in passed_categories for category in test_categories + ): + item.add_marker( + pytest.mark.skip( + reason="Test categories do not match all the passed categories" + ) + ) + else: + item.add_marker( + pytest.mark.skip( + reason="Test belongs to a category but no categories were passed" + ) + ) items.sort( - key=lambda i: 0 if "base" in set(m.name for m in i.iter_markers()) else 1 + key=lambda item: 0 if "base" in set(m.name for m in item.iter_markers()) else 1 ) @@ -412,13 +417,13 @@ def load_resolutions_file(): return json.loads(f.read()) -def generate_report(outpath, template_path, profile_name, output_format="html"): +def generate_report(outpath, template_path, categories, output_format="html"): """ Generates the various output reports. :param outpath: destination directory for all reports :param template_path: directory containing the Heat templates validated - :param profile_name: Optional validation profile selected + :param categories: Optional categories selected :param output_format: One of "html", "excel", or "csv". Default is "html" :raises: ValueError if requested output format is unknown """ @@ -426,13 +431,13 @@ def generate_report(outpath, template_path, profile_name, output_format="html"): generate_failure_file(outpath) output_format = output_format.lower().strip() if output_format else "html" if output_format == "html": - generate_html_report(outpath, profile_name, template_path, failures) + generate_html_report(outpath, categories, template_path, failures) elif output_format == "excel": - generate_excel_report(outpath, profile_name, template_path, failures) + generate_excel_report(outpath, categories, template_path, failures) elif output_format == "json": - generate_json(outpath, template_path, profile_name) + generate_json(outpath, template_path, categories) elif output_format == "csv": - generate_csv_report(outpath, profile_name, template_path, failures) + generate_csv_report(outpath, categories, template_path, failures) else: raise ValueError("Unsupported output format: " + output_format) @@ -469,10 +474,11 @@ def generate_failure_file(outpath): write_json(data, failure_path) -def generate_csv_report(output_dir, profile_name, template_path, failures): +def generate_csv_report(output_dir, categories, template_path, failures): rows = [["Validation Failures"]] headers = [ - ("Profile Selected:", profile_name), + ("Categories Selected:", categories), + ("Tool Version:", version.VERSION), ("Report Generated At:", make_timestamp()), ("Directory Validated:", template_path), ("Checksum:", hash_directory(template_path)), @@ -523,7 +529,7 @@ def generate_csv_report(output_dir, profile_name, template_path, failures): writer.writerow(row) -def generate_excel_report(output_dir, profile_name, template_path, failures): +def generate_excel_report(output_dir, categories, template_path, failures): output_path = os.path.join(output_dir, "report.xlsx") workbook = xlsxwriter.Workbook(output_path) bold = workbook.add_format({"bold": True}) @@ -534,7 +540,8 @@ def generate_excel_report(output_dir, profile_name, template_path, failures): worksheet.write(0, 0, "Validation Failures", heading) headers = [ - ("Profile Selected:", profile_name), + ("Categories Selected:", ",".join(categories)), + ("Tool Version:", version.VERSION), ("Report Generated At:", make_timestamp()), ("Directory Validated:", template_path), ("Checksum:", hash_directory(template_path)), @@ -636,7 +643,8 @@ def aggregate_results(has_errors, outcomes, r_id=None): else: pytest.warns( "Unexpected error aggregating outcomes ({}) for requirement {}".format( - outcomes, r_id) + outcomes, r_id + ) ) return "ERROR" @@ -693,18 +701,18 @@ def collect_errors(r_id, collection_failures, test_result): r_id is None, then it collects all errors that occur on failures and results that are not mapped to requirements """ + def selector(item): if r_id: return r_id in req_ids(item) else: return not req_ids(item) - errors = (error(x) for x in chain(collection_failures, test_result) - if selector(x)) + errors = (error(x) for x in chain(collection_failures, test_result) if selector(x)) return [e for e in errors if e] -def generate_json(outpath, template_path, profile_name): +def generate_json(outpath, template_path, categories): """ Creates a JSON summary of the entire test run. """ @@ -714,7 +722,7 @@ def generate_json(outpath, template_path, profile_name): "template_directory": template_path, "timestamp": make_iso_timestamp(), "checksum": hash_directory(template_path), - "profile": profile_name, + "categories": categories, "outcome": aggregate_run_results(COLLECTION_FAILURES, ALL_RESULTS), "tests": [], "requirements": [], @@ -754,7 +762,7 @@ def generate_json(outpath, template_path, profile_name): "text": r_data["description"], "keyword": r_data["keyword"], "result": result, - "errors": collect_errors(r_id, COLLECTION_FAILURES, ALL_RESULTS) + "errors": collect_errors(r_id, COLLECTION_FAILURES, ALL_RESULTS), } ) # If there are tests that aren't mapped to a requirement, then we'll @@ -767,7 +775,7 @@ def generate_json(outpath, template_path, profile_name): "id": "Unmapped", "text": "Tests not mapped to requirements (see tests)", "result": aggregate_results(has_errors, unmapped_outcomes), - "errors": collect_errors(None, COLLECTION_FAILURES, ALL_RESULTS) + "errors": collect_errors(None, COLLECTION_FAILURES, ALL_RESULTS), } ) @@ -775,7 +783,7 @@ def generate_json(outpath, template_path, profile_name): write_json(data, report_path) -def generate_html_report(outpath, profile_name, template_path, failures): +def generate_html_report(outpath, categories, template_path, failures): reqs = load_current_requirements() resolutions = load_resolutions_file() fail_data = [] @@ -797,8 +805,9 @@ def generate_html_report(outpath, profile_name, template_path, failures): with open(j2_template_path, "r") as f: report_template = jinja2.Template(f.read()) contents = report_template.render( + version=version.VERSION, num_failures=len(failures) + len(COLLECTION_FAILURES), - profile_name=profile_name, + categories=categories, template_dir=make_href(template_path), checksum=hash_directory(template_path), timestamp=make_timestamp(), @@ -820,6 +829,13 @@ def pytest_addoption(parser): help="Directory which holds the templates for validation", ) + parser.addoption( + "--template-source", + dest="template_source", + action="append", + help="Source Directory which holds the templates for validation", + ) + parser.addoption( "--self-test", dest="self_test", @@ -827,20 +843,6 @@ def pytest_addoption(parser): help="Test the unit tests against their fixtured data", ) - parser.addoption( - "--validation-profile", - dest="validation_profile", - action="store", - help="Runs all unmarked tests plus test with a matching marker", - ) - - parser.addoption( - "--validation-profile-name", - dest="validation_profile_name", - action="store", - help="Friendly name of the validation profile used in reports", - ) - parser.addoption( "--report-format", dest="report_format", @@ -860,7 +862,14 @@ def pytest_addoption(parser): dest="output_dir", action="store", default=None, - help="Alternate " + help="Alternate ", + ) + + parser.addoption( + "--category", + dest="test_categories", + action="append", + help="optional category of test to execute", ) @@ -1040,6 +1049,21 @@ def unicode_writerow(writer, row): writer.writerow(row) +def parse_heat_requirements(reqs): + """Takes requirements and returns list of only Heat requirements""" + data = json.loads(reqs) + for key, values in list(data.items()): + if "Heat" in (values["docname"]): + if "MUST" not in (values["keyword"]): + del data[key] + else: + if "none" in (values["validation_mode"]): + del data[key] + else: + del data[key] + return data + + # noinspection PyUnusedLocal def pytest_report_collectionfinish(config, startdir, items): """Generates a simple traceability report to output/traceability.csv""" @@ -1047,7 +1071,9 @@ def pytest_report_collectionfinish(config, startdir, items): output_dir = os.path.split(traceability_path)[0] if not os.path.exists(output_dir): os.makedirs(output_dir) - requirements = load_current_requirements() + reqs = load_current_requirements() + reqs = json.dumps(reqs) + requirements = parse_heat_requirements(reqs) unmapped, mapped = partition( lambda i: hasattr(i.function, "requirement_ids"), items ) diff --git a/ice_validator/tests/fixtures/test_all_parameters_used_in_template/fail/fail.yaml b/ice_validator/tests/fixtures/test_all_parameters_used_in_template/fail/fail.yaml index 6064c91..6f65d89 100644 --- a/ice_validator/tests/fixtures/test_all_parameters_used_in_template/fail/fail.yaml +++ b/ice_validator/tests/fixtures/test_all_parameters_used_in_template/fail/fail.yaml @@ -1,3 +1,43 @@ +# -*- 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_all_parameters_used_in_template/pass/pass.yaml b/ice_validator/tests/fixtures/test_all_parameters_used_in_template/pass/pass.yaml index ee9311f..51cefa4 100644 --- a/ice_validator/tests/fixtures/test_all_parameters_used_in_template/pass/pass.yaml +++ b/ice_validator/tests/fixtures/test_all_parameters_used_in_template/pass/pass.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.env b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.env index 4ea6ee3..4d1f3a4 100644 --- a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.env +++ b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.env @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + parameters: test123: nsdafjk bad: ndfaskl \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.yaml b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.yaml index 90d0f3c..bb46456 100644 --- a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.yaml +++ b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/fail/fail.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + parameters: test123: type: string diff --git a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.env b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.env index de8d3e0..c6b67b6 100644 --- a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.env +++ b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.env @@ -1,2 +1,42 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + parameters: test123: nsdafjk \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.yaml b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.yaml index 90d0f3c..bb46456 100644 --- a/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.yaml +++ b/ice_validator/tests/fixtures/test_env_parameters_defined_in_template/pass/pass.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + parameters: test123: type: string diff --git a/ice_validator/tests/fixtures/test_environment_file_parameters/fail/STARKDB-nested.yaml b/ice_validator/tests/fixtures/test_environment_file_parameters/fail/STARKDB-nested.yaml index 97bc4cf..0f15cfa 100644 --- a/ice_validator/tests/fixtures/test_environment_file_parameters/fail/STARKDB-nested.yaml +++ b/ice_validator/tests/fixtures/test_environment_file_parameters/fail/STARKDB-nested.yaml @@ -1,9 +1,58 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa parameters: + my_nested_parameter: + type: number + description: sdfnklafd + STARKDB_image_name: + type: number + description: sdfnklafd + STARKDB_name: + type: number + description: sdfnklafd my_nested_parameter: type: number description: sdfnklafd @@ -12,10 +61,62 @@ parameters: resources: + STARKDB_server_2: + type: OS::Nova::Server + properties: + image: { get_param: STARKDB_image_name } + flavor: { get_param: STARKDB_flavor_dvdfg } + name: { get_param: STARKDB_name } + availability_zone: { get_param: availability_zone_0 } + my_nested_resource2: type: test properties: - my_nested_parameter: {get_param: my_nested_parameter} + name: { get_param: asfasf } + + STARKDB_2_crazy_port_2: + type: OS::Neutron::Port + properties: + network: { get_param: crazy_net_id } + fixed_ips: + - subnet: { get_param: crazy_subnet_id } + - ip_address: { get_param: STARKDB_crazy_ip_0 } + allowed_address_pairs: [ { "ip_address": {get_param: + STARKDB_crazy_floating_ip}}] + + int_private_net_id: + type: OS::Neutron::Net + properties: + name: { get_param: int_priv_net_id } + + STARKDB_0_int_priv_port_0: + type: OS::Neutron::Port + properties: + network: { get_resource: int_private_net_id } + fixed_ips: + - subnet: { get_resource: int_priv_subnet } + - ip_address: { get_param: STARKDB_int_private_v6_ips } + + myrouteprefix: + type: OS::ContrailV2::InterfaceRouteTable + properties: + name: + str_replace: + template: VNF_NAME_interface_route_table + params: + VNF_NAME: { get_param: vnf_name } + interface_route_table_routes: + interface_route_table_routes_route: { get_param: fw_oam_route_prefixes } + test: safd + + stark_rg: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: stark_rg_count } + resource_def: + type: STARKDB-nested.yaml + properties: + my_nested_parameter: 4 outputs: test_value: diff --git a/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.env b/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.env index 9187b10..19ab746 100644 --- a/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.env +++ b/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.env @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + parameters: fw_oam_route_prefixes: nsaflj diff --git a/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.yaml b/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.yaml index d84cc1f..efe09bb 100644 --- a/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.yaml +++ b/ice_validator/tests/fixtures/test_environment_file_parameters/fail/fail.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_environment_file_parameters/pass/STARKDB-nested.yaml b/ice_validator/tests/fixtures/test_environment_file_parameters/pass/STARKDB-nested.yaml index 97bc4cf..89077ac 100644 --- a/ice_validator/tests/fixtures/test_environment_file_parameters/pass/STARKDB-nested.yaml +++ b/ice_validator/tests/fixtures/test_environment_file_parameters/pass/STARKDB-nested.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.env b/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.env index 46d2728..3879ffa 100644 --- a/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.env +++ b/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.env @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + parameters: #fw_oam_route_prefixes: nsaflj @@ -20,7 +60,7 @@ parameters: #TESTDB_name: bghbhjb - TESTDB_avail_hosts: test + #TESTDB_avail_hosts: test TESTDB_image_name: sadfadf @@ -30,7 +70,7 @@ parameters: param_X: sadnfklsadnfl - priv_net_id: 123214 + #priv_net_id: 123214 #priv_sub2net_id: 123123 @@ -48,7 +88,7 @@ parameters: #STARKDB_crazy_floating_ip: safd - crazy_net_id: safd + #crazy_net_id: safd #crazy_subnet_id: asfd diff --git a/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.yaml b/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.yaml index 42f23ee..8099410 100644 --- a/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.yaml +++ b/ice_validator/tests/fixtures/test_environment_file_parameters/pass/pass.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/parent.yaml b/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/parent.yaml new file mode 100644 index 0000000..d1e1b9c --- /dev/null +++ b/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/parent.yaml @@ -0,0 +1,55 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + +# VERSION = '1.0.0' + +--- +resources: + testvm_server_0: + type: OS::Nova::Server + properties: + name: { get_param: testvm_name_0 } + flavor: { get_param: testvm_flavor_name} + image: { get_param: testvm_image_name} + + nested_resource: + type: testvm.yaml + properties: + param1: abc diff --git a/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/testvm.yaml b/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/testvm.yaml index 87c54e2..ffb4e39 100644 --- a/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/testvm.yaml +++ b/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/fail/testvm.yaml @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -42,10 +42,9 @@ --- resources: - testvm_server_0: + testvm_server_1: type: OS::Nova::Server properties: name: { get_param: testvm_name_0 } flavor: { get_param: testvm_flavor_name} - image: { get_param: testvm_image_name} - + image: { get_param: testvm_image_name} \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/pass/test_vm.yaml b/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/pass/test_vm.yaml index 87c54e2..e54ad54 100644 --- a/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/pass/test_vm.yaml +++ b/ice_validator/tests/fixtures/test_filename_is_vmtype_dot_yaml/pass/test_vm.yaml @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed diff --git a/ice_validator/tests/fixtures/test_nested_parameters/pass/heat_template.yaml b/ice_validator/tests/fixtures/test_nested_parameters/pass/heat_template.yaml index bb9585b..fe5aa59 100644 --- a/ice_validator/tests/fixtures/test_nested_parameters/pass/heat_template.yaml +++ b/ice_validator/tests/fixtures/test_nested_parameters/pass/heat_template.yaml @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -53,7 +53,7 @@ resources: server_0: type: nested_template_1.yaml properties: - name: { get_param: server_name_0 } + name: { get_param: name } my_resource_group_1: type: OS::Heat::ResourceGroup properties: diff --git a/ice_validator/tests/fixtures/test_neutron_port_network_parameter/fail/fail.yaml b/ice_validator/tests/fixtures/test_neutron_port_network_parameter/fail/fail.yaml index 8beb00a..8fa5a80 100644 --- a/ice_validator/tests/fixtures/test_neutron_port_network_parameter/fail/fail.yaml +++ b/ice_validator/tests/fixtures/test_neutron_port_network_parameter/fail/fail.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_neutron_port_network_parameter/pass/pass.yaml b/ice_validator/tests/fixtures/test_neutron_port_network_parameter/pass/pass.yaml index 86da04e..88f5502 100644 --- a/ice_validator/tests/fixtures/test_neutron_port_network_parameter/pass/pass.yaml +++ b/ice_validator/tests/fixtures/test_neutron_port_network_parameter/pass/pass.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_no_image_files/fail/pass.sh b/ice_validator/tests/fixtures/test_no_image_files/fail/pass.sh index 739dc11..1227b1f 100644 --- a/ice_validator/tests/fixtures/test_no_image_files/fail/pass.sh +++ b/ice_validator/tests/fixtures/test_no_image_files/fail/pass.sh @@ -1 +1,41 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + echo "test" \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_no_image_files/fail/pass.yaml b/ice_validator/tests/fixtures/test_no_image_files/fail/pass.yaml index 86da04e..88f5502 100644 --- a/ice_validator/tests/fixtures/test_no_image_files/fail/pass.yaml +++ b/ice_validator/tests/fixtures/test_no_image_files/fail/pass.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_no_image_files/pass/pass.sh b/ice_validator/tests/fixtures/test_no_image_files/pass/pass.sh index 739dc11..1227b1f 100644 --- a/ice_validator/tests/fixtures/test_no_image_files/pass/pass.sh +++ b/ice_validator/tests/fixtures/test_no_image_files/pass/pass.sh @@ -1 +1,41 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + echo "test" \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_no_image_files/pass/pass.yaml b/ice_validator/tests/fixtures/test_no_image_files/pass/pass.yaml index 86da04e..88f5502 100644 --- a/ice_validator/tests/fixtures/test_no_image_files/pass/pass.yaml +++ b/ice_validator/tests/fixtures/test_no_image_files/pass/pass.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2015-04-30 description: fdsafsfsa diff --git a/ice_validator/tests/fixtures/test_no_image_files/pass/settings b/ice_validator/tests/fixtures/test_no_image_files/pass/settings index ad78c6f..736231c 100644 --- a/ice_validator/tests/fixtures/test_no_image_files/pass/settings +++ b/ice_validator/tests/fixtures/test_no_image_files/pass/settings @@ -1 +1,41 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + test=one \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_non_server_name/fail/fail0.yaml b/ice_validator/tests/fixtures/test_non_server_name/fail/fail0.yaml index 50acd30..dc04ca7 100644 --- a/ice_validator/tests/fixtures/test_non_server_name/fail/fail0.yaml +++ b/ice_validator/tests/fixtures/test_non_server_name/fail/fail0.yaml @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -56,7 +56,11 @@ resources: vm_typeX_0_bialy_port_2: type: OS::Neutron::Port properties: - name: mynameistrouble + name: + str_replace: + template: mynameisstilltrouble + param: + still: safnlk network: { get_param: int_intranet_net_name } fixed_ips: - ip_address: { get_param: lb_1_int_intranet_floating_ip } @@ -75,7 +79,10 @@ resources: type: OS::Neutron::Port properties: name: - str_replace: mynameisstilltrouble + str_replace: + template: mynameisstilltrouble + param: + still: safnlk network: { get_param: int_intranet_net_id } fixed_ips: - ip_address: { get_param: lb_2_int_intranet_floating_v6_ip } @@ -93,6 +100,7 @@ resources: vm_typeX_2_bialy_port_2: type: OS::Neutron::Port properties: + name: ansdjlf network: { get_param: extnet_net_name } fixed_ips: - ip_address: { get_param: lb_1_extnet_floating_ip } diff --git a/ice_validator/tests/fixtures/test_non_server_name/fail/fail1.yaml b/ice_validator/tests/fixtures/test_non_server_name/fail/fail1.yaml deleted file mode 100644 index daa2045..0000000 --- a/ice_validator/tests/fixtures/test_non_server_name/fail/fail1.yaml +++ /dev/null @@ -1,129 +0,0 @@ -# -*- 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. -# -# VERSION: '1.0.0' - ---- -parameters: - - vm_typeX_bialy_vlan_filter: - type: comma_delimited_list - vm_typeX_bialy_public_vlans: - type: comma_delimited_list - vm_typeX_bialy_private_vlans: - type: comma_delimited_list - vm_typeX_bialy_guest_vlans: - type: comma_delimited_list - -resources: - - vm_typeX_0_bialy_port_2: - type: OS::Neutron::Port - properties: - name: - str_replace: - template: - params: mynameisstilltrouble - network: { get_param: int_intranet_net_name } - fixed_ips: - - ip_address: { get_param: lb_1_int_intranet_floating_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Trunk - - vm_typeX_1_bialy_port_2: - type: OS::Neutron::Port - properties: - name: - str_replace: {} - network: { get_param: int_intranet_net_id } - fixed_ips: - - ip_address: { get_param: lb_2_int_intranet_floating_v6_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Non_Trunk - - vm_typeX_2_bialy_port_2: - type: OS::Neutron::Port - properties: - network: { get_param: extnet_net_name } - fixed_ips: - - ip_address: { get_param: lb_1_extnet_floating_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: OVS - - vm_typeX_3_bialy_port_2: - type: OS::Neutron::Port - properties: - network: { get_param: extnet_net_id } - fixed_ips: - - ip_address: { get_param: lb_2_extnet_floating_v6_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Mirrored_Trunk - diff --git a/ice_validator/tests/fixtures/test_non_server_name/fail/fail2.yaml b/ice_validator/tests/fixtures/test_non_server_name/fail/fail2.yaml deleted file mode 100644 index 64a519b..0000000 --- a/ice_validator/tests/fixtures/test_non_server_name/fail/fail2.yaml +++ /dev/null @@ -1,133 +0,0 @@ -# -*- 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. -# -# VERSION: '1.0.0' - ---- -parameters: - - vm_typeX_bialy_vlan_filter: - type: comma_delimited_list - vm_typeX_bialy_public_vlans: - type: comma_delimited_list - vm_typeX_bialy_private_vlans: - type: comma_delimited_list - vm_typeX_bialy_guest_vlans: - type: comma_delimited_list - -resources: - - vm_typeX_0_bialy_port_2: - type: OS::Neutron::Port - properties: - name: - str_replace: - template: - params: - mynameisstillbad: foozle - network: { get_param: int_intranet_net_name } - fixed_ips: - - ip_address: { get_param: lb_1_int_intranet_floating_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Trunk - - vm_typeX_1_bialy_port_2: - type: OS::Neutron::Port - properties: - name: - str_replace: - template: - params: - mynameisstilltrouble: - network: { get_param: int_intranet_net_id } - fixed_ips: - - ip_address: { get_param: lb_2_int_intranet_floating_v6_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Non_Trunk - - vm_typeX_2_bialy_port_2: - type: OS::Neutron::Port - properties: - network: { get_param: extnet_net_name } - fixed_ips: - - ip_address: { get_param: lb_1_extnet_floating_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: OVS - - vm_typeX_3_bialy_port_2: - type: OS::Neutron::Port - properties: - network: { get_param: extnet_net_id } - fixed_ips: - - ip_address: { get_param: lb_2_extnet_floating_v6_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Mirrored_Trunk - diff --git a/ice_validator/tests/fixtures/test_non_server_name/fail/fail3.yaml b/ice_validator/tests/fixtures/test_non_server_name/fail/fail3.yaml deleted file mode 100644 index 2def749..0000000 --- a/ice_validator/tests/fixtures/test_non_server_name/fail/fail3.yaml +++ /dev/null @@ -1,135 +0,0 @@ -# -*- 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. -# -# VERSION: '1.0.0' - ---- -parameters: - - vm_typeX_bialy_vlan_filter: - type: comma_delimited_list - vm_typeX_bialy_public_vlans: - type: comma_delimited_list - vm_typeX_bialy_private_vlans: - type: comma_delimited_list - vm_typeX_bialy_guest_vlans: - type: comma_delimited_list - -resources: - - vm_typeX_0_bialy_port_2: - type: OS::Neutron::Port - properties: - name: - str_replace: - template: - params: - mynameisstillbad: - get_param: foozle - network: { get_param: int_intranet_net_name } - fixed_ips: - - ip_address: { get_param: lb_1_int_intranet_floating_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Trunk - - vm_typeX_1_bialy_port_2: - type: OS::Neutron::Port - properties: - name: - str_replace: - template: - params: - mynameisstilltrouble: - get_param: - network: { get_param: int_intranet_net_id } - fixed_ips: - - ip_address: { get_param: lb_2_int_intranet_floating_v6_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Non_Trunk - - vm_typeX_2_bialy_port_2: - type: OS::Neutron::Port - properties: - network: { get_param: extnet_net_name } - fixed_ips: - - ip_address: { get_param: lb_1_extnet_floating_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: OVS - - vm_typeX_3_bialy_port_2: - type: OS::Neutron::Port - properties: - network: { get_param: extnet_net_id } - fixed_ips: - - ip_address: { get_param: lb_2_extnet_floating_v6_ip } - binding:vnic_type: direct - value_specs: - vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} - public_vlans: {get_param: vm_typeX_bialy_public_vlans} - private_vlans: {get_param: vm_typeX_bialy_private_vlans} - guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} - vlan_mirror: - ATT_FABRIC_CONFIGURATION_REQUIRED: true - metadata: - port_type: SR-IOV_Mirrored_Trunk - diff --git a/ice_validator/tests/fixtures/test_non_server_name/pass/pass0.yaml b/ice_validator/tests/fixtures/test_non_server_name/pass/pass0.yaml index ff96331..e825b03 100644 --- a/ice_validator/tests/fixtures/test_non_server_name/pass/pass0.yaml +++ b/ice_validator/tests/fixtures/test_non_server_name/pass/pass0.yaml @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,7 +37,7 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # -# VERSION: '1.0.0' +# VERSION: '1.2.0' --- parameters: @@ -58,10 +58,12 @@ resources: properties: name: str_replace: - template: mynameisok_port2 + template: mynameisok_myindex params: mynameisok: get_param: vnf_name + myindex: + get_param: 0 network: { get_param: int_intranet_net_name } fixed_ips: - ip_address: { get_param: lb_1_int_intranet_floating_ip } @@ -81,10 +83,12 @@ resources: properties: name: str_replace: - template: mynameisok_port2 + template: mynameisok_myindex params: mynameisok: get_param: vnf_name + myindex: + get_param: 1 network: { get_param: int_intranet_net_id } fixed_ips: - ip_address: { get_param: lb_2_int_intranet_floating_v6_ip } diff --git a/ice_validator/tests/fixtures/test_oam_address_outputs/fail/base_fail.yaml b/ice_validator/tests/fixtures/test_oam_address_outputs/fail/base_fail.yaml new file mode 100644 index 0000000..c31c735 --- /dev/null +++ b/ice_validator/tests/fixtures/test_oam_address_outputs/fail/base_fail.yaml @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +outputs: + oam_management_v6_address: + description: OAM management address + value: {get_param: oam_address} + + oam_management_v4_address: + description: OAM management address + value: {get_param: oam_address} diff --git a/ice_validator/tests/fixtures/test_oam_address_outputs/fail/module_fail.yaml b/ice_validator/tests/fixtures/test_oam_address_outputs/fail/module_fail.yaml new file mode 100644 index 0000000..1c63c9c --- /dev/null +++ b/ice_validator/tests/fixtures/test_oam_address_outputs/fail/module_fail.yaml @@ -0,0 +1,45 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +outputs: + oam_management_v4_address: + description: OAM management address + value: {get_param: oam_address} + + oam_management_v6_address: + description: OAM management address + value: {get_param: oam_address} \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_oam_address_outputs/pass/base_pass.yaml b/ice_validator/tests/fixtures/test_oam_address_outputs/pass/base_pass.yaml new file mode 100644 index 0000000..6fbcb2c --- /dev/null +++ b/ice_validator/tests/fixtures/test_oam_address_outputs/pass/base_pass.yaml @@ -0,0 +1,41 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +outputs: + oam_management_v6_address: + description: OAM management address + value: {get_param: oam_address} diff --git a/ice_validator/tests/fixtures/test_oam_address_outputs/pass/module_pass.yaml b/ice_validator/tests/fixtures/test_oam_address_outputs/pass/module_pass.yaml new file mode 100644 index 0000000..2ba45e5 --- /dev/null +++ b/ice_validator/tests/fixtures/test_oam_address_outputs/pass/module_pass.yaml @@ -0,0 +1,41 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +outputs: + oam_management_v4_address: + description: OAM management address + value: {get_param: oam_address} diff --git a/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/fail/base_mod.yaml b/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/fail/base_mod.yaml index 0dc304e..7721fe6 100644 --- a/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/fail/base_mod.yaml +++ b/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/fail/base_mod.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2014-10-16 resources: diff --git a/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/pass/base_mod.yaml b/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/pass/base_mod.yaml index 36d3f6e..64fca0a 100644 --- a/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/pass/base_mod.yaml +++ b/ice_validator/tests/fixtures/test_port_connected_to_multiple_servers/pass/base_mod.yaml @@ -1,3 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + heat_template_version: 2014-10-16 resources: diff --git a/ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/fail/fail.yaml b/ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/fail/fail.yaml new file mode 100644 index 0000000..a734a30 --- /dev/null +++ b/ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/fail/fail.yaml @@ -0,0 +1,49 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ +# + +resources: + sf_server_0: + type: OS::Nova::Server + properties: + networks: + - port: {get_resource: sf_1_int_di_port_2} + - port: {get_resource: sf_2_int_icsr_port_0} + - port: {get_resource: sf_3_gn_vmi_port_0} + - port: {get_resource: sf_4_cor_vmi_port_1} + - port: {get_resource: sf_5_rad_vmi_port_2} + - port: {get_resource: sf_6_calea_vmi_3} diff --git a/ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/pass/pass.yaml b/ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/pass/pass.yaml new file mode 100644 index 0000000..6f644e5 --- /dev/null +++ b/ice_validator/tests/fixtures/test_server_and_port_vm_indices_match/pass/pass.yaml @@ -0,0 +1,49 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ +# + +resources: + sf_server_0: + type: OS::Nova::Server + properties: + networks: + - port: {get_resource: sf_0_int_di_port_2} + - port: {get_resource: sf_0_int_icsr_port_0} + - port: {get_resource: sf_0_gn_vmi_0} + - port: {get_resource: sf_0_cor_vmi_1} + - port: {get_resource: sf_0_rad_vmi_2} + - port: {get_resource: sf_0_calea_vmi_3} diff --git a/ice_validator/tests/fixtures/test_vm_class_has_unique_type/fail/fail.yaml b/ice_validator/tests/fixtures/test_vm_class_has_unique_type/fail/fail.yaml new file mode 100644 index 0000000..d50ddbc --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_class_has_unique_type/fail/fail.yaml @@ -0,0 +1,69 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +parameters: + vm_role: + type: string + +resources: + dns_server_0: + type: OS::Nova::Server + properties: + metadata: + vm_role: {get_param: vm_role} + networks: + - port: { get_resource: dns_0_oam_port_0 } + + dns_server_1: + type: OS::Nova::Server + properties: + metadata: + vm_role: {get_param: vm_role} + networks: + - port: { get_resource: dns_1_oam_port_0 } + + dns_0_oam_port_0: + type: OS::Neutron::Port + + dns_1_oam_port_0: + type: OS::Neutron::Port + + cinder_attach_0: + type: OS::Cinder::VolumeAttachment + properties: + volume_id: 1234 + instance_uuid: { get_resource: dns_server_0 } diff --git a/ice_validator/tests/fixtures/test_vm_class_has_unique_type/pass/pass.yaml b/ice_validator/tests/fixtures/test_vm_class_has_unique_type/pass/pass.yaml new file mode 100644 index 0000000..f162887 --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_class_has_unique_type/pass/pass.yaml @@ -0,0 +1,75 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +parameters: + vm_role: + type: string + +resources: + dns_server_0: + type: OS::Nova::Server + properties: + metadata: + vm_role: {get_param: vm_role} + networks: + - port: { get_resource: dns_0_oam_port_0 } + + dns_server_1: + type: OS::Nova::Server + properties: + metadata: + vm_role: {get_param: vm_role} + networks: + - port: { get_resource: dns_1_oam_port_0 } + + dns_0_oam_port_0: + type: OS::Neutron::Port + + dns_1_oam_port_0: + type: OS::Neutron::Port + + cinder_attach_0: + type: OS::Cinder::VolumeAttachment + properties: + volume_id: 1234 + instance_uuid: { get_resource: dns_server_0 } + + cinder_attach_1: + type: OS::Cinder::VolumeAttachment + properties: + volume_id: 1234 + instance_uuid: { get_resource: dns_server_1 } diff --git a/ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.env b/ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.env new file mode 100644 index 0000000..8f27823 --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.env @@ -0,0 +1,39 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +parameters: + vm_role: dns$1 diff --git a/ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.yaml b/ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.yaml new file mode 100644 index 0000000..4d3b8af --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_role_value/fail/fail_parameter.yaml @@ -0,0 +1,53 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +parameters: + vm_role: + type: string + +resources: + dns_server_0: + type: OS::Nova::Server + properties: + metadata: + vm_role: dns$1 + + dns_server_1: + type: OS::Nova::Server + properties: + metadata: + vm_role: {get_param: vm_role} \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_hardcoded.yaml b/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_hardcoded.yaml new file mode 100644 index 0000000..19af492 --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_hardcoded.yaml @@ -0,0 +1,43 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +resources: + dns_server_0: + type: OS::Nova::Server + properties: + metadata: + vm_role: dns \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.env b/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.env new file mode 100644 index 0000000..5556831 --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.env @@ -0,0 +1,39 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +parameters: + vm_role: dns \ No newline at end of file diff --git a/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.yaml b/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.yaml new file mode 100644 index 0000000..9c36767 --- /dev/null +++ b/ice_validator/tests/fixtures/test_vm_role_value/pass/pass_parameter.yaml @@ -0,0 +1,47 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ + +parameters: + vm_role: + type: string + +resources: + dns_server_0: + type: OS::Nova::Server + properties: + metadata: + vm_role: {get_param: vm_role} \ No newline at end of file diff --git a/ice_validator/tests/helpers.py b/ice_validator/tests/helpers.py index fa106c3..0b33c0c 100644 --- a/ice_validator/tests/helpers.py +++ b/ice_validator/tests/helpers.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -113,6 +113,19 @@ def validates(*requirement_ids): return decorator +def categories(*categories): + def decorator(func): + @funcutils.wraps(func) + def wrapper(*args, **kw): + return func(*args, **kw) + + wrapper.categories = categories + return wrapper + + decorator.categories = categories + return decorator + + def get_environment_pair(heat_template): """Returns a yaml/env pair given a yaml file""" base_dir, filename = os.path.split(heat_template) @@ -130,6 +143,47 @@ def get_environment_pair(heat_template): return None +def find_environment_file(yaml_files): + """ + Pass file and recursively step backwards until environment file is found + + :param yaml_files: list or string, start at size 1 and grows recursively + :return: corresponding environment file for a file, or None + """ + # sanitize + if isinstance(yaml_files, str): + yaml_files = [yaml_files] + + yaml_file = yaml_files[-1] + filepath, filename = os.path.split(yaml_file) + + environment_pair = get_environment_pair(yaml_file) + if environment_pair: + return environment_pair + + for file in os.listdir(filepath): + fq_name = "{}/{}".format(filepath, file) + if fq_name.endswith("yaml") or fq_name.endswith("yml"): + if fq_name not in yaml_files: + with open(fq_name) as f: + yml = yaml.load(f) + resources = yml.get("resources", {}) + for resource_id, resource in resources.items(): + resource_type = resource.get("type", "") + if resource_type == "OS::Heat::ResourceGroup": + resource_type = ( + resource.get("properties", {}) + .get("resource_def", {}) + .get("type", "") + ) + # found called nested file + if resource_type == filename: + yaml_files.append(fq_name) + environment_pair = find_environment_file(yaml_files) + + return environment_pair + + def load_yaml(yaml_file): """ Load the YAML file at the given path. If the file has previously been diff --git a/ice_validator/tests/report.html.jinja2 b/ice_validator/tests/report.html.jinja2 index 5856c5d..9b98514 100644 --- a/ice_validator/tests/report.html.jinja2 +++ b/ice_validator/tests/report.html.jinja2 @@ -1,7 +1,7 @@ {## ============LICENSE_START=======================================================#} {## org.onap.vvp/validation-scripts#} {## ===================================================================#} -{## Copyright © 2018 AT&T Intellectual Property. All rights reserved.#} +{## Copyright © 2019 AT&T Intellectual Property. All rights reserved.#} {## ===================================================================#} {###} {## Unless otherwise specified, all software contained herein is licensed#} @@ -96,7 +96,7 @@

Validation Report

    -
  • Profile: {{ profile_name }}
  • +
  • Categories: {{ categories }}
  • Tool Version: {{ version }}
  • Directory Validated: {{ template_dir }}
  • Checksum: {{ checksum }}
  • diff --git a/ice_validator/tests/structures.py b/ice_validator/tests/structures.py index 3f48422..6461879 100644 --- a/ice_validator/tests/structures.py +++ b/ice_validator/tests/structures.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -35,23 +35,21 @@ # # ============LICENSE_END============================================ # - +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# """structures """ -import sys - - import collections import inspect import os import re +import sys from tests import cached_yaml as yaml from tests.helpers import load_yaml - from .utils import nested_dict -VERSION = "3.5.0" +VERSION = "4.2.0" # key = pattern, value = regex compiled from pattern _REGEX_CACHE = {} @@ -68,34 +66,61 @@ def _get_regex(pattern): return regex -class HeatObject(object): - """base class for xxxx::xxxx::xxxx objects +class Hashabledict(dict): + """A hashable dict. + dicts with the same keys and whose keys have the same values + are assigned the same hash. """ - resource_type = None + def __hash__(self): + return hash((frozenset(self), frozenset(self.values()))) + + +class HeatProcessor(object): + """base class for xxxx::xxxx::xxxx processors + """ - def __init__(self): - self.re_rids = self.get_re_rids() + resource_type = None # string 'xxxx::xxxx::xxxx' + re_rids = collections.OrderedDict() # OrderedDict of name: regex + # name is a string to name the regex. + # regex parses the proper resource id format. @staticmethod - def get_re_rids(): - """Return OrderedDict of name: regex - Each regex parses the proper format for a given rid - (resource id). + def get_param_value(value): + """Return get_param value of `value` """ - return collections.OrderedDict() + if isinstance(value, dict) and len(value) == 1: + v = value.get("get_param") + if isinstance(v, list) and v: + v = v[0] + else: + v = None + return v - def get_rid_match_tuple(self, rid): + @classmethod + def get_resource_or_param_value(cls, value): + """Return the get_resource or get_param value of `value` + """ + if isinstance(value, dict) and len(value) == 1: + v = value.get("get_resource") or cls.get_param_value(value) + else: + v = None + return v + + @classmethod + def get_rid_match_tuple(cls, rid): """find the first regex matching `rid` and return the tuple (name, match object) or ('', None) if no match. """ - for name, regex in self.re_rids.items(): + rid = "" if rid is None else rid + for name, regex in cls.re_rids.items(): match = regex.match(rid) if match: return name, match return "", None - def get_rid_patterns(self): + @classmethod + def get_rid_patterns(cls): """Return OrderedDict of name: friendly regex.pattern "friendly" means the group notation is replaced with braces, and the trailing "$" is removed. @@ -106,7 +131,7 @@ class HeatObject(object): """ friendly_pattern = _get_regex(r"\(\?P<(.*?)>.*?\)") rid_patterns = collections.OrderedDict() - for name, regex in self.re_rids.items(): + for name, regex in cls.re_rids.items(): rid_patterns[name] = friendly_pattern.sub( r"{\1}", regex.pattern # replace groups with braces )[ @@ -114,8 +139,86 @@ class HeatObject(object): ] # remove trailing $ return rid_patterns + @classmethod + def get_str_replace_name(cls, resource_dict): + """Return the name modified by str_replace of `resource_dict`, + a resource (i.e. a value in some template's resources). + Return None, if there is no name, str_replace, its template, + or any missing parameters. + """ + str_replace = Heat.nested_get( + resource_dict, "properties", "name", "str_replace" + ) + if not str_replace: + return None + template = Heat.nested_get(str_replace, "template") + if not isinstance(template, str): + return None + params = Heat.nested_get(str_replace, "params", default={}) + if not isinstance(params, dict): + return None + # WARNING + # The user must choose non-overlapping keys for params since they + # are replaced in the template in arbitrary order. + name = template + for key, value in params.items(): + param = cls.get_param_value(value) + if param is None: + return None + name = name.replace(key, str(param)) + return name + + +class CinderVolumeAttachmentProcessor(HeatProcessor): + """ Cinder VolumeAttachment + """ -class ContrailV2NetworkHeatObject(HeatObject): + resource_type = "OS::Cinder::VolumeAttachment" + + @classmethod + def get_config(cls, resources): + """Return a tuple (va_config, va_count) + va_config - Hashabledict of Cinder Volume Attachment config + indexed by rid. + va_count - dict of attachment counts indexed by rid. + """ + va_count = collections.defaultdict(int) + va_config = Hashabledict() + for resource in resources.values(): + resource_type = nested_dict.get(resource, "type") + if resource_type == cls.resource_type: + config, rids = cls.get_volume_attachment_config(resource) + for rid in rids: + va_config[rid] = config + va_count[rid] += 1 + return va_config, va_count + + @classmethod + def get_volume_attachment_config(cls, resource): + """Returns the cinder volume attachment configuration + of `resource` as a tuple (config, rids) + where: + - config is a Hashabledict whose keys are the keys of the + properties of resource, and whose values are the + corresponding property values (nova server resource ids) + replaced with the vm-type they reference. + - rids is the set of nova server resource ids referenced by + the property values. + """ + config = Hashabledict() + rids = set() + for key, value in (resource.get("properties") or {}).items(): + rid = cls.get_resource_or_param_value(value) + if rid: + name, match = NovaServerProcessor.get_rid_match_tuple(rid) + if name == "server": + vm_type = match.groupdict()["vm_type"] + config[key] = vm_type + rids.add(rid) + return config, rids + + +class ContrailV2NetworkFlavorBaseProcessor(HeatProcessor): """ContrailV2 objects which have network_flavor """ @@ -123,7 +226,8 @@ class ContrailV2NetworkHeatObject(HeatObject): network_flavor_internal = "internal" network_flavor_subint = "subint" - def get_network_flavor(self, resource): + @classmethod + def get_network_flavor(cls, resource): """Return the network flavor of resource, one of "internal" - get_resource, or get_param contains _int_ "subint" - get_param contains _subint_ @@ -140,324 +244,376 @@ class ContrailV2NetworkHeatObject(HeatObject): param = network_refs[0] if isinstance(param, dict): if "get_resource" in param: - network_flavor = self.network_flavor_internal + network_flavor = cls.network_flavor_internal else: p = param.get("get_param") if isinstance(p, str): if "_int_" in p or p.startswith("int_"): - network_flavor = self.network_flavor_internal + network_flavor = cls.network_flavor_internal elif "_subint_" in p: - network_flavor = self.network_flavor_subint + network_flavor = cls.network_flavor_subint else: - network_flavor = self.network_flavor_external + network_flavor = cls.network_flavor_external return network_flavor -class ContrailV2InstanceIp(ContrailV2NetworkHeatObject): +class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor): """ ContrailV2 InstanceIp """ resource_type = "OS::ContrailV2::InstanceIp" - - def get_re_rids(self): - """Return OrderedDict of name: regex - """ - return collections.OrderedDict( - [ - ( - "int_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_int" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_IP" - r"_(?P\d+)" - r"$" - ), + re_rids = collections.OrderedDict( + [ + ( + "int_ip", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_int" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"_IP" + r"_(?P\d+)" + r"$" ), - ( - "int_v6_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_int" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_v6_IP" - r"_(?P\d+)" - r"$" - ), + ), + ( + "int_v6_ip", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_int" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"_v6_IP" + r"_(?P\d+)" + r"$" ), - ( - "subint_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_subint" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_IP" - r"_(?P\d+)" - r"$" - ), + ), + ( + "subint_ip", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_subint" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"_IP" + r"_(?P\d+)" + r"$" ), - ( - "subint_v6_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_subint" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_v6_IP" - r"_(?P\d+)" - r"$" - ), + ), + ( + "subint_v6_ip", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_subint" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"_v6_IP" + r"_(?P\d+)" + r"$" ), - ( - "ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_IP" - r"_(?P\d+)" - r"$" - ), + ), + ( + "ip", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"_IP" + r"_(?P\d+)" + r"$" ), - ( - "v6_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_v6_IP" - r"_(?P\d+)" - r"$" - ), + ), + ( + "v6_ip", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"_v6_IP" + r"_(?P\d+)" + r"$" ), - ] - ) + ), + ] + ) -class ContrailV2InterfaceRouteTable(HeatObject): +class ContrailV2InterfaceRouteTableProcessor(HeatProcessor): """ ContrailV2 InterfaceRouteTable """ resource_type = "OS::ContrailV2::InterfaceRouteTable" -class ContrailV2NetworkIpam(HeatObject): +class ContrailV2NetworkIpamProcessor(HeatProcessor): """ ContrailV2 NetworkIpam """ resource_type = "OS::ContrailV2::NetworkIpam" -class ContrailV2PortTuple(HeatObject): +class ContrailV2PortTupleProcessor(HeatProcessor): """ ContrailV2 PortTuple """ resource_type = "OS::ContrailV2::PortTuple" -class ContrailV2ServiceHealthCheck(HeatObject): +class ContrailV2ServiceHealthCheckProcessor(HeatProcessor): """ ContrailV2 ServiceHealthCheck """ resource_type = "OS::ContrailV2::ServiceHealthCheck" -class ContrailV2ServiceInstance(HeatObject): +class ContrailV2ServiceInstanceProcessor(HeatProcessor): """ ContrailV2 ServiceInstance """ resource_type = "OS::ContrailV2::ServiceInstance" -class ContrailV2ServiceInstanceIp(HeatObject): +class ContrailV2ServiceInstanceIpProcessor(HeatProcessor): """ ContrailV2 ServiceInstanceIp """ resource_type = "OS::ContrailV2::ServiceInstanceIp" -class ContrailV2ServiceTemplate(HeatObject): +class ContrailV2ServiceTemplateProcessor(HeatProcessor): """ ContrailV2 ServiceTemplate """ resource_type = "OS::ContrailV2::ServiceTemplate" -class ContrailV2VirtualMachineInterface(ContrailV2NetworkHeatObject): +class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProcessor): """ ContrailV2 Virtual Machine Interface resource """ resource_type = "OS::ContrailV2::VirtualMachineInterface" - - def get_re_rids(self): - """Return OrderedDict of name: regex - """ - return collections.OrderedDict( - [ - ( - "vmi_internal", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_int" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"$" - ), + re_rids = collections.OrderedDict( + [ + ( + "vmi_internal", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_int" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"$" ), - ( - "vmi_subint", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_subint" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"$" - ), + ), + ( + "vmi_subint", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_subint" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"$" ), - ( - "vmi_external", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"$" - ), + ), + ( + "vmi_external", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_(?P.+)" + r"_vmi" + r"_(?P\d+)" + r"$" ), - ] - ) + ), + ] + ) -class ContrailV2VirtualNetwork(HeatObject): +class ContrailV2VirtualNetworkProcessor(HeatProcessor): """ ContrailV2 VirtualNetwork """ resource_type = "OS::ContrailV2::VirtualNetwork" + re_rids = collections.OrderedDict( + [ + ("network", _get_regex(r"int" r"_(?P.+)" r"_network" r"$")), + ("rvn", _get_regex(r"int" r"_(?P.+)" r"_RVN" r"$")), + ] + ) - def get_re_rids(self): - """Return OrderedDict of name: regex - """ - return collections.OrderedDict( - [ - ( - "network", - _get_regex(r"int" r"_(?P.+)" r"_network" r"$"), + +class HeatResourceGroupProcessor(HeatProcessor): + """ Heat ResourceGroup + """ + + resource_type = "OS::Heat::ResourceGroup" + re_rids = collections.OrderedDict( + [ + ( + "subint", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_subint" + r"_(?P.+)" + r"_port_(?P\d+)" + r"_subinterfaces" + r"$" ), - ("rvn", _get_regex(r"int" r"_(?P.+)" r"_RVN" r"$")), - ] - ) + ) + ] + ) -class NeutronNet(HeatObject): +class NeutronNetProcessor(HeatProcessor): """ Neutron Net resource """ resource_type = "OS::Neutron::Net" + re_rids = collections.OrderedDict( + [("network", _get_regex(r"int" r"_(?P.+)" r"_network" r"$"))] + ) - def get_re_rids(self): - """Return OrderedDict of name: regex - """ - return collections.OrderedDict( - [("network", _get_regex(r"int" r"_(?P.+)" r"_network" r"$"))] - ) - -class NeutronPort(HeatObject): +class NeutronPortProcessor(HeatProcessor): """ Neutron Port resource """ resource_type = "OS::Neutron::Port" - - def get_re_rids(self): - """Return OrderedDict of name: regex - """ - return collections.OrderedDict( - [ - ( - "internal_port", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_int" - r"_(?P.+)" - r"_port_(?P\d+)" - r"$" - ), + re_rids = collections.OrderedDict( + [ + ( + "internal_port", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_int" + r"_(?P.+)" + r"_port_(?P\d+)" + r"$" ), - ( - "port", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_(?P.+)" - r"_port_(?P\d+)" - r"$" - ), + ), + ( + "port", + _get_regex( + r"(?P.+)" + r"_(?P\d+)" + r"_(?P.+)" + r"_port_(?P\d+)" + r"$" ), - ( - "floating_ip", - _get_regex( - r"reserve_port" - r"_(?P.+)" - r"_(?P.+)" - r"_floating_ip_(?P\d+)" - r"$" - ), + ), + ( + "floating_ip", + _get_regex( + r"reserve_port" + r"_(?P.+)" + r"_(?P.+)" + r"_floating_ip_(?P\d+)" + r"$" ), - ( - "floating_v6_ip", - _get_regex( - r"reserve_port" - r"_(?P.+)" - r"_(?P.+)" - r"_floating_v6_ip_(?P\d+)" - r"$" - ), + ), + ( + "floating_v6_ip", + _get_regex( + r"reserve_port" + r"_(?P.+)" + r"_(?P.+)" + r"_floating_v6_ip_(?P\d+)" + r"$" ), - ] + ), + ] + ) + + @classmethod + def uses_sr_iov(cls, resource): + """Returns True/False as `resource` is/not + An OS::Nova:Port with the property binding:vnic_type + """ + return nested_dict.get( + resource, "type" + ) == cls.resource_type and "binding:vnic_type" in nested_dict.get( + resource, "properties", default={} ) -class NovaServer(HeatObject): +class NovaServerProcessor(HeatProcessor): """ Nova Server resource """ resource_type = "OS::Nova::Server" + re_rids = collections.OrderedDict( + [ + ( + "server", + _get_regex(r"(?P.+)" r"_server_(?P\d+)" r"$"), + ) + ] + ) - def get_re_rids(self): - """Return OrderedDict of name: regex - """ - return collections.OrderedDict( - [ - ( - "server", - _get_regex( - r"(?P.+)" r"_server_(?P\d+)" r"$" - ), - ) - ] - ) + @classmethod + def get_flavor(cls, resource): + """Return the flavor property of `resource` + """ + return cls.get_param_value(nested_dict.get(resource, "properties", "flavor")) + + @classmethod + def get_image(cls, resource): + """Return the image property of `resource` + """ + return cls.get_param_value(nested_dict.get(resource, "properties", "image")) + + @classmethod + def get_network(cls, resource): + """Return the network configuration of `resource` as a + frozenset of network-roles. + """ + network = set() + networks = nested_dict.get(resource, "properties", "networks") + if isinstance(networks, list): + for port in networks: + value = cls.get_resource_or_param_value(nested_dict.get(port, "port")) + name, match = NeutronPortProcessor.get_rid_match_tuple(value) + if name: + network_role = match.groupdict().get("network_role") + if network_role: + network.add(network_role) + return frozenset(network) + + @classmethod + def get_vm_class(cls, resource): + """Return the vm_class of `resource`, a Hashabledict (of + hashable values) whose keys are only the required keys. + Return empty Hashabledict if `resource` is not a NovaServer. + """ + vm_class = Hashabledict() + resource_type = nested_dict.get(resource, "type") + if resource_type == cls.resource_type: + d = dict( + flavor=cls.get_flavor(resource), + image=cls.get_image(resource), + networks=cls.get_network(resource), + ) + if all(d.values()): + vm_class.update(d) + return vm_class class Heat(object): @@ -466,9 +622,15 @@ class Heat(object): envpath - absolute path to environmnt file. """ + type_bool = "boolean" + type_boolean = "boolean" type_cdl = "comma_delimited_list" + type_comma_delimited_list = "comma_delimited_list" + type_json = "json" type_num = "number" + type_number = "number" type_str = "string" + type_string = "string" def __init__(self, filepath=None, envpath=None): self.filepath = None @@ -487,22 +649,37 @@ class Heat(object): self.env = None if envpath: self.load_env(envpath) - self.heat_objects = self.get_heat_objects() + self.heat_processors = self.get_heat_processors() @property def contrail_resources(self): """This attribute is a dict of Contrail resources. """ return self.get_resource_by_type( - resource_type=ContrailV2VirtualMachineInterface.resource_type + resource_type=ContrailV2VirtualMachineInterfaceProcessor.resource_type ) + def get_all_resources(self, base_dir): + """ + Like ``resources``, + but this returns all the resources definitions + defined in the template, resource groups, and nested YAML files. + """ + resources = {} + for r_id, r_data in self.resources.items(): + resources[r_id] = r_data + resource = Resource(r_id, r_data) + if resource.is_nested(): + nested = Heat(os.path.join(base_dir, resource.get_nested_filename())) + resources.update(nested.get_all_resources(base_dir)) + return resources + @staticmethod - def get_heat_objects(): + def get_heat_processors(): """Return a dict, key is resource_type, value is the - HeatObject subclass whose resource_type is the key. + HeatProcessor subclass whose resource_type is the key. """ - return _HEAT_OBJECTS + return _HEAT_PROCESSORS def get_resource_by_type(self, resource_type): """Return dict of resources whose type is `resource_type`. @@ -518,8 +695,8 @@ class Heat(object): """return get_rid_match_tuple(rid) called on the class corresponding to the given resource_type. """ - hoc = self.heat_objects.get(resource_type, HeatObject) - return hoc().get_rid_match_tuple(rid) + processor = self.heat_processors.get(resource_type, HeatProcessor) + return processor.get_rid_match_tuple(rid) def get_vm_type(self, rid, resource=None): """return the vm_type @@ -541,29 +718,14 @@ class Heat(object): self.yml = yaml.load(fi) self.heat_template_version = self.yml.get("heat_template_version", None) self.description = self.yml.get("description", "") - self.parameter_groups = self.yml.get("parameter_groups", {}) + self.parameter_groups = self.yml.get("parameter_groups") or {} self.parameters = self.yml.get("parameters") or {} - self.resources = self.yml.get("resources", {}) - self.outputs = self.yml.get("outputs", {}) - self.conditions = self.yml.get("conditions", {}) - - def get_all_resources(self, base_dir): - """ - Like ``resources``, but this returns all the resources definitions - defined in the template, resource groups, and nested YAML files. - """ - resources = {} - for r_id, r_data in self.resources.items(): - resources[r_id] = r_data - resource = Resource(r_id, r_data) - if resource.is_nested(): - nested = Heat(os.path.join(base_dir, resource.get_nested_filename())) - resources.update(nested.get_all_resources(base_dir)) - return resources + self.resources = self.yml.get("resources") or {} + self.outputs = self.yml.get("outputs") or {} + self.conditions = self.yml.get("conditions") or {} def load_env(self, envpath): - """ - Load the Environment template given a envpath. + """Load the Environment template given a envpath. """ self.env = Env(filepath=envpath) @@ -577,13 +739,17 @@ class Heat(object): def neutron_port_resources(self): """This attribute is a dict of Neutron Ports """ - return self.get_resource_by_type(resource_type=NeutronPort.resource_type) + return self.get_resource_by_type( + resource_type=NeutronPortProcessor.resource_type + ) @property def nova_server_resources(self): """This attribute is a dict of Nova Servers """ - return self.get_resource_by_type(resource_type=NovaServer.resource_type) + return self.get_resource_by_type( + resource_type=NovaServerProcessor.resource_type + ) @staticmethod def part_is_in_name(part, name): @@ -614,7 +780,7 @@ class Resource(object): self.resource_id = resource_id or "" self.resource = resource or {} self.properties = self.resource.get("properties", {}) - self.resource_type = resource.get("type", "") + self.resource_type = self.resource.get("type", "") @staticmethod def get_index_var(resource): @@ -681,19 +847,30 @@ class Resource(object): return {} -def _get_heat_objects(): +def get_all_resources(yaml_files): + """Return a dict, resource id: resource + of the union of resources across all files. """ - Introspect this module and return a dict of all HeatObject sub-classes with - a (True) resource_type. Key is the resource_type, value is the - corresponding class. + resources = {} + for heat_template in yaml_files: + heat = Heat(filepath=heat_template) + dirname = os.path.dirname(heat_template) + resources.update(heat.get_all_resources(dirname)) + return resources + + +def _get_heat_processors(): + """Introspect this module and return a + dict of all HeatProcessor sub-classes with a (True) resource_type. + Key is the resource_type, value is the corrresponding class. """ mod_classes = inspect.getmembers(sys.modules[__name__], inspect.isclass) - heat_objects = { + heat_processors = { c.resource_type: c for _, c in mod_classes - if issubclass(c, HeatObject) and c.resource_type + if issubclass(c, HeatProcessor) and c.resource_type } - return heat_objects + return heat_processors -_HEAT_OBJECTS = _get_heat_objects() +_HEAT_PROCESSORS = _get_heat_processors() diff --git a/ice_validator/tests/test_all_parameters_used_in_template.py b/ice_validator/tests/test_all_parameters_used_in_template.py index 41356d4..44fe9da 100644 --- a/ice_validator/tests/test_all_parameters_used_in_template.py +++ b/ice_validator/tests/test_all_parameters_used_in_template.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -35,46 +35,21 @@ # # ============LICENSE_END============================================ # -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# - -import pytest -from tests import cached_yaml as yaml - -from .helpers import validates -from .utils.nested_iterables import find_all_get_param_in_yml +import re -VERSION = "1.0.0" +from tests.helpers import validates, load_yaml +from tests.utils.nested_iterables import find_all_get_param_in_yml -# pylint: disable=invalid-name +AVAILABILITY_ZONE = re.compile(r"availability_zone_?\d*") @validates("R-90279") def test_all_parameters_used_in_template(yaml_file): - - invalid_params = [] - get_params = [] - skip_params = ["availability_zone"] - - with open(yaml_file, "r") as f: - yml = yaml.load(f) - - template_parameters = yml.get("parameters") - if not template_parameters: - pytest.skip("no parameters found in template") - - get_params = find_all_get_param_in_yml(yml) - if not get_params: - pytest.skip("no get_params found in template") - - template_parameters = list(template_parameters.keys()) - for param in template_parameters: - for sparam in skip_params: - if param.find(sparam) != -1: - template_parameters.remove(param) - - invalid_params = set(template_parameters) - set(get_params) - - assert not invalid_params, "Unused parameters detected in template {}".format( - invalid_params - ) + yml = load_yaml(yaml_file) + params = (yml.get("parameters") or {}).keys() + expected_params = {p for p in params if not AVAILABILITY_ZONE.match(p)} + used_params = set(find_all_get_param_in_yml(yml)) + unused_params = expected_params.difference(used_params) + + msg = "Unused parameters detected in template {}".format(unused_params) + assert not unused_params, msg diff --git a/ice_validator/tests/test_contrail_instance_ip_resource_id.py b/ice_validator/tests/test_contrail_instance_ip_resource_id.py index c7c8c57..e1c1977 100644 --- a/ice_validator/tests/test_contrail_instance_ip_resource_id.py +++ b/ice_validator/tests/test_contrail_instance_ip_resource_id.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,7 +37,6 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # - """ resources: {vm-type}_server_{vm-type_index} @@ -45,29 +44,28 @@ resources: import pytest from .structures import Heat -from .structures import ContrailV2InstanceIp +from .structures import ContrailV2InstanceIpProcessor from .helpers import validates -VERSION = "1.1.0" +VERSION = "2.0.0" def run_test(heat_template, regex_names, network_flavor): """run test """ heat = Heat(filepath=heat_template) - heat_object_class = ContrailV2InstanceIp - resource_type = heat_object_class.resource_type + processor = ContrailV2InstanceIpProcessor + resource_type = processor.resource_type resources = heat.get_resource_by_type(resource_type=resource_type) if not resources: pytest.skip("No %s resources found" % resource_type) bad = [] - heat_object = heat_object_class() - rid_patterns = heat_object.get_rid_patterns() + rid_patterns = processor.get_rid_patterns() for rid, resource in resources.items(): - flavor = heat_object.get_network_flavor(resource) + flavor = processor.get_network_flavor(resource) if flavor != network_flavor: continue - regex_name = heat_object.get_rid_match_tuple(rid)[0] + regex_name = processor.get_rid_match_tuple(rid)[0] if regex_name in regex_names: continue bad.append(rid) @@ -105,7 +103,7 @@ def test_contrail_instance_ip_resource_id_external(heat_template): run_test( heat_template, regex_names=("ip", "v6_ip"), - network_flavor=ContrailV2InstanceIp.network_flavor_external, + network_flavor=ContrailV2InstanceIpProcessor.network_flavor_external, ) @@ -121,7 +119,7 @@ def test_contrail_instance_ip_resource_id_internal(heat_template): run_test( heat_template, regex_names=("int_ip", "int_v6_ip"), - network_flavor=ContrailV2InstanceIp.network_flavor_internal, + network_flavor=ContrailV2InstanceIpProcessor.network_flavor_internal, ) @@ -137,5 +135,5 @@ def test_contrail_instance_ip_resource_id_subint(heat_template): run_test( heat_template, regex_names=("subint_ip", "subint_v6_ip"), - network_flavor=ContrailV2InstanceIp.network_flavor_subint, + network_flavor=ContrailV2InstanceIpProcessor.network_flavor_subint, ) diff --git a/ice_validator/tests/test_contrail_resource_id.py b/ice_validator/tests/test_contrail_resource_id.py index 7667600..88cc2f0 100644 --- a/ice_validator/tests/test_contrail_resource_id.py +++ b/ice_validator/tests/test_contrail_resource_id.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -43,17 +43,17 @@ contrail """ import pytest -from .structures import ContrailV2InterfaceRouteTable -from .structures import ContrailV2NetworkIpam -from .structures import ContrailV2PortTuple -from .structures import ContrailV2ServiceHealthCheck -from .structures import ContrailV2ServiceTemplate +from .structures import ContrailV2InterfaceRouteTableProcessor +from .structures import ContrailV2NetworkIpamProcessor +from .structures import ContrailV2PortTupleProcessor +from .structures import ContrailV2ServiceHealthCheckProcessor +from .structures import ContrailV2ServiceTemplateProcessor from .utils.network_roles import get_network_roles from .utils.vm_types import get_vm_types from .structures import Heat from .helpers import validates -VERSION = "1.0.1" +VERSION = "2.0.0" def run_test(heat_template, contrail_class, get_parts, part_name): @@ -98,7 +98,10 @@ def test_contrail_interfaceroutetable_resource_id(heat_template): contain the ``{network-role}``. """ run_test( - heat_template, ContrailV2InterfaceRouteTable, get_network_roles, "network_role" + heat_template, + ContrailV2InterfaceRouteTableProcessor, + get_network_roles, + "network_role", ) @@ -111,7 +114,9 @@ def test_contrail_networkipam_resource_id(heat_template): **MUST** contain the ``{network-role}``. """ - run_test(heat_template, ContrailV2NetworkIpam, get_network_roles, "network_role") + run_test( + heat_template, ContrailV2NetworkIpamProcessor, get_network_roles, "network_role" + ) @validates("R-20065") @@ -123,7 +128,7 @@ def test_contrail_porttuple_resource_id(heat_template): **MUST** contain the ``{vm-type}``. """ - run_test(heat_template, ContrailV2PortTuple, get_vm_types, "vm_type") + run_test(heat_template, ContrailV2PortTupleProcessor, get_vm_types, "vm_type") @validates("R-76014") @@ -135,7 +140,9 @@ def test_contrail_servicehealthcheck_resource_id(heat_template): **MUST** contain the ``{vm-type}``. """ - run_test(heat_template, ContrailV2ServiceHealthCheck, get_vm_types, "vm_type") + run_test( + heat_template, ContrailV2ServiceHealthCheckProcessor, get_vm_types, "vm_type" + ) @validates("R-16437") @@ -147,4 +154,4 @@ def test_contrail_servicetemplate_resource_id(heat_template): **MUST** contain the ``{vm-type}``. """ - run_test(heat_template, ContrailV2ServiceTemplate, get_vm_types, "vm_type") + run_test(heat_template, ContrailV2ServiceTemplateProcessor, get_vm_types, "vm_type") diff --git a/ice_validator/tests/test_contrail_vmi_resource_id.py b/ice_validator/tests/test_contrail_vmi_resource_id.py index 35f16e6..9e9641d 100644 --- a/ice_validator/tests/test_contrail_vmi_resource_id.py +++ b/ice_validator/tests/test_contrail_vmi_resource_id.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,25 +37,25 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # -import pytest - -from .structures import Heat -from .structures import ContrailV2VirtualMachineInterface -from .helpers import validates """ resources: {vm-type}_server_{vm-type_index} """ +import pytest + +from .structures import Heat +from .structures import ContrailV2VirtualMachineInterfaceProcessor +from .helpers import validates -VERSION = "1.0.0" +VERSION = "2.0.0" def run_test(heat_template, regex_name, network_flavor): """run test """ heat = Heat(filepath=heat_template) - heat_object_class = ContrailV2VirtualMachineInterface + heat_object_class = ContrailV2VirtualMachineInterfaceProcessor resource_type = heat_object_class.resource_type resources = heat.get_resource_by_type(resource_type=resource_type) if not resources: @@ -94,7 +94,7 @@ def test_contrail_instance_ip_resource_id_external(heat_template): run_test( heat_template, regex_name="vmi_external", - network_flavor=ContrailV2VirtualMachineInterface.network_flavor_external, + network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_external, ) @@ -111,7 +111,7 @@ def test_contrail_instance_ip_resource_id_internal(heat_template): run_test( heat_template, regex_name="vmi_internal", - network_flavor=ContrailV2VirtualMachineInterface.network_flavor_internal, + network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_internal, ) @@ -128,5 +128,5 @@ def test_contrail_instance_ip_resource_id_subint(heat_template): run_test( heat_template, regex_name="vmi_subint", - network_flavor=ContrailV2VirtualMachineInterface.network_flavor_subint, + network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_subint, ) diff --git a/ice_validator/tests/test_contrail_vn_resource_id.py b/ice_validator/tests/test_contrail_vn_resource_id.py index 4045eee..2e27259 100644 --- a/ice_validator/tests/test_contrail_vn_resource_id.py +++ b/ice_validator/tests/test_contrail_vn_resource_id.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -46,9 +46,9 @@ import pytest from .helpers import validates from .structures import Heat -from .structures import ContrailV2VirtualNetwork +from .structures import ContrailV2VirtualNetworkProcessor -VERSION = "1.0.0" +VERSION = "2.0.0" # pylint: disable=invalid-name @@ -65,7 +65,7 @@ def test_neutron_net_resource_id(heat_template): 2) int_{network-role}_RVN`` where RVN represents Resource Virtual """ heat = Heat(filepath=heat_template) - heat_object_class = ContrailV2VirtualNetwork + heat_object_class = ContrailV2VirtualNetworkProcessor resource_type = heat_object_class.resource_type resources = heat.get_resource_by_type(resource_type) if not resources: diff --git a/ice_validator/tests/test_env_parameters_defined_in_template.py b/ice_validator/tests/test_env_parameters_defined_in_template.py index 9bdd56e..afb2473 100644 --- a/ice_validator/tests/test_env_parameters_defined_in_template.py +++ b/ice_validator/tests/test_env_parameters_defined_in_template.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -43,12 +43,12 @@ from .helpers import validates, get_environment_pair @validates("R-599443") -def test_env_params_are_defined_in_template(heat_template): +def test_env_params_are_defined_in_template(yaml_file): """Test that each paraemter defined in an environment file is also defined in the paired heat template""" bad = [] - template_pair = get_environment_pair(heat_template) + template_pair = get_environment_pair(yaml_file) if not template_pair: pytest.skip("No yaml/env pair could be determined") diff --git a/ice_validator/tests/test_environment_file_parameters.py b/ice_validator/tests/test_environment_file_parameters.py index 031f898..f13821d 100644 --- a/ice_validator/tests/test_environment_file_parameters.py +++ b/ice_validator/tests/test_environment_file_parameters.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,14 +37,13 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # - """ environment file structure """ +import os +from .helpers import validates, categories, get_environment_pair, find_environment_file import re import pytest - -from .helpers import validates, get_environment_pair - +from tests import cached_yaml as yaml VERSION = "1.0.0" @@ -96,6 +95,7 @@ resource_id: - nested_prop_1: { get_param: [parameter_2, {index}] } prop2: # this is a dict of dicts nested_prop_0: { get_param: parameter_1 } + prop3: { get_param: [parameter_3, 0]} """ @@ -109,7 +109,6 @@ def check_resource_parameter( exclude_resource="", exclude_parameter="", ): - if not environment_pair: pytest.skip("No heat/env pair could be identified") @@ -120,7 +119,6 @@ def check_resource_parameter( pytest.skip("No parameters specified in the environment file") invalid_parameters = [] - if template_file: for resource, resource_prop in template_file.get("resources", {}).items(): @@ -141,10 +139,8 @@ def check_resource_parameter( 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 @@ -169,7 +165,6 @@ def check_resource_parameter( invalid_parameters.append(pattern) elif isinstance(resource_parameter, dict): - if nested_prop and nested_prop in resource_parameter: resource_parameter = resource_parameter.get(nested_prop) @@ -177,6 +172,9 @@ def check_resource_parameter( if not pattern: continue + if isinstance(pattern, list): + pattern = pattern[0] + if check_param_in_env_file( environment_pair, pattern, @@ -190,498 +188,227 @@ def check_resource_parameter( 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) +def run_check_resource_parameter( + yaml_file, prop, DESIRED, resource_type, check_resource=True, **kwargs +): - prop = "image" - DESIRED = True - resource_type = "OS::Nova::Server" + filepath, filename = os.path.split(yaml_file) + environment_pair = get_environment_pair(yaml_file) - 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 + if not environment_pair: + # this is a nested file + + if not check_resource: + # dont check env for nested files + # This will be tested separately for parent template + pytest.skip("This test doesn't apply to nested files") + + environment_pair = find_environment_file(yaml_file) + if environment_pair: + with open(yaml_file, "r") as f: + yml = yaml.load(f) + environment_pair["yyml"] = yml + else: + pytest.skip("unable to determine environment file for nested yaml file") + + if check_resource: + invalid_parameters = check_resource_parameter( + environment_pair, prop, DESIRED, resource_type, **kwargs ) - ) - - -@validates("R-69431") -def test_nova_server_flavor_parameter_exists_in_environment_file(heat_template): + else: + invalid_parameters = check_param_in_env_file(environment_pair, prop, DESIRED) - 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 - ) + if kwargs.get("resource_type_inverse"): + resource_type = "non-{}".format(resource_type) assert not invalid_parameters, ( - "OS::Nova::Server {} parameters not" - " found in {} environment file {}".format( - prop, environment_pair.get("name"), invalid_parameters + "{} {} parameters in template {}{}" + " found in {} environment file: {}".format( + resource_type, + prop, + filename, + " not" if DESIRED else "", + 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") +@validates("R-91125") +def test_nova_server_image_parameter_exists_in_environment_file(yaml_file): + run_check_resource_parameter(yaml_file, "image", True, "OS::Nova::Server") - environment_pair = get_environment_pair(heat_template) - prop = "name" - DESIRED = False - resource_type = "OS::Nova::Server" +@validates("R-69431") +def test_nova_server_flavor_parameter_exists_in_environment_file(yaml_file): + run_check_resource_parameter(yaml_file, "flavor", True, "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 - ) - ) +@categories("environment_file") +@validates("R-22838") +def test_nova_server_name_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter(yaml_file, "name", False, "OS::Nova::Server") +@categories("environment_file") @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 - ) +def test_nova_server_az_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, "availability_zone", False, "OS::Nova::Server" ) +@categories("environment_file") @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 - ) - ) +def test_nova_server_vnf_id_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter(yaml_file, "vnf_id", False, "", check_resource=False) +@categories("environment_file") @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 - ) +def test_nova_server_vf_module_id_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, "vf_module_id", False, "", check_resource=False ) +@categories("environment_file") @validates("R-37039") def test_nova_server_vf_module_index_parameter_doesnt_exist_in_environment_file( - heat_template + yaml_file ): - - 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_index" - 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 - ) + run_check_resource_parameter( + yaml_file, "vf_module_index", False, "", check_resource=False ) +@categories("environment_file") @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 - ) - ) +def test_nova_server_vnf_name_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter(yaml_file, "vnf_name", False, "", check_resource=False) +@categories("environment_file") @validates("R-80374") def test_nova_server_vf_module_name_parameter_doesnt_exist_in_environment_file( - heat_template + yaml_file ): - - 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 - ) + run_check_resource_parameter( + yaml_file, "vf_module_name", False, "", check_resource=False ) +@categories("environment_file") @validates("R-02691") def test_nova_server_workload_context_parameter_doesnt_exist_in_environment_file( - heat_template + yaml_file ): - - 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 - ) + run_check_resource_parameter( + yaml_file, "workload_context", False, "", check_resource=False ) +@categories("environment_file") @validates("R-13194") def test_nova_server_environment_context_parameter_doesnt_exist_in_environment_file( - heat_template + yaml_file ): - - 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 - ) + run_check_resource_parameter( + yaml_file, "environment_context", False, "", check_resource=False ) +@categories("environment_file") @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 - ) - ) +def test_neutron_port_network_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter(yaml_file, "network", False, "OS::Neutron::Port") +@categories("environment_file") @validates("R-39841", "R-87123", "R-62590", "R-98905", "R-93030", "R-62590") def test_neutron_port_external_fixedips_ipaddress_parameter_doesnt_exist_in_environment_file( - heat_template + yaml_file ): - - 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" - exclude_parameter = re.compile(r"^(.+?)_int_(.+?)$") - - invalid_parameters = check_resource_parameter( - environment_pair, - prop, - DESIRED, - resource_type, - nested_prop=nested_prop, - exclude_parameter=exclude_parameter, - ) - - assert not invalid_parameters, ( - "{} {} external parameters" - " found in {} environment file {}".format( - resource_type, nested_prop, environment_pair.get("name"), invalid_parameters - ) + run_check_resource_parameter( + yaml_file, + "fixed_ips", + False, + "OS::Neutron::Port", + nested_prop="ip_address", + exclude_parameter=re.compile(r"^(.+?)_int_(.+?)$"), ) @validates("R-28795", "R-97201", "R-93496", "R-90206", "R-98569", "R-93496") def test_neutron_port_internal_fixedips_ipaddress_parameter_exists_in_environment_file( - heat_template + yaml_file ): - - 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 = True - resource_type = "OS::Neutron::Port" - exclude_parameter = re.compile(r"^((?!_int_).)*$") - - invalid_parameters = check_resource_parameter( - environment_pair, - prop, - DESIRED, - resource_type, - nested_prop=nested_prop, - exclude_parameter=exclude_parameter, - ) - - assert not invalid_parameters, ( - "{} {} internal parameters" - " not found in {} environment file {}".format( - resource_type, nested_prop, environment_pair.get("name"), invalid_parameters - ) + run_check_resource_parameter( + yaml_file, + "fixed_ips", + True, + "OS::Neutron::Port", + nested_prop="ip_address", + exclude_parameter=re.compile(r"^((?!_int_).)*$"), ) +@categories("environment_file") @validates("R-83677", "R-80829", "R-69634", "R-22288") def test_neutron_port_fixedips_subnet_parameter_doesnt_exist_in_environment_file( - heat_template + yaml_file ): - - 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" - 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 - ) + run_check_resource_parameter( + yaml_file, "fixed_ips", False, "OS::Neutron::Port", nested_prop="subnet" ) +@categories("environment_file") @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 - ) +def test_neutron_port_aap_ip_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, + "allowed_address_pairs", + False, + "OS::Neutron::Port", + nested_prop="ip_address", ) +@categories("environment_file") @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 - ) +def test_non_nova_server_name_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, "name", False, "OS::Nova::Server", resource_type_inverse=True ) +@categories("environment_file") @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 - ) +def test_network_fqdn_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, r"^(.+?)_net_fqdn$", False, "", check_resource=False ) +@categories("environment_file") @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 - ) +def test_contrail_route_prefixes_parameter_doesnt_exist_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, + "interface_route_table_routes", + False, + "OS::ContrailV2::InterfaceRouteTable", + nested_prop="interface_route_table_routes_route", ) @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 - ) +def test_heat_rg_count_parameter_exists_in_environment_file(yaml_file): + run_check_resource_parameter( + yaml_file, + "count", + True, + "OS::Heat::ResourceGroup", + exclude_resource=re.compile(r"^(.+?)_subint_(.+?)_port_(.+?)_subinterfaces$"), ) diff --git a/ice_validator/tests/test_filename_is_vmtype_dot_yaml.py b/ice_validator/tests/test_filename_is_vmtype_dot_yaml.py index f31f370..49c917c 100644 --- a/ice_validator/tests/test_filename_is_vmtype_dot_yaml.py +++ b/ice_validator/tests/test_filename_is_vmtype_dot_yaml.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -36,12 +36,10 @@ # ============LICENSE_END============================================ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. - import os -from tests import cached_yaml as yaml - from .helpers import validates -from .utils.vm_types import get_vm_types +from .utils.vm_types import get_all_vm_types +from .parametrizers import get_nested_files VERSION = "1.0.0" @@ -53,23 +51,17 @@ def test_filename_is_vmtype_dot_yaml(yaml_files): vm_types = [] invalid_files = [] + nested_files = [] - for yaml_file in yaml_files: - with open(yaml_file, "r") as f: - yml = yaml.load(f) - - if "resources" not in yml: - continue + nested_files.extend( + os.path.splitext(os.path.basename(filename))[0] + for filename in get_nested_files(yaml_files) + ) - vm_types.extend(get_vm_types(yml["resources"])) + vm_types = get_all_vm_types(yaml_files) - for yaml_file in yaml_files: - basename, filename = os.path.split(yaml_file) - file, ext = os.path.splitext(os.path.basename(filename)) - for vt in vm_types: - if vt == file: - invalid_files.append({"vm_type": vt, "file": yaml_file}) + invalid_files.extend(vm_type for vm_type in vm_types if vm_type in nested_files) - assert not invalid_files, "filenames must not be in format vm_type.yaml: {}".format( - invalid_files - ) + assert ( + not invalid_files + ), "Nested filenames must not be in format vm_type.yaml: {}".format(invalid_files) diff --git a/ice_validator/tests/test_nested_parameters.py b/ice_validator/tests/test_nested_parameters.py index 3e3bb06..5c93e77 100644 --- a/ice_validator/tests/test_nested_parameters.py +++ b/ice_validator/tests/test_nested_parameters.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -40,17 +40,15 @@ """heat parameters """ - import pytest from tests import cached_yaml as yaml from tests.structures import Resource - from .helpers import validates VERSION = "1.0.0" -def check_nested_parameter_doesnt_change(yaml_file, parameter): +def check_nested_parameter_doesnt_change(yaml_file): with open(yaml_file) as fh: yml = yaml.load(fh) @@ -62,37 +60,51 @@ def check_nested_parameter_doesnt_change(yaml_file, parameter): invalid_parameters = [] """ - checking if property: { get_param: }, then property == + checking if property: { get_param: parameter }, then property == parameter resource_id: type: nested.yaml properties: - property: { get_param: } + property: { get_param: parameter } resource_id: type: OS::Heat::ResourceGroup properties: resource_def: properties: - property: { get_param: } + property: { get_param: parameter } """ for resource_id, resource in yml.get("resources", {}).items(): - r = Resource(resource_id=resource_id, resource=resource) - properties = r.get_nested_properties() - for k1, v1 in properties.items(): - if ( - isinstance(v1, dict) - and "get_param" in v1 - and parameter == v1.get("get_param") - ): - if k1 != parameter: - invalid_parameters.append( - { - "resource": r.resource_id, - "nested parameter": k1, - "parameter": parameter, - } - ) + resource_type = resource.get("type") + if resource_type and ( + resource_type.endswith("yaml") + or resource_type.endswith("yml") + or resource_type == "OS::Heat::ResourceGroup" + ): + # workaround for subinterfaces + metadata = resource.get("metadata") + if metadata: + subinterface_type = metadata.get("subinterface_type") + if subinterface_type and subinterface_type == "network_collection": + continue + + r = Resource(resource_id=resource_id, resource=resource) + properties = r.get_nested_properties() + for k1, v1 in properties.items(): + if isinstance(v1, dict) and "get_param" in v1: + parameter = v1.get("get_param") + if isinstance(parameter, list): + parameter = parameter[0] + + if k1 != parameter: + invalid_parameters.append( + { + "resource": r.resource_id, + "nested parameter": k1, + "parameter": parameter, + "file": yaml_file, + } + ) assert ( not invalid_parameters @@ -101,41 +113,6 @@ def check_nested_parameter_doesnt_change(yaml_file, parameter): ) -@validates("R-70757") -def test_vm_role_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "vm_role") - - -@validates("R-44491") -def test_vnf_id_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "vnf_id") - - -@validates("R-86237") -def test_vf_module_id_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "vf_module_id") - - -@validates("R-16576") -def test_vnf_name_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "vnf_name") - - -@validates("R-49177") -def test_vf_module_name_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "vf_module_name") - - -@validates("R-22441") -def test_vf_module_index_name_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "vf_module_index") - - -@validates("R-62954") -def test_environment_context_name_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "environment_context") - - -@validates("R-75202") -def test_workload_context_name_doesnt_change_in_nested_template(yaml_file): - check_nested_parameter_doesnt_change(yaml_file, "workload_context") +@validates("R-708564") +def test_parameter_name_doesnt_change_in_nested_template(yaml_file): + check_nested_parameter_doesnt_change(yaml_file) diff --git a/ice_validator/tests/test_neutron_net_resource_id.py b/ice_validator/tests/test_neutron_net_resource_id.py index 36e77fa..1b0b322 100644 --- a/ice_validator/tests/test_neutron_net_resource_id.py +++ b/ice_validator/tests/test_neutron_net_resource_id.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -46,9 +46,9 @@ import pytest from .helpers import validates from .structures import Heat -from .structures import NeutronNet +from .structures import NeutronNetProcessor -VERSION = "1.1.0" +VERSION = "2.0.0" # pylint: disable=invalid-name @@ -62,12 +62,11 @@ def test_neutron_net_resource_id(heat_template): * int_{network-role}_network """ heat = Heat(filepath=heat_template) - neutron_nets = heat.get_resource_by_type(NeutronNet.resource_type) + neutron_nets = heat.get_resource_by_type(NeutronNetProcessor.resource_type) if not neutron_nets: pytest.skip("No neutron nets found") - neutron_net = NeutronNet() bad = [] for rid in neutron_nets: - if not neutron_net.get_rid_match_tuple(rid)[0]: + if not NeutronNetProcessor.get_rid_match_tuple(rid)[0]: bad.append("Neutron Net %s does not match any known format" % rid) assert not bad, "; ".join(bad) diff --git a/ice_validator/tests/test_neutron_port_addresses.py b/ice_validator/tests/test_neutron_port_addresses.py index 0cd6b3b..95b8ddc 100644 --- a/ice_validator/tests/test_neutron_port_addresses.py +++ b/ice_validator/tests/test_neutron_port_addresses.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -35,7 +35,6 @@ # # ============LICENSE_END============================================ # -# ECOMP is a trademark and service mark of AT&T Intellectual Property. # """ @@ -93,6 +92,8 @@ def get_port_addresses(filepath): param = heat.nested_get(aa_pair, field, "get_param") if param is None: continue + else: + param = param[0] if isinstance(param, list) else param port_addresses[field][param][basename].add(rid) return port_addresses @@ -166,6 +167,7 @@ def validate_field(heat, allowed_address_pairs, field, v6=False): break else: # if v6 and testing v6, or inverse + param = param[0] if isinstance(param, list) else param if v6 == is_v6_ip(param): ports.add(param) if error is None and len(ports) > 1: @@ -197,7 +199,7 @@ def validate_external_ipaddress_v6(heat, allowed_address_pairs): @validates("R-91810") def test_neutron_port_external_ipaddress(heat_template): """ - If a VNF requires ECOMP to assign a Virtual IP (VIP) Address to + If a VNF requires ONAP to assign a Virtual IP (VIP) Address to ports connected an external network, the port **MUST NOT** have more than one IPv4 VIP address. """ @@ -207,7 +209,7 @@ def test_neutron_port_external_ipaddress(heat_template): @validates("R-41956") def test_neutron_port_external_ipaddress_v6(heat_template): """ - If a VNF requires ECOMP to assign a Virtual IP (VIP) Address to + If a VNF requires ONAP to assign a Virtual IP (VIP) Address to ports connected an external network, the port **MUST NOT** have more than one IPv6 VIP address. """ @@ -219,7 +221,7 @@ def test_neutron_port_floating(yaml_files): """ If a VNF has two or more ports that attach to an external network that require a Virtual IP Address (VIP), - and the VNF requires ECOMP automation to assign the IP address, + and the VNF requires ONAP automation to assign the IP address, all the Virtual Machines using the VIP address **MUST** be instantiated in the same Base Module Heat Orchestration Template or in the same Incremental Module Heat Orchestration Template. @@ -231,12 +233,12 @@ def test_neutron_port_floating(yaml_files): for field, params in fields.items(): for param, files in params.items(): if len(files) > 1: - bad.append( - '"%s" "%s" in multiple templates: %s' - % ( - field, - param, - ", ".join("%s: %s" % (k, list(v)) for k, v in files.items()), + error = ["{} {} assigned in multiple templates: ".format(field, param)] + for file_name, r_ids in files.items(): + error.append( + "In {} it's assigned to {}. ".format( + file_name, ", ".join(r_ids) + ) ) - ) + bad.append("".join(error)) assert not bad, "; ".join(bad) diff --git a/ice_validator/tests/test_neutron_port_fixed_ips.py b/ice_validator/tests/test_neutron_port_fixed_ips.py index f8cb7db..f69b995 100644 --- a/ice_validator/tests/test_neutron_port_fixed_ips.py +++ b/ice_validator/tests/test_neutron_port_fixed_ips.py @@ -286,8 +286,7 @@ def test_neutron_port_external_fixed_ips(heat_template): """ When the VNF's Heat Orchestration Template's resource ``OS::Neutron::Port`` is attaching - to an external network (per the ECOMP definition, see - Requirement R-57424), + to an external network, and an IPv4 address is being cloud assigned by OpenStack's DHCP Service and the external network IPv4 subnet is to be specified using the property ``fixed_ips`` @@ -308,8 +307,7 @@ def test_neutron_port_internal_fixed_ips(heat_template): * the VNF's Heat Orchestration Template's resource ``OS::Neutron::Port`` in an Incremental Module is attaching - to an internal network (per the ECOMP definition, see - Requirements R-52425 and R-46461) + to an internal network that is created in the Base Module, AND * an IPv4 address is being cloud assigned by OpenStack's DHCP Service AND * the internal network IPv4 subnet is to be specified diff --git a/ice_validator/tests/test_neutron_port_internal_network.py b/ice_validator/tests/test_neutron_port_internal_network.py index b625be6..868930d 100644 --- a/ice_validator/tests/test_neutron_port_internal_network.py +++ b/ice_validator/tests/test_neutron_port_internal_network.py @@ -132,8 +132,7 @@ def get_neutron_ports(heat): def test_neutron_port_internal_network(yaml_files): """ When the VNF's Heat Orchestration Template's Resource - ``OS::Neutron::Port`` is attaching to an internal network (per the - ECOMP definition, see Requirements R-52425 and R-46461), + ``OS::Neutron::Port`` is attaching to an internal network, and the internal network is created in a different Heat Orchestration Template than the ``OS::Neutron::Port``, the ``network`` parameter name **MUST** diff --git a/ice_validator/tests/test_no_unused_parameters_between_env_and_templates.py b/ice_validator/tests/test_no_unused_parameters_between_env_and_templates.py deleted file mode 100644 index 333e01e..0000000 --- a/ice_validator/tests/test_no_unused_parameters_between_env_and_templates.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf8 -*- -# ============LICENSE_START======================================================= -# org.onap.vvp/validation-scripts -# =================================================================== -# Copyright © 2018 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============================================ -# -import os -import pytest - -from .helpers import validates, get_environment_pair - - -def get_keys(template, key): - """ - Gets the set of keys from an expected dict from the ``template`` mapped to - the ``key``. If the key is not found, or is not a dict, then an empty - set is returned - """ - value = template.get(key) - if not value or not hasattr(value, "keys"): - return set() - else: - return set(value.keys()) - - -@pytest.mark.heat_only -@validates("R-01896", "R-26124") -def test_no_unused_parameters_between_env_and_templates(heat_template): - """ - Check all defined parameters are used in the appropriate Heat template. - """ - environment_pair = get_environment_pair(heat_template) - if not environment_pair: - pytest.skip("No heat/env pair could be identified") - - env_parameters = get_keys(environment_pair["eyml"], "parameters") - template_parameters = get_keys(environment_pair["yyml"], "parameters") - - extra_in_template = template_parameters.difference(env_parameters) - extra_in_env = env_parameters.difference(template_parameters) - - msg = ( - "Mismatched parameters detected for the template and environment pair " - "({basename}). Ensure the parameters exist in both " - "templates indented under their respective parameters sections. " - ) - if extra_in_env: - msg += ( - "The following parameters exist in the env file, but not the " - "template: {extra_in_env}. " - ) - if extra_in_template: - msg += ( - "The following parameters exist in the template file, but not the " - "environment file: {extra_in_template}" - ) - - assert not (extra_in_template or extra_in_env), msg.format( - basename=os.path.split(environment_pair["name"])[-1], - extra_in_env=", ".join(extra_in_env), - extra_in_template=", ".join(extra_in_template), - ) diff --git a/ice_validator/tests/test_non_server_name.py b/ice_validator/tests/test_non_server_name.py index 7d88155..f47e078 100644 --- a/ice_validator/tests/test_non_server_name.py +++ b/ice_validator/tests/test_non_server_name.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -42,12 +42,15 @@ resource property name """ +import collections + import pytest from .structures import Heat +from .structures import HeatProcessor from .helpers import validates -VERSION = "1.1.0" +VERSION = "1.2.0" def get_non_servers(heat): @@ -67,7 +70,7 @@ def test_non_server_name(heat_template): """ If a VNF's Heat Orchestration Template contains the property ``name`` for a non ``OS::Nova::Server`` resource, the intrinsic function - ``str_replace`` **MUST** be used in conjunction with the ECOMP + ``str_replace`` **MUST** be used in conjunction with the ONAP supplied metadata parameter ``vnf_name`` to generate a unique value. """ @@ -138,6 +141,29 @@ def test_non_server_name(heat_template): + "template ({})" ).format(rid, vnf_name_param, template) ) - msg = "Improper name property for non-OS::Nova::Server resources. " + ". ".join(bad) + msg = ( + "Improper name property for" " non-OS::Nova::Server resources. " + ) + ". ".join(bad) assert not bad, msg + + +@validates("R-85734") +def test_non_server_name_unique(yaml_files): + """Test name has unique value + """ + non_servers = {} + for yaml_file in yaml_files: + h = Heat(filepath=yaml_file) + non_servers.update(get_non_servers(h)) + names = collections.defaultdict(set) + for rid, resource in non_servers.items(): + name = HeatProcessor.get_str_replace_name(resource) + if name: + names[name].add(rid) + bad = {key: value for key, value in names.items() if len(value) > 1} + delim = "\n" + 4 * " " + assert not bad, "Names must be unique," " not shared across resource ids.%s%s" % ( + delim, + delim.join("%s: %s" % (name, list(value)) for name, value in bad.items()), + ) diff --git a/ice_validator/tests/test_nova_server_resource_id.py b/ice_validator/tests/test_nova_server_resource_id.py index 64462a5..4410586 100644 --- a/ice_validator/tests/test_nova_server_resource_id.py +++ b/ice_validator/tests/test_nova_server_resource_id.py @@ -2,7 +2,7 @@ # ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,18 +37,16 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # - """ resources: {vm-type}_server_{vm-type_index} """ import pytest - from .structures import Heat -from .structures import NovaServer +from .structures import NovaServerProcessor from .helpers import validates -VERSION = "1.0.0" +VERSION = "2.0.0" # pylint: disable=invalid-name @@ -67,12 +65,11 @@ def test_nova_server_resource_id(heat_template): resources = heat.nova_server_resources if not resources: pytest.skip("No Nova Server resources found") - nova_server = NovaServer() bad = [] for rid in resources: - if not nova_server.get_rid_match_tuple(rid)[0]: + if not NovaServerProcessor.get_rid_match_tuple(rid)[0]: bad.append(rid) assert not bad, "Resource ids %s must match %s" % ( bad, - nova_server.get_rid_patterns(), + NovaServerProcessor.get_rid_patterns(), ) diff --git a/ice_validator/tests/test_nova_servers_resource_ids.py b/ice_validator/tests/test_nova_servers_resource_ids.py index 9747e29..b5c8754 100644 --- a/ice_validator/tests/test_nova_servers_resource_ids.py +++ b/ice_validator/tests/test_nova_servers_resource_ids.py @@ -37,10 +37,8 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # - import pytest from tests import cached_yaml as yaml - from .helpers import validates from .utils.vm_types import get_vm_type_for_nova_server @@ -102,9 +100,9 @@ def test_nova_servers_valid_resource_ids(yaml_file): ) assert not invalid_nova_servers, ( - "Invalid OS::Nova::Server resource ids detected {}\n" + "Invalid OS::Nova::Server resource ids detected {}. " "OS::Nova::Server resource ids must be in the form " - "_server_ \n" - " is derived from flavor, image and name properties " + "{{vm_type}}_server_{{vm_type_index}} where " + "{{vm_type}} is derived from flavor, image and name properties." "".format(invalid_nova_servers) ) diff --git a/ice_validator/tests/test_nova_servers_vm_types.py b/ice_validator/tests/test_nova_servers_vm_types.py index 786973e..a2d6a6e 100644 --- a/ice_validator/tests/test_nova_servers_vm_types.py +++ b/ice_validator/tests/test_nova_servers_vm_types.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -118,23 +118,17 @@ def test_vm_type_network_role_collision(yaml_file): @validates("R-50436", "R-45188", "R-40499") def test_nova_server_flavor_parameter(yaml_file): - - prop = "flavor" - check_nova_parameter_format(prop, yaml_file) + check_nova_parameter_format("flavor", yaml_file) @validates("R-51430", "R-54171", "R-87817") def test_nova_server_name_parameter(yaml_file): - - prop = "name" - check_nova_parameter_format(prop, yaml_file) + check_nova_parameter_format("name", yaml_file) @validates("R-71152", "R-57282", "R-58670") def test_nova_server_image_parameter(yaml_file): - - prop = "image" - check_nova_parameter_format(prop, yaml_file) + check_nova_parameter_format("image", yaml_file) def check_nova_parameter_format(prop, yaml_file): diff --git a/ice_validator/tests/test_oam_address_outputs.py b/ice_validator/tests/test_oam_address_outputs.py new file mode 100644 index 0000000..287d472 --- /dev/null +++ b/ice_validator/tests/test_oam_address_outputs.py @@ -0,0 +1,65 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ +# +import os + +from tests.helpers import validates +from tests.structures import Heat + +MSG = ( + "OAM management address can be declared as output in at most 1 template. " + + "Output parameter {} found in multiple templates: {}" +) + + +def find_output_param(param, templates): + templates = (t for t in templates if param in Heat(t).outputs) + return [os.path.basename(t) for t in templates] + + +@validates("R-18683") +def test_oam_address_v4_zero_or_one(heat_templates): + param = "oam_management_v4_address" + templates = find_output_param(param, heat_templates) + assert len(templates) <= 1, MSG.format(param, ", ".join(templates)) + + +@validates("R-94669") +def test_oam_address_v6_zero_or_one(heat_templates): + param = "oam_management_v6_address" + templates = find_output_param(param, heat_templates) + assert len(templates) <= 1, MSG.format(param, ", ".join(templates)) diff --git a/ice_validator/tests/test_port_resource_ids.py b/ice_validator/tests/test_port_resource_ids.py index f53370d..be80fe9 100644 --- a/ice_validator/tests/test_port_resource_ids.py +++ b/ice_validator/tests/test_port_resource_ids.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -52,7 +52,7 @@ from .utils.network_roles import ( from .utils.vm_types import get_vm_type_for_nova_server -@validates("R-20453", "R-26351", "R-26506" "R-681859") +@validates("R-20453", "R-26351", "R-26506", "R-681859") def test_port_resource_ids(heat_template): """ Check that all resource ids for ports follow the right diff --git a/ice_validator/tests/test_server_and_port_vm_indices_match.py b/ice_validator/tests/test_server_and_port_vm_indices_match.py new file mode 100644 index 0000000..20423bb --- /dev/null +++ b/ice_validator/tests/test_server_and_port_vm_indices_match.py @@ -0,0 +1,84 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ +# +import re + +from tests.helpers import validates +from tests.structures import Heat +from tests.utils import nested_dict + +SERVER_ID_PATTERN = re.compile(r"\w+_server_(\d+)") +PORT_ID_PATTERN = re.compile(r"\w+_(\d+)_\w+\d+") + + +def get_ports(server): + props = server.get("properties") or {} + networks = props.get("networks") or [] + for network in networks: + r_id = nested_dict.get(network, "port", "get_resource") + if r_id: + yield r_id + + +@validates("R-304011") +def test_server_and_port_vmtype_indices_match(yaml_file): + # NOTE: This test is only going to validate that the index values + # match between the between the ports and server names. Other + # tests already cover the other aspects of this requirement + + heat = Heat(filepath=yaml_file) + servers = heat.get_resource_by_type("OS::Nova::Server") + errors = [] + for r_id, server in servers.items(): + match = SERVER_ID_PATTERN.match(r_id) + if not match: + continue # other tests cover valid server ID format + server_index = match.group(1) + ports = get_ports(server) + for port in ports: + port_match = PORT_ID_PATTERN.match(port) + if port_match: + port_vm_index = port_match.group(1) + if port_vm_index != server_index: + errors.append( + ( + "{{vm-type_index}} ({}) in port ID ({}) " + + "does not match the {{index}} ({}) in the " + + "servers resource ID ({})" + ).format(port_vm_index, port, server_index, r_id) + ) + assert not errors, ". ".join(errors) diff --git a/ice_validator/tests/test_servers_have_required_metadata.py b/ice_validator/tests/test_servers_have_required_metadata.py index 8ea8869..4f76e7b 100644 --- a/ice_validator/tests/test_servers_have_required_metadata.py +++ b/ice_validator/tests/test_servers_have_required_metadata.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -35,8 +35,6 @@ # # ============LICENSE_END============================================ # -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# import pytest from tests import cached_yaml as yaml @@ -48,12 +46,11 @@ from .helpers import validates def test_servers_have_required_metadata(yaml_file): """ Check all defined nova server instances have the required metadata: - vnf_id and vf_module_id + vnf_id, vf_module_id, and vnf_name """ with open(yaml_file) as fh: yml = yaml.load(fh) - # Check if the param vm_role is defined if "resources" not in yml: pytest.skip("No resources specified in the heat template") diff --git a/ice_validator/tests/test_vm_class_has_unique_type.py b/ice_validator/tests/test_vm_class_has_unique_type.py new file mode 100644 index 0000000..684c1b4 --- /dev/null +++ b/ice_validator/tests/test_vm_class_has_unique_type.py @@ -0,0 +1,155 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + +"""heat parameters +""" + +import collections + +import pytest + +from .structures import CinderVolumeAttachmentProcessor +from .structures import NovaServerProcessor +from .structures import get_all_resources +from .helpers import validates + +VERSION = "2.0.0" + + +class VmClassValidator(object): + """validate VM class has unique type + """ + + def __init__(self): + self.vm_counts = None + self.vm_classes = None + self.vm_rids = None + self.vm_types = None + self.va_count = None + + def __call__(self, resources): + """return (possibly empty) list of error message strings + """ + if not resources: + pytest.skip("No resources found") + self.vm_counts = collections.defaultdict(set) + self.vm_classes = collections.defaultdict(set) + self.vm_rids = collections.defaultdict(set) + self.vm_types = collections.defaultdict(set) + va_config, self.va_count = CinderVolumeAttachmentProcessor.get_config(resources) + if not va_config: + pytest.skip("No Cinder Volume Attachment configurations found") + for rid, resource in resources.items(): + vm_class = NovaServerProcessor.get_vm_class(resource) + if vm_class: + vm_class["cinder_volume_attachment"] = va_config.get(rid) + match = NovaServerProcessor.get_rid_match_tuple(rid)[1] + if match: + vm_type = match.groupdict().get("vm_type") + if vm_type: + self.vm_classes[vm_class].add(rid) + self.vm_types[vm_type].add(vm_class) + self.vm_counts[vm_type].add(self.va_count.get(rid)) + self.vm_rids[vm_type].add(rid) + if not self.vm_classes: + pytest.skip("No vm_classes found") + return self.get_errors() + + def get_errors(self): + """return (possibly empty) list of error message strings + """ + errors = [] + for k, v in self.vm_types.items(): + if len(v) > 1: + errors.append( + "vm-type %s has class conflict %s" + % (k, ", ".join(str(list(self.vm_classes[c])) for c in v)) + ) + classes = list(v) + errors.append( + "Differences %s" + % ", ".join([str(key_diff(classes[0], c)) for c in classes[1:]]) + ) + for k, v in self.vm_counts.items(): + if len(v) > 1: + errors.append( + "Attachment count conflict %s" + % ({rid: self.va_count.get(rid) for rid in self.vm_rids[k]}) + ) + return errors + + +def key_diff(d1, d2, prefix=""): + """Return list of keys which differ between d1 and d2 (dicts) + """ + diff = [prefix + k for k in d1 if k not in d2] + diff.extend(prefix + k for k in d2 if k not in d1) + if isinstance(d1, dict) and isinstance(d2, dict): + for k, v1 in d1.items(): + if k in d2 and v1 != d2[k]: + v2 = d2[k] + if isinstance(v1, type(v2)) and isinstance(v1, (dict, frozenset)): + diff.extend(key_diff(v1, v2, prefix=prefix + k + ".")) + else: + diff.append(prefix + k) + return diff + + +@validates("R-01455") +def test_vm_class_has_unique_type(yaml_files): + """ + When a VNF’s Heat Orchestration Template creates a Virtual + Machine (i.e., OS::Nova::Server), each “class” of VMs MUST be + assigned a VNF unique vm-type; where “class” defines VMs that + MUST have the following identical characteristics: + + 1. OS::Nova::Server resource property flavor value + 2. OS::Nova::Server resource property image value + 3. Cinder Volume attachments + Each VM in the “class” MUST have the identical Cinder + Volume configuration + 4. Network attachments and IP address requirements + Each VM in the “class” MUST have the the identical number of + ports connecting to the identical networks and requiring the + identical IP address configuration + """ + resources = get_all_resources(yaml_files) + errors = VmClassValidator()(resources) + assert not errors, "\n".join(errors) diff --git a/ice_validator/tests/test_vm_role_value.py b/ice_validator/tests/test_vm_role_value.py new file mode 100644 index 0000000..e7da73d --- /dev/null +++ b/ice_validator/tests/test_vm_role_value.py @@ -0,0 +1,99 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START======================================================= +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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============================================ +# +import re + +import pytest +from six import string_types + +from tests.helpers import validates, get_environment_pair +from tests.structures import Heat + + +@validates("R-86476") +def test_vm_role_hardcoded(yaml_file): + """ + Validate vm_role value when hardcoded in the template + """ + heat = Heat(filepath=yaml_file) + servers = heat.get_resource_by_type("OS::Nova::Server") + errors = [] + for r_id, server in servers.items(): + props = server.get("properties") or {} + metadata = props.get("metadata") or {} + if "vm_role" not in metadata: + continue + vm_role_value = metadata["vm_role"] + if isinstance(vm_role_value, dict): + continue # Likely using get_param - validate separately + if not re.match(r"^\w+$", vm_role_value): + errors.append( + "OS::Nova::Server {} vm_role = {}".format(r_id, vm_role_value) + ) + + msg = ( + "vm_role's value must only contain alphanumerics and underscores. " + + "Invalid vm_role's detected: " + + ". ".join(errors) + ) + assert not errors, msg + + +@validates("R-86476") +def test_vm_role_from_env_file(heat_template): + """ + Validate vm_role when using parameters and env file + """ + pair = get_environment_pair(heat_template) + if not pair: + pytest.skip("Unable to resolve environment pair") + template_params = pair["yyml"].get("parameters") or {} + env_params = pair["eyml"].get("parameters") or {} + + if "vm_role" not in template_params: + pytest.skip("vm_role not in parameters") + + if "vm_role" not in env_params: + pytest.skip("vm_role not in environment file. Error checked elsewhere") + + vm_role = env_params.get("vm_role", "") + if not isinstance(vm_role, string_types): + vm_role = str(vm_role) + msg = "vm_role {} contains non-alphanumeric or non-underscore characters".format( + vm_role + ) + assert re.match(r"^\w+$", vm_role), msg diff --git a/ice_validator/tests/test_volume_module_naming.py b/ice_validator/tests/test_volume_module_naming.py index 770ad26..68c2158 100644 --- a/ice_validator/tests/test_volume_module_naming.py +++ b/ice_validator/tests/test_volume_module_naming.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2018 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -36,6 +36,7 @@ # ============LICENSE_END============================================ import os +from tests.helpers import validates from tests.parametrizers import get_nested_files from tests.structures import Heat, Resource @@ -45,7 +46,7 @@ def non_nested_files(filenames): return set(filenames).difference(set(nested_files)) -# No requirement ID yet available +@validates("R-589037") def test_detected_volume_module_follows_naming_convention(template_dir): all_files = [os.path.join(template_dir, f) for f in os.listdir(template_dir)] yaml_files = [f for f in all_files if f.endswith(".yaml") or f.endswith(".yml")] diff --git a/ice_validator/tests/test_volume_resource_ids.py b/ice_validator/tests/test_volume_resource_ids.py index dc5ed7d..3beb79f 100644 --- a/ice_validator/tests/test_volume_resource_ids.py +++ b/ice_validator/tests/test_volume_resource_ids.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,12 +37,9 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # - import re - import pytest from tests import cached_yaml as yaml - from .utils.vm_types import get_vm_type_for_nova_server diff --git a/ice_validator/tests/utils/vm_types.py b/ice_validator/tests/utils/vm_types.py index 78006b9..327b75b 100644 --- a/ice_validator/tests/utils/vm_types.py +++ b/ice_validator/tests/utils/vm_types.py @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -39,6 +39,7 @@ # import re +from tests import cached_yaml as yaml def get_vm_types_for_resource(resource): @@ -111,3 +112,20 @@ def get_vm_types(resources): vm_types.extend(list(get_vm_types_for_resource(v))) return set(vm_types) + + +def get_all_vm_types(yaml_files): + """ + Get all vm_types for a list of yaml files + """ + vm_types = [] + for yaml_file in yaml_files: + with open(yaml_file, "r") as f: + yml = yaml.load(f) + + if "resources" not in yml: + continue + + vm_types.extend(get_vm_types(yml["resources"])) + + return set(vm_types) diff --git a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.env b/ice_validator/version.py similarity index 91% rename from ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.env rename to ice_validator/version.py index 487bc4e..d32636e 100644 --- a/ice_validator/tests/fixtures/test_no_unused_parameters_between_env_and_templates/fail/unused_param.env +++ b/ice_validator/version.py @@ -1,8 +1,8 @@ # -*- coding: utf8 -*- -# ============LICENSE_START======================================================= +# ============LICENSE_START==================================================== # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -37,10 +37,5 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. # ---- -parameters: - out: 2 - res: 3 - indexed: 4 - unused_env: 4 - indx: 1 \ No newline at end of file + +VERSION = "1.0.0" diff --git a/ice_validator/vvp-config.yaml b/ice_validator/vvp-config.yaml new file mode 100644 index 0000000..93532b3 --- /dev/null +++ b/ice_validator/vvp-config.yaml @@ -0,0 +1,51 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + +ui: + app-name: VNF Validation Tool +categories: + - name: Environment File Compliance. (Required to Onboard) + category: environment_file + description: + Checks certain parameters are excluded from the .env file, per HOT Requirements. + Required for ASDC onboarding, not needed for manual Openstack testing. +settings: + polling-freqency: 1000 + default-verbosity: Standard diff --git a/ice_validator/vvp.py b/ice_validator/vvp.py new file mode 100644 index 0000000..9c63168 --- /dev/null +++ b/ice_validator/vvp.py @@ -0,0 +1,781 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 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. +# + +""" +A GUI that wraps the pytest validations scripts. + +To make an executable for windows execute the ``make_exe.bat`` to generate the +.exe and its associated files. The the necessary files will be written to the +``dist/vvp/`` directory. This entire directory must be copied to the target machine. + +NOTE: This script does require Python 3.6+ +""" +import appdirs +import os +import pytest +import sys +import version +import yaml +import contextlib +import multiprocessing +import queue +import tempfile +import webbrowser +import zipfile + +from collections import MutableMapping +from configparser import ConfigParser +from multiprocessing import Queue +from pathlib import Path +from shutil import rmtree +from tkinter import ( + filedialog, + font, + messagebox, + Tk, + PanedWindow, + BOTH, + HORIZONTAL, + RAISED, + Frame, + Label, + W, + StringVar, + OptionMenu, + LabelFrame, + E, + BooleanVar, + Entry, + Button, + WORD, + END, + Checkbutton, + IntVar, + Toplevel, +) +from tkinter.scrolledtext import ScrolledText +from typing import Optional, List, Dict, TextIO, Callable, Iterator + +VERSION = version.VERSION +PATH = os.path.dirname(os.path.realpath(__file__)) +OUT_DIR = "output" + + +class ToolTip(object): + """ + create a tooltip for a given widget + """ + + def __init__(self, widget, text="widget info"): + self.waittime = 750 # miliseconds + self.wraplength = 180 # pixels + self.widget = widget + self.text = text + self.widget.bind("", self.enter) + self.widget.bind("", self.leave) + self.widget.bind("", self.leave) + self.id = None + self.tw = None + + def enter(self, event=None): + self.schedule() + + def leave(self, event=None): + self.unschedule() + self.hidetip() + + def schedule(self): + self.unschedule() + self.id = self.widget.after(self.waittime, self.showtip) + + def unschedule(self): + id = self.id + self.id = None + if id: + self.widget.after_cancel(id) + + def showtip(self, event=None): + x = y = 0 + x, y, cx, cy = self.widget.bbox("insert") + x += self.widget.winfo_rootx() + 25 + y += self.widget.winfo_rooty() + 20 + # creates a toplevel window + self.tw = Toplevel(self.widget) + # Leaves only the label and removes the app window + self.tw.wm_overrideredirect(True) + self.tw.wm_geometry("+%d+%d" % (x, y)) + label = Label( + self.tw, + text=self.text, + justify="left", + background="#ffffff", + relief="solid", + borderwidth=1, + wraplength=self.wraplength, + ) + label.pack(ipadx=1) + + def hidetip(self): + tw = self.tw + self.tw = None + if tw: + tw.destroy() + + +class QueueWriter: + """``stdout`` and ``stderr`` will be written to this queue by pytest, and + pulled into the main GUI application""" + + def __init__(self, log_queue: queue.Queue): + """Writes data to the provided queue. + + :param log_queue: the queue instance to write to. + """ + self.queue = log_queue + + def write(self, data: str): + """Writes ``data`` to the queue """ + self.queue.put(data) + + # noinspection PyMethodMayBeStatic + def isatty(self) -> bool: + """Always returns ``False``""" + return False + + def flush(self): + """No operation method to satisfy file-like behavior""" + pass + + +def get_plugins() -> Optional[List]: + """When running in a frozen bundle, plugins need to be registered + explicitly. This method will return the required plugins to register + based on the run mode""" + if hasattr(sys, "frozen"): + import pytest_tap.plugin + + return [pytest_tap.plugin] + else: + return None + + +def run_pytest( + template_dir: str, + log: TextIO, + result_queue: Queue, + categories: Optional[list], + verbosity: str, + report_format: str, + halt_on_failure: bool, + template_source: str, +): + """Runs pytest using the given ``profile`` in a background process. All + ``stdout`` and ``stderr`` are redirected to ``log``. The result of the job + will be put on the ``completion_queue`` + + :param template_dir: The directory containing the files to be validated. + :param log: ` `stderr`` and ``stdout`` of the pytest job will be + directed here + :param result_queue: Completion status posted here. See :class:`Config` + for more information. + :param categories: list of optional categories. When provided, pytest + will collect and execute all tests that are + decorated with any of the passed categories, as + well as tests not decorated with a category. + :param verbosity: Flag to be passed to pytest to control verbosity. + Options are '' (empty string), '-v' (verbose), + '-vv' (more verbose). + :param report_format: Determines the style of report written. Options are + csv, html, or excel + :param halt_on_failure: Determines if validation will halt when basic failures + are encountered in the input files. This can help + prevent a large number of errors from flooding the + report. + """ + out_path = "{}/{}".format(PATH, OUT_DIR) + if os.path.exists(out_path): + rmtree(out_path, ignore_errors=True) + with contextlib.redirect_stderr(log), contextlib.redirect_stdout(log): + try: + args = [ + "--ignore=app_tests", + "--capture=sys", + verbosity, + "--template-directory={}".format(template_dir), + "--report-format={}".format(report_format), + "--template-source={}".format(template_source), + ] + if categories: + for category in categories: + args.extend(("--category", category)) + if not halt_on_failure: + args.append("--continue-on-failure") + pytest.main(args=args, plugins=get_plugins()) + result_queue.put((True, None)) + except Exception as e: + result_queue.put((False, e)) + + +class UserSettings(MutableMapping): + FILE_NAME = "UserSettings.ini" + + def __init__(self): + user_config_dir = appdirs.AppDirs("org.onap.vvp", "ONAP").user_config_dir + if not os.path.exists(user_config_dir): + os.makedirs(user_config_dir, exist_ok=True) + self._settings_path = os.path.join(user_config_dir, self.FILE_NAME) + self._config = ConfigParser() + self._config.read(self._settings_path) + + def __getitem__(self, k): + return self._config["DEFAULT"][k] + + def __setitem__(self, k, v) -> None: + self._config["DEFAULT"][k] = v + + def __delitem__(self, v) -> None: + del self._config["DEFAULT"][v] + + def __len__(self) -> int: + return len(self._config["DEFAULT"]) + + def __iter__(self) -> Iterator: + return iter(self._config["DEFAULT"]) + + def save(self): + with open(self._settings_path, "w") as f: + self._config.write(f) + + +class Config: + """ + Configuration for the Validation GUI Application + + Attributes + ---------- + ``log_queue`` Queue for the ``stdout`` and ``stderr` of + the background job + ``log_file`` File-like object (write only!) that writes to + the ``log_queue`` + ``status_queue`` Job completion status of the background job is + posted here as a tuple of (bool, Exception). + The first parameter is True if the job completed + successfully, and False otherwise. If the job + failed, then an Exception will be provided as the + second element. + ``command_queue`` Used to send commands to the GUI. Currently only + used to send shutdown commands in tests. + """ + + DEFAULT_FILENAME = "vvp-config.yaml" + DEFAULT_POLLING_FREQUENCY = "1000" + + def __init__(self, config: dict = None): + """Creates instance of application configuration. + + :param config: override default configuration if provided.""" + if config: + self._config = config + else: + with open(self.DEFAULT_FILENAME, "r") as f: + self._config = yaml.load(f) + self._user_settings = UserSettings() + self._watched_variables = [] + self._validate() + self._manager = multiprocessing.Manager() + self.log_queue = self._manager.Queue() + self.status_queue = self._manager.Queue() + self.log_file = QueueWriter(self.log_queue) + self.command_queue = self._manager.Queue() + + def watch(self, *variables): + """Traces the variables and saves their settings for the user. The + last settings will be used where available""" + self._watched_variables = variables + for var in self._watched_variables: + var.trace_add("write", self.save_settings) + + def save_settings(self, *args): + """Save the value of all watched variables to user settings""" + for var in self._watched_variables: + self._user_settings[var._name] = str(var.get()) + self._user_settings.save() + + @property + def app_name(self) -> str: + """Name of the application (displayed in title bar)""" + app_name = self._config["ui"].get("app-name", "VNF Validation Tool") + return "{} - {}".format(app_name, VERSION) + + @property + def category_names(self) -> List[str]: + """List of validation profile names for display in the UI""" + return [category["name"] for category in self._config["categories"]] + + @property + def polling_frequency(self) -> int: + """Returns the frequency (in ms) the UI polls the queue communicating + with any background job""" + return int( + self._config["settings"].get( + "polling-frequency", self.DEFAULT_POLLING_FREQUENCY + ) + ) + + def default_verbosity(self, levels: Dict[str, str]) -> str: + requested_level = self._user_settings.get("verbosity") or self._config[ + "settings" + ].get("default-verbosity", "Standard") + keys = [key for key in levels] + for key in levels: + if key.lower().startswith(requested_level.lower()): + return key + raise RuntimeError( + "Invalid default-verbosity level {}. Valid" + "values are {}".format(requested_level, ", ".join(keys)) + ) + + def get_description(self, category_name: str) -> str: + """Returns the description associated with the category name""" + return self._get_category(category_name)["description"] + + def get_category(self, category_name: str) -> str: + """Returns the category associated with the category name""" + return self._get_category(category_name).get("category", "") + + def get_category_value(self, category_name: str) -> str: + """Returns the saved value for a category name""" + return self._user_settings.get(category_name, 0) + + def _get_category(self, category_name: str) -> Dict[str, str]: + """Returns the profile definition""" + for category in self._config["categories"]: + if category["name"] == category_name: + return category + raise RuntimeError( + "Unexpected error: No category found in vvp-config.yaml " + "with a name of " + category_name + ) + + @property + def default_report_format(self): + return self._user_settings.get("report_format", "HTML") + + @property + def report_formats(self): + return ["CSV", "Excel", "HTML"] + + @property + def default_input_format(self): + requested_default = self._user_settings.get("input_format") or self._config[ + "settings" + ].get("default-input-format") + if requested_default in self.input_formats: + return requested_default + else: + return self.input_formats[0] + + @property + def input_formats(self): + return ["Directory (Uncompressed)", "ZIP File"] + + @property + def default_halt_on_failure(self): + setting = self._user_settings.get("halt_on_failure", "True") + return setting.lower() == "true" + + def _validate(self): + """Ensures the config file is properly formatted""" + categories = self._config["categories"] + + # All profiles have required keys + expected_keys = {"name", "description"} + for category in categories: + actual_keys = set(category.keys()) + missing_keys = expected_keys.difference(actual_keys) + if missing_keys: + raise RuntimeError( + "Error in vvp-config.yaml file: " + "Required field missing in category. " + "Missing: {} " + "Categories: {}".format(",".join(missing_keys), category) + ) + + +class ValidatorApp: + VERBOSITY_LEVELS = {"Less": "", "Standard (-v)": "-v", "More (-vv)": "-vv"} + + def __init__(self, config: Config = None): + """Constructs the GUI element of the Validation Tool""" + self.task = None + self.config = config or Config() + + self._root = Tk() + self._root.title(self.config.app_name) + self._root.protocol("WM_DELETE_WINDOW", self.shutdown) + + main_window = PanedWindow(self._root) + main_window.pack(fill=BOTH, expand=1) + + control_panel = PanedWindow( + main_window, orient=HORIZONTAL, sashpad=4, sashrelief=RAISED + ) + actions = Frame(control_panel) + control_panel.add(actions) + control_panel.paneconfigure(actions, minsize=250) + + # profile start + number_of_categories = len(self.config.category_names) + category_frame = LabelFrame(actions, text="Additional Validation Categories:") + category_frame.grid(row=1, column=1, columnspan=3, pady=5, sticky="we") + + self.categories = [] + + for x in range(0, number_of_categories): + category_name = self.config.category_names[x] + category_value = IntVar(value=0) + category_value._name = "category_{}".format(category_name.replace(" ", "_")) + category_value.set(self.config.get_category_value(category_value._name)) + self.categories.append(category_value) + category_checkbox = Checkbutton( + category_frame, text=category_name, variable=self.categories[x] + ) + ToolTip(category_checkbox, self.config.get_description(category_name)) + category_checkbox.grid(row=x + 1, column=1, columnspan=2, sticky="w") + + settings_frame = LabelFrame(actions, text="Settings") + settings_frame.grid(row=3, column=1, columnspan=3, pady=10, sticky="we") + verbosity_label = Label(settings_frame, text="Verbosity:") + verbosity_label.grid(row=1, column=1, sticky=W) + self.verbosity = StringVar(self._root, name="verbosity") + self.verbosity.set(self.config.default_verbosity(self.VERBOSITY_LEVELS)) + verbosity_menu = OptionMenu( + settings_frame, self.verbosity, *tuple(self.VERBOSITY_LEVELS.keys()) + ) + verbosity_menu.config(width=25) + verbosity_menu.grid(row=1, column=2, columnspan=3, sticky=E, pady=5) + + report_format_label = Label(settings_frame, text="Report Format:") + report_format_label.grid(row=2, column=1, sticky=W) + self.report_format = StringVar(self._root, name="report_format") + self.report_format.set(self.config.default_report_format) + report_format_menu = OptionMenu( + settings_frame, self.report_format, *self.config.report_formats + ) + report_format_menu.config(width=25) + report_format_menu.grid(row=2, column=2, columnspan=3, sticky=E, pady=5) + + input_format_label = Label(settings_frame, text="Input Format:") + input_format_label.grid(row=3, column=1, sticky=W) + self.input_format = StringVar(self._root, name="input_format") + self.input_format.set(self.config.default_input_format) + input_format_menu = OptionMenu( + settings_frame, self.input_format, *self.config.input_formats + ) + input_format_menu.config(width=25) + input_format_menu.grid(row=3, column=2, columnspan=3, sticky=E, pady=5) + + self.halt_on_failure = BooleanVar(self._root, name="halt_on_failure") + self.halt_on_failure.set(self.config.default_halt_on_failure) + halt_on_failure_label = Label(settings_frame, text="Halt on Basic Failures:") + halt_on_failure_label.grid(row=4, column=1, sticky=E, pady=5) + halt_checkbox = Checkbutton( + settings_frame, offvalue=False, onvalue=True, variable=self.halt_on_failure + ) + halt_checkbox.grid(row=4, column=2, columnspan=2, sticky=W, pady=5) + + directory_label = Label(actions, text="Template Location:") + directory_label.grid(row=4, column=1, pady=5, sticky=W) + self.template_source = StringVar(self._root, name="template_source") + directory_entry = Entry(actions, width=40, textvariable=self.template_source) + directory_entry.grid(row=4, column=2, pady=5, sticky=W) + directory_browse = Button(actions, text="...", command=self.ask_template_source) + directory_browse.grid(row=4, column=3, pady=5, sticky=W) + + validate = Button(actions, text="Validate Templates", command=self.validate) + validate.grid(row=5, column=1, columnspan=2, pady=5) + + self.result_panel = Frame(actions) + # We'll add these labels now, and then make them visible when the run completes + self.completion_label = Label(self.result_panel, text="Validation Complete!") + self.result_label = Label( + self.result_panel, text="View Report", fg="blue", cursor="hand2" + ) + self.underline(self.result_label) + self.result_label.bind("", self.open_report) + self.result_panel.grid(row=6, column=1, columnspan=2) + control_panel.pack(fill=BOTH, expand=1) + + main_window.add(control_panel) + + self.log_panel = ScrolledText(main_window, wrap=WORD, width=120, height=20) + self.log_panel.configure(font=font.Font(family="Courier New", size="11")) + self.log_panel.pack(fill=BOTH, expand=1) + + main_window.add(self.log_panel) + + # Briefly add the completion and result labels so the window size includes + # room for them + self.completion_label.pack() + self.result_label.pack() # Show report link + self._root.after_idle( + lambda: ( + self.completion_label.pack_forget(), + self.result_label.pack_forget(), + ) + ) + + self.config.watch( + *self.categories, + self.verbosity, + self.input_format, + self.report_format, + self.halt_on_failure, + ) + self.schedule(self.execute_pollers) + + def ask_template_source(self): + if self.input_format.get() == "ZIP File": + template_source = filedialog.askopenfilename( + title="Select Archive", + filetypes=(("ZIP Files", "*.zip"), ("All Files", "*")), + ) + else: + template_source = filedialog.askdirectory() + self.template_source.set(template_source) + + def validate(self): + """Run the pytest validations in a background process""" + if not self.delete_prior_report(): + return + + if not self.template_source.get(): + self.ask_template_source() + + template_dir = self.resolve_template_dir() + + if template_dir: + self.kill_background_task() + self.clear_log() + self.completion_label.pack_forget() + self.result_label.pack_forget() + self.task = multiprocessing.Process( + target=run_pytest, + args=( + template_dir, + self.config.log_file, + self.config.status_queue, + self.categories_list(), + self.VERBOSITY_LEVELS[self.verbosity.get()], + self.report_format.get().lower(), + self.halt_on_failure.get(), + self.template_source.get(), + ), + ) + self.task.daemon = True + self.task.start() + + @property + def title(self): + """Returns the text displayed in the title bar of the application""" + return self._root.title() + + def execute_pollers(self): + """Call all methods that require periodic execution, and re-schedule + their execution for the next polling interval""" + try: + self.poll_log_file() + self.poll_status_queue() + self.poll_command_queue() + finally: + self.schedule(self.execute_pollers) + + @staticmethod + def _drain_queue(q): + """Yields values from the queue until empty""" + while True: + try: + yield q.get(block=False) + except queue.Empty: + break + + def poll_command_queue(self): + """Picks up command strings from the commmand queue, and + dispatches it for execution. Only SHUTDOWN is supported + currently""" + for command in self._drain_queue(self.config.command_queue): + if command == "SHUTDOWN": + self.shutdown() + + def poll_status_queue(self): + """Checks for completion of the job, and then displays the View Report link + if it was successful or writes the exception to the ``log_panel`` if + it fails.""" + for is_success, e in self._drain_queue(self.config.status_queue): + if is_success: + self.completion_label.pack() + self.result_label.pack() # Show report link + else: + self.log_panel.insert(END, str(e)) + + def poll_log_file(self): + """Reads captured stdout and stderr from the log queue and writes it to the + log panel.""" + for line in self._drain_queue(self.config.log_queue): + self.log_panel.insert(END, line) + self.log_panel.see(END) + + def schedule(self, func: Callable): + """Schedule the callable ``func`` to be executed according to + the polling_frequency""" + self._root.after(self.config.polling_frequency, func) + + def clear_log(self): + """Removes all log entries from teh log panel""" + self.log_panel.delete("1.0", END) + + def delete_prior_report(self) -> bool: + """Attempts to delete the current report, and pops up a warning message + to the user if it can't be deleted. This will force the user to + close the report before re-running the validation. Returns True if + the file was deleted or did not exist, or False otherwise""" + if not os.path.exists(self.report_file_path): + return True + + try: + os.remove(self.report_file_path) + return True + except OSError as e: + messagebox.showerror( + "Error", + "Please close or rename the open report file before re-validating", + ) + return False + + @property + def report_file_path(self): + ext_mapping = {"csv": "csv", "html": "html", "excel": "xlsx"} + ext = ext_mapping.get(self.report_format.get().lower()) + return os.path.join(PATH, OUT_DIR, "report.{}".format(ext)) + + def open_report(self, event): + """Open the report in the user's default browser""" + webbrowser.open_new("file://{}".format(self.report_file_path)) + + def start(self): + """Start the event loop of the application. This method does not return""" + self._root.mainloop() + + @staticmethod + def underline(label): + """Apply underline format to an existing label""" + f = font.Font(label, label.cget("font")) + f.configure(underline=True) + label.configure(font=f) + + def kill_background_task(self): + if self.task and self.task.is_alive(): + self.task.terminate() + for _ in self._drain_queue(self.config.log_queue): + pass + + def shutdown(self): + """Shutdown the application""" + self.kill_background_task() + self._root.destroy() + + def check_template_source_is_valid(self): + """Verifies the value of template source exists and of valid type based + on input setting""" + if not self.template_source.get(): + return False + template_path = Path(self.template_source.get()) + + if not template_path.exists(): + messagebox.showerror( + "Error", + "Input does not exist. Please provide a valid file or directory.", + ) + return False + + if self.input_format.get() == "ZIP File": + if zipfile.is_zipfile(template_path): + return True + else: + messagebox.showerror( + "Error", "Expected ZIP file, but input is not a valid ZIP file" + ) + return False + else: + if template_path.is_dir(): + return True + else: + messagebox.showerror( + "Error", "Expected directory, but input is not a directory" + ) + return False + + def resolve_template_dir(self) -> str: + """Extracts the zip file to a temporary directory if needed, otherwise + returns the directory supplied to template source. Returns empty string + if the template source isn't valid""" + if not self.check_template_source_is_valid(): + return "" + if self.input_format.get() == "ZIP File": + temp_dir = tempfile.mkdtemp() + archive = zipfile.ZipFile(self.template_source.get()) + archive.extractall(path=temp_dir) + return temp_dir + else: + return self.template_source.get() + + def categories_list(self) -> list: + categories = [] + selected_categories = self.categories + for x in range(0, len(selected_categories)): + if selected_categories[x].get(): + category = self.config.category_names[x] + categories.append(self.config.get_category(category)) + return categories + + +if __name__ == "__main__": + multiprocessing.freeze_support() # needed for PyInstaller to work + ValidatorApp().start() diff --git a/requirements.txt b/requirements.txt index e073b97..0c2112a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ # ============LICENSE_START======================================================= # org.onap.vvp/validation-scripts # =================================================================== -# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. # =================================================================== # # Unless otherwise specified, all software contained herein is licensed @@ -49,3 +49,4 @@ appdirs==1.4.3 jinja2==2.10 yamllint==1.12.1 six==1.12.0 +pyinstaller diff --git a/tox.ini b/tox.ini index c8468a5..34ba2cd 100644 --- a/tox.ini +++ b/tox.ini @@ -40,23 +40,25 @@ [tox] skipsdist=True -envlist = py3,style +envlist = py36,style [testenv] distribute = False +basepython = python3.6 commands = {envpython} --version pytest --version coverage run --module pytest ice_validator/tests --self-test -rxXs coverage xml -deps = -rrequirements.txt +deps = --no-use-pep517 + -rrequirements.txt flake8==3.4.1 coverage==4.5.1 [testenv:style] commands = flake8 ice_validator -[testenv:py3] +[testenv:py36] basepython=python3.6 [flake8] -- 2.16.6