summaryrefslogtreecommitdiffstats
path: root/ice_validator/tests
diff options
context:
space:
mode:
Diffstat (limited to 'ice_validator/tests')
-rw-r--r--ice_validator/tests/cached_yaml.py (renamed from ice_validator/tests/test_env_files_provided.py)32
-rw-r--r--ice_validator/tests/conftest.py343
-rw-r--r--ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/valid_template.yaml8
-rw-r--r--ice_validator/tests/fixtures/test_fixed_ips_include_vm_type_network_role/pass/valid_template.yaml8
-rw-r--r--ice_validator/tests/helpers.py20
-rw-r--r--ice_validator/tests/parametrizers.py446
-rw-r--r--ice_validator/tests/report.html.jinja2220
-rw-r--r--ice_validator/tests/structures.py32
-rw-r--r--ice_validator/tests/test_all_referenced_resources_exists.py76
-rw-r--r--ice_validator/tests/test_allowed_address_pair_format.py177
-rw-r--r--ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py32
-rw-r--r--ice_validator/tests/test_availability_zone_get_param.py73
-rw-r--r--ice_validator/tests/test_base_template_outputs_consumed.py100
-rw-r--r--ice_validator/tests/test_fixed_ips_format.py123
-rw-r--r--ice_validator/tests/test_fixed_ips_format_use_get_param.py81
-rw-r--r--ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py16
-rw-r--r--ice_validator/tests/test_heat_template_and_env_file_extension.py82
-rw-r--r--ice_validator/tests/test_heat_templates_provided.py46
-rw-r--r--ice_validator/tests/test_nested_templates.py69
-rw-r--r--ice_validator/tests/test_nested_templates_invalid_nesting.py63
-rw-r--r--ice_validator/tests/test_no_unused_parameters_between_env_and_templates.py38
-rw-r--r--ice_validator/tests/test_nova_servers_correct_parameter_types.py114
-rw-r--r--ice_validator/tests/test_parse_yaml.py62
-rw-r--r--ice_validator/tests/test_referenced_and_defined_parameters_match.py54
-rw-r--r--ice_validator/tests/test_required_parameters_specified_in_env_files.py11
-rw-r--r--ice_validator/tests/test_reserve_port_fixed_ips_format.py118
-rw-r--r--ice_validator/tests/test_reserve_port_fixed_ips_has_base_outputs.py114
-rw-r--r--ice_validator/tests/test_reserve_port_only_in_base_template.py78
-rw-r--r--ice_validator/tests/test_volume_templates_outputs_resources.py4
-rw-r--r--ice_validator/tests/utils/nested_dict.py1
-rw-r--r--ice_validator/tests/utils/nested_files.py69
-rw-r--r--ice_validator/tests/utils/network_roles.py90
-rw-r--r--ice_validator/tests/utils/ports.py189
-rw-r--r--ice_validator/tests/utils/vm_types.py33
-rw-r--r--ice_validator/tests/utils/volumes.py2
35 files changed, 983 insertions, 2041 deletions
diff --git a/ice_validator/tests/test_env_files_provided.py b/ice_validator/tests/cached_yaml.py
index d784d20..99fbd2c 100644
--- a/ice_validator/tests/test_env_files_provided.py
+++ b/ice_validator/tests/cached_yaml.py
@@ -34,19 +34,27 @@
# limitations under the License.
#
# ============LICENSE_END============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-'''
-test_env_files_provided
-'''
+import os
+
+import yaml
+
+YAML_CACHE = {}
+resolver = yaml.resolver
+YAMLError = yaml.YAMLError
+constructor = yaml.constructor
+
-VERSION = '1.0.0'
+def add_constructor(tag, constructor):
+ yaml.add_constructor(
+ tag,
+ constructor,
+ )
-def test_env_files_provided(env_files):
- '''
- Make sure environment files have been provided
- '''
- assert len(env_files) > 0, '"*.env" not found'
+def load(fp):
+ """Provides cached loading of yaml files"""
+ abs_path = os.path.abspath(fp.name)
+ if abs_path not in YAML_CACHE:
+ YAML_CACHE[abs_path] = yaml.safe_load(fp)
+ return YAML_CACHE[abs_path]
diff --git a/ice_validator/tests/conftest.py b/ice_validator/tests/conftest.py
index f5f25a3..a08b99a 100644
--- a/ice_validator/tests/conftest.py
+++ b/ice_validator/tests/conftest.py
@@ -45,8 +45,10 @@ import os
import sys
import time
import requests
+import traceback
import docutils.core
+import jinja2
import pytest
from more_itertools import partition
from six import string_types
@@ -55,9 +57,7 @@ import xlsxwriter
__path__ = [os.path.dirname(os.path.abspath(__file__))]
resolution_steps_file = "resolution_steps.json"
-requirements_file = "requirements.json"
-
-FAILURE_DATA = {}
+heat_requirements_file = "heat_requirements.json"
report_columns = [
("Input File", "file"),
@@ -69,6 +69,12 @@ report_columns = [
]
report = collections.OrderedDict(report_columns)
+COLLECTION_FAILURES = []
+COLLECTION_FAILURE_WARNING = """WARNING: The following unexpected errors occurred
+while preparing to validate the the input files. Some validations may not have been
+executed. Please refer these issue to the VNF Validation Tool team.
+"""
+
def extract_error_msg(rep):
try:
@@ -92,6 +98,11 @@ def pytest_runtest_makereport(item, call):
if rep.outcome == "failed":
if not os.path.exists(output_dir):
os.mkdir(output_dir)
+ if os.path.exists("{}/failures".format(output_dir)):
+ with open("{}/failures".format(output_dir), "r") as o:
+ jdata = json.loads(o.read())
+ else:
+ jdata = {}
if hasattr(item.function, "requirement_ids"):
requirement_ids = item.function.requirement_ids
@@ -113,17 +124,31 @@ def pytest_runtest_makereport(item, call):
else:
resolved_pair = rep.nodeid.split("[")[1][:-1]
- FAILURE_DATA[len(FAILURE_DATA)] = {
+ markers = set(m.name for m in item.iter_markers())
+ base_test = "base" in markers
+
+ msg = extract_error_msg(rep)
+ if base_test:
+ msg = "!!Base Test Failure!! Halting test suite execution...\n{}".format(
+ msg
+ )
+
+ jdata[len(jdata)] = {
"file": resolved_pair,
"vnfrqts": requirement_ids,
"test": item.function.__name__,
"test_file": item.function.__module__.split(".")[-1],
"raw_output": str(rep.longrepr),
- "message": extract_error_msg(rep),
+ "message": msg,
}
with open("{}/failures".format(output_dir), "w") as f:
- json.dump(FAILURE_DATA, f, indent=4)
+ json.dump(jdata, f, indent=4)
+
+ if not item.config.option.continue_on_failure and base_test:
+ pytest.exit(
+ "{}\n{}\n{}".format(msg, resolved_pair, item.function.__name__)
+ )
def make_timestamp():
@@ -144,13 +169,31 @@ def pytest_sessionfinish(session, exitstatus):
)
-def pytest_runtest_setup(item):
- profile = item.session.config.option.validation_profile
- markers = set(m.name for m in item.iter_markers())
- if not profile and markers and "xfail" not in markers:
- pytest.skip("No validation profile selected. Skipping tests with marks.")
- if profile and markers and profile not in markers and "xfail" not in markers:
- pytest.skip("Doesn't match selection validation profile")
+def pytest_collection_modifyitems(session, config, items):
+ 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")
+ )
+
+ items.sort(
+ key=lambda item: 0 if "base" in set(m.name for m in item.iter_markers()) else 1
+ )
def make_href(path):
@@ -158,10 +201,10 @@ def make_href(path):
links = []
for p in paths:
abs_path = os.path.abspath(p)
- filename = os.path.split(abs_path)[1]
+ name = abs_path if os.path.isdir(abs_path) else os.path.split(abs_path)[1]
links.append(
- "<a href='file://{abs_path}' target='_blank'>{filename}</a>".format(
- abs_path=abs_path, filename=filename
+ "<a href='file://{abs_path}' target='_blank'>{name}</a>".format(
+ abs_path=abs_path, name=name
)
)
return "<br/>".join(links)
@@ -184,7 +227,7 @@ def generate_report(outpath, template_path, profile_name, output_format):
with open(resolution_steps, "r") as f:
rdata = json.loads(f.read())
- heat_requirements = "{}/../{}".format(__path__[0], requirements_file)
+ heat_requirements = "{}/../{}".format(__path__[0], heat_requirements_file)
if os.path.exists(heat_requirements):
with open(heat_requirements, "r") as f:
hdata = json.loads(f.read())
@@ -203,6 +246,7 @@ def generate_report(outpath, template_path, profile_name, output_format):
# mapping resolution steps to module and test name
for k, v in faildata.items():
+ # resolution_step = ""
faildata[k]["resolution_steps"] = ""
for rs in rdata:
if v["test_file"] == rs["module"] and v["test"] == rs["function"]:
@@ -221,21 +265,33 @@ def generate_report(outpath, template_path, profile_name, output_format):
def generate_csv_report(output_dir, profile_name, template_path, faildata):
- rows = []
- rows.append(["Validation Failures"])
+ rows = [["Validation Failures"]]
headers = [
("Profile Selected:", profile_name),
("Report Generated At:", make_timestamp()),
("Directory Validated:", template_path),
("Checksum:", hash_directory(template_path)),
- ("Total Errors:", len(faildata)),
+ ("Total Errors:", len(faildata) + len(COLLECTION_FAILURES)),
]
-
rows.append([])
for header in headers:
rows.append(header)
rows.append([])
+ if COLLECTION_FAILURES:
+ rows.append([COLLECTION_FAILURE_WARNING])
+ rows.append(["Validation File", "Test", "Fixtures", "Error"])
+ for failure in COLLECTION_FAILURES:
+ rows.append(
+ [
+ failure["module"],
+ failure["test"],
+ ";".join(failure["fixtures"]),
+ failure["error"],
+ ]
+ )
+ rows.append([])
+
# table header
rows.append([col for col, _ in report_columns])
@@ -274,7 +330,7 @@ def generate_excel_report(output_dir, profile_name, template_path, faildata):
("Report Generated At:", make_timestamp()),
("Directory Validated:", template_path),
("Checksum:", hash_directory(template_path)),
- ("Total Errors:", len(faildata)),
+ ("Total Errors:", len(faildata) + len(COLLECTION_FAILURES)),
]
for row, (header, value) in enumerate(headers, start=2):
worksheet.write(row, 0, header, bold)
@@ -283,13 +339,26 @@ def generate_excel_report(output_dir, profile_name, template_path, faildata):
worksheet.set_column(0, len(headers) - 1, 40)
worksheet.set_column(len(headers), len(headers), 80)
+ if COLLECTION_FAILURES:
+ collection_failures_start = 2 + len(headers) + 2
+ worksheet.write(collection_failures_start, 0, COLLECTION_FAILURE_WARNING, bold)
+ collection_failure_headers = ["Validation File", "Test", "Fixtures", "Error"]
+ for col_num, col_name in enumerate(collection_failure_headers):
+ worksheet.write(collection_failures_start + 1, col_num, col_name, bold)
+ for row, data in enumerate(COLLECTION_FAILURES, collection_failures_start + 2):
+ worksheet.write(row, 0, data["module"])
+ worksheet.write(row, 1, data["test"])
+ worksheet.write(row, 2, ",".join(data["fixtures"]))
+ worksheet.write(row, 3, data["error"], code)
+
# table header
- start_error_table_row = 2 + len(headers) + 2
+ start_error_table_row = 2 + len(headers) + len(COLLECTION_FAILURES) + 4
+ worksheet.write(start_error_table_row, 0, "Validation Failures", bold)
for col_num, (col_name, _) in enumerate(report_columns):
- worksheet.write(start_error_table_row, col_num, col_name, bold)
+ worksheet.write(start_error_table_row + 1, col_num, col_name, bold)
# table content
- for row, data in enumerate(faildata.values(), start=start_error_table_row + 1):
+ for row, data in enumerate(faildata.values(), start=start_error_table_row + 2):
for col, key in enumerate(report.values()):
if key == "file":
paths = (
@@ -306,70 +375,35 @@ def generate_excel_report(output_dir, profile_name, template_path, faildata):
def generate_html_report(outpath, profile_name, template_path, faildata):
- with open("{}/report.html".format(outpath), "w") as of:
- body_begin = """
- <style type="text/css">
- h1, li {{
- font-family:Arial, sans-serif;
- }}
- .tg {{border-collapse:collapse;border-spacing:0;}}
- .tg td{{font-family:Arial, sans-serif;font-size:8px;padding:10px 5px;
- border-style:solid;border-width:1px;overflow:hidden;word-break:normal;
- border-color:black;}}
- .tg th{{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;
- padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;
- word-break:normal;border-color:black;}}
- .tg .tg-rwj1{{font-size:10px;font-family:Arial, Helvetica,
- sans-serif !important;;border-color:inherit;vertical-align:top}}</style>
- <h1>Validation Failures</h1>
- <ul>
- <li><b>Profile Selected: </b> <tt>{profile}</tt></li>
- <li><b>Report Generated At:</b> <tt>{timestamp}</tt></li>
- <li><b>Directory Validated:</b> <tt>{template_dir}</tt></li>
- <li><b>Checksum:</b> <tt>{checksum}</tt></li>
- <li><b>Total Errors:</b> {num_failures}</li>
- </ul>
- """.format(
- profile=profile_name,
- timestamp=make_timestamp(),
+ failures = []
+ for data in faildata.values():
+ failures.append(
+ {
+ "file_links": make_href(data["file"]),
+ "test_id": data["test_file"],
+ "error_message": data["message"],
+ "raw_output": data["raw_output"],
+ "requirements": docutils.core.publish_parts(
+ writer_name="html", source=data["req_description"]
+ )["body"],
+ "resolution_steps": data["resolution_steps"],
+ }
+ )
+ pkg_dir = os.path.split(__file__)[0]
+ j2_template_path = os.path.join(pkg_dir, "report.html.jinja2")
+ with open(j2_template_path, "r") as f:
+ report_template = jinja2.Template(f.read())
+ contents = report_template.render(
+ num_failures=len(failures) + len(COLLECTION_FAILURES),
+ profile_name=profile_name,
+ template_dir=make_href(template_path),
checksum=hash_directory(template_path),
- template_dir=template_path,
- num_failures=len(faildata),
+ timestamp=make_timestamp(),
+ failures=failures,
+ collection_failures=COLLECTION_FAILURES,
)
- of.write(body_begin)
-
- if len(faildata) == 0:
- of.write("<p>Success! No validation failures detected.</p>")
- return
-
- table_begin = '<table class="tg">'
- of.write(table_begin)
-
- # table headers
- of.write("<tr>")
- for k, v in report.items():
- of.write('<th class="tg-rwj1">{}</th>'.format(k))
- of.write("</tr>")
-
- # table content
- for k, v in faildata.items():
- of.write("<tr>")
- for rk, rv in report.items():
- if rv == "file":
- value = make_href(v[rv])
- elif rv == "raw_output":
- value = "<pre>{}</pre>".format(v[rv])
- elif rv == "req_description":
- parts = docutils.core.publish_parts(
- writer_name="html", source=v[rv]
- )
- value = parts["body"]
- else:
- value = v[rv].replace("\n", "<br />")
- of.write(" <td>{}</td>".format(value))
- of.write("</tr>")
-
- of.write("</table>")
+ with open(os.path.join(outpath, "report.html"), "w") as f:
+ f.write(contents)
def pytest_addoption(parser):
@@ -411,6 +445,13 @@ def pytest_addoption(parser):
help="Format of output report (html, csv, excel)",
)
+ parser.addoption(
+ "--continue-on-failure",
+ dest="continue_on_failure",
+ action="store_true",
+ help="Continue validation even when structural errors exist in input files",
+ )
+
def pytest_configure(config):
"""
@@ -420,9 +461,9 @@ def pytest_configure(config):
if config.getoption("template_dir") and config.getoption("self_test"):
raise Exception('"--template-dir", and "--self-test"' " are mutually exclusive")
if not (
- config.getoption("template_dir") or
- config.getoption("self_test") or
- config.getoption("help")
+ config.getoption("template_dir")
+ or config.getoption("self_test")
+ or config.getoption("help")
):
raise Exception('One of "--template-dir" or' ' "--self-test" must be specified')
@@ -435,90 +476,107 @@ def pytest_generate_tests(metafunc):
is not specified on the CLI, the fixtures associated with this
test name.
"""
- if "filename" in metafunc.fixturenames:
- from .parametrizers import parametrize_filename
- parametrize_filename(metafunc)
+ # noinspection PyBroadException
+ try:
+ if "filename" in metafunc.fixturenames:
+ from .parametrizers import parametrize_filename
+
+ parametrize_filename(metafunc)
- if "filenames" in metafunc.fixturenames:
- from .parametrizers import parametrize_filenames
+ if "filenames" in metafunc.fixturenames:
+ from .parametrizers import parametrize_filenames
- parametrize_filenames(metafunc)
+ parametrize_filenames(metafunc)
- if "template_dir" in metafunc.fixturenames:
- from .parametrizers import parametrize_template_dir
+ if "template_dir" in metafunc.fixturenames:
+ from .parametrizers import parametrize_template_dir
- parametrize_template_dir(metafunc)
+ parametrize_template_dir(metafunc)
- if "environment_pair" in metafunc.fixturenames:
- from .parametrizers import parametrize_environment_pair
+ if "environment_pair" in metafunc.fixturenames:
+ from .parametrizers import parametrize_environment_pair
- parametrize_environment_pair(metafunc)
+ parametrize_environment_pair(metafunc)
- if "heat_volume_pair" in metafunc.fixturenames:
- from .parametrizers import parametrize_heat_volume_pair
+ if "heat_volume_pair" in metafunc.fixturenames:
+ from .parametrizers import parametrize_heat_volume_pair
- parametrize_heat_volume_pair(metafunc)
+ parametrize_heat_volume_pair(metafunc)
- if "yaml_files" in metafunc.fixturenames:
- from .parametrizers import parametrize_yaml_files
+ if "yaml_files" in metafunc.fixturenames:
+ from .parametrizers import parametrize_yaml_files
- parametrize_yaml_files(metafunc)
+ parametrize_yaml_files(metafunc)
- if "env_files" in metafunc.fixturenames:
- from .parametrizers import parametrize_environment_files
+ if "env_files" in metafunc.fixturenames:
+ from .parametrizers import parametrize_environment_files
- parametrize_environment_files(metafunc)
+ parametrize_environment_files(metafunc)
- if "yaml_file" in metafunc.fixturenames:
- from .parametrizers import parametrize_yaml_file
+ if "yaml_file" in metafunc.fixturenames:
+ from .parametrizers import parametrize_yaml_file
- parametrize_yaml_file(metafunc)
+ parametrize_yaml_file(metafunc)
- if "env_file" in metafunc.fixturenames:
- from .parametrizers import parametrize_environment_file
+ if "env_file" in metafunc.fixturenames:
+ from .parametrizers import parametrize_environment_file
- parametrize_environment_file(metafunc)
+ parametrize_environment_file(metafunc)
- if "parsed_yaml_file" in metafunc.fixturenames:
- from .parametrizers import parametrize_parsed_yaml_file
+ if "parsed_yaml_file" in metafunc.fixturenames:
+ from .parametrizers import parametrize_parsed_yaml_file
- parametrize_parsed_yaml_file(metafunc)
+ parametrize_parsed_yaml_file(metafunc)
- if "parsed_environment_file" in metafunc.fixturenames:
- from .parametrizers import parametrize_parsed_environment_file
+ if "parsed_environment_file" in metafunc.fixturenames:
+ from .parametrizers import parametrize_parsed_environment_file
- parametrize_parsed_environment_file(metafunc)
+ parametrize_parsed_environment_file(metafunc)
- if "heat_template" in metafunc.fixturenames:
- from .parametrizers import parametrize_heat_template
+ if "heat_template" in metafunc.fixturenames:
+ from .parametrizers import parametrize_heat_template
- parametrize_heat_template(metafunc)
+ parametrize_heat_template(metafunc)
- if "heat_templates" in metafunc.fixturenames:
- from .parametrizers import parametrize_heat_templates
+ if "heat_templates" in metafunc.fixturenames:
+ from .parametrizers import parametrize_heat_templates
- parametrize_heat_templates(metafunc)
+ parametrize_heat_templates(metafunc)
- if "volume_template" in metafunc.fixturenames:
- from .parametrizers import parametrize_volume_template
+ if "volume_template" in metafunc.fixturenames:
+ from .parametrizers import parametrize_volume_template
- parametrize_volume_template(metafunc)
+ parametrize_volume_template(metafunc)
- if "volume_templates" in metafunc.fixturenames:
- from .parametrizers import parametrize_volume_templates
+ if "volume_templates" in metafunc.fixturenames:
+ from .parametrizers import parametrize_volume_templates
- parametrize_volume_templates(metafunc)
+ parametrize_volume_templates(metafunc)
- if "template" in metafunc.fixturenames:
- from .parametrizers import parametrize_template
+ if "template" in metafunc.fixturenames:
+ from .parametrizers import parametrize_template
- parametrize_template(metafunc)
+ parametrize_template(metafunc)
- if "templates" in metafunc.fixturenames:
- from .parametrizers import parametrize_templates
+ if "templates" in metafunc.fixturenames:
+ from .parametrizers import parametrize_templates
- parametrize_templates(metafunc)
+ parametrize_templates(metafunc)
+ except Exception as e:
+ # If an error occurs in the collection phase, then it won't be logged as a
+ # normal test failure. This means that failures could occur, but not
+ # be seen on the report resulting in a false positive success message. These
+ # errors will be stored and reported separately on the report
+ COLLECTION_FAILURES.append(
+ {
+ "module": metafunc.module.__name__,
+ "test": metafunc.function.__name__,
+ "fixtures": metafunc.fixturenames,
+ "error": traceback.format_exc(),
+ }
+ )
+ raise e
def hash_directory(path):
@@ -538,7 +596,7 @@ def load_current_requirements():
r = requests.get(url)
with open('requirements.json', 'wb') as needs:
needs.write(r.content)
- path = "requirements.json"
+ path = "heat_requirements.json"
if not os.path.exists(path):
return {}
with io.open(path, encoding="utf8", mode="r") as f:
@@ -562,6 +620,7 @@ def unicode_writerow(writer, row):
def pytest_report_collectionfinish(config, startdir, items):
+
"""Generates a simple traceability report to output/traceability.csv"""
traceability_path = os.path.join(__path__[0], "../output/traceability.csv")
output_dir = os.path.split(traceability_path)[0]
diff --git a/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/valid_template.yaml b/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/valid_template.yaml
index 8b291bd..e219ab4 100644
--- a/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/valid_template.yaml
+++ b/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/valid_template.yaml
@@ -97,11 +97,11 @@ parameters:
description: db_int_intranet_v6_ip_0
db_int_intranet_ips:
- type: string
+ type: comma_delimited_list
description: db_int_intranet_ips
db_int_intranet_v6_ips:
- type: string
+ type: comma_delimited_list
description: db_int_intranet_v6_ips
db_int_intranet_floating_ip:
@@ -121,11 +121,11 @@ parameters:
description: lb_extnet_v6_ip_0
lb_extnet_ips:
- type: string
+ type: comma_delimited_list
description: lb_extnet_ips
lb_extnet_v6_ips:
- type: string
+ type: comma_delimited_list
description: lb_extnet_v6_ips
lb_extnet_floating_ip:
diff --git a/ice_validator/tests/fixtures/test_fixed_ips_include_vm_type_network_role/pass/valid_template.yaml b/ice_validator/tests/fixtures/test_fixed_ips_include_vm_type_network_role/pass/valid_template.yaml
index cbd60b5..8bb53ac 100644
--- a/ice_validator/tests/fixtures/test_fixed_ips_include_vm_type_network_role/pass/valid_template.yaml
+++ b/ice_validator/tests/fixtures/test_fixed_ips_include_vm_type_network_role/pass/valid_template.yaml
@@ -97,11 +97,11 @@ parameters:
description: db_int_intranet_v6_ip_0
db_int_intranet_ips:
- type: string
+ type: comma_delimited_list
description: db_int_intranet_ips
db_int_intranet_v6_ips:
- type: string
+ type: comma_delimited_list
description: db_int_intranet_v6_ips
lb_extnet_ip_0:
@@ -117,11 +117,11 @@ parameters:
description: lb_extnet_v6_ip_0
lb_extnet_ips:
- type: string
+ type: comma_delimited_list
description: lb_extnet_ips
lb_extnet_v6_ips:
- type: string
+ type: comma_delimited_list
description: lb_extnet_v6_ips
resources:
diff --git a/ice_validator/tests/helpers.py b/ice_validator/tests/helpers.py
index 5e4f3d3..502d3aa 100644
--- a/ice_validator/tests/helpers.py
+++ b/ice_validator/tests/helpers.py
@@ -41,8 +41,9 @@
"""Helpers
"""
+import os
from boltons import funcutils
-import yaml
+from tests import cached_yaml as yaml
VERSION = '1.1.0'
@@ -106,3 +107,20 @@ def validates(*requirement_ids):
return wrapper
decorator.requirement_ids = requirement_ids
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)
+ basename = os.path.splitext(filename)[0]
+ env_template = os.path.join(base_dir, "{}.env".format(basename))
+ if os.path.exists(env_template):
+ with open(heat_template, "r") as fh:
+ yyml = yaml.load(fh)
+ with open(env_template, "r") as fh:
+ eyml = yaml.load(fh)
+
+ environment_pair = {"name": basename, "yyml": yyml, "eyml": eyml}
+ return environment_pair
+
+ return None
diff --git a/ice_validator/tests/parametrizers.py b/ice_validator/tests/parametrizers.py
index 511c39a..641d53a 100644
--- a/ice_validator/tests/parametrizers.py
+++ b/ice_validator/tests/parametrizers.py
@@ -43,37 +43,35 @@
from os import path, listdir
import re
-import yaml
+from tests import cached_yaml as yaml
import pytest
from .helpers import get_parsed_yml_for_yaml_files, check_basename_ending
from .utils.nested_files import get_list_of_nested_files
-VERSION = "1.0.0"
-
+VERSION = '1.0.0'
# pylint: disable=invalid-name
def get_template_dir(metafunc):
- """
+ '''
returns template_dir, either as its passed in on CLI
or, during --self-test, the directory whos name matches
the current tests module name
- """
- if metafunc.config.getoption("template_dir") is None:
+ '''
+ if metafunc.config.getoption('template_dir') is None:
return path.join(
path.dirname(path.realpath(__file__)),
- "fixtures",
- metafunc.function.__module__.split(".")[-1],
- )
+ 'fixtures',
+ metafunc.function.__module__.split('.')[-1])
else:
- return metafunc.config.getoption("template_dir")[0]
+ return metafunc.config.getoption('template_dir')[0]
def get_nested_files(filenames):
- """
+ '''
returns all the nested files for a set of filenames
- """
+ '''
nested_files = []
for filename in filenames:
try:
@@ -81,319 +79,334 @@ def get_nested_files(filenames):
yml = yaml.load(fh)
if "resources" not in yml:
continue
- nested_files.extend(
- get_list_of_nested_files(yml["resources"], path.dirname(filename))
- )
+ nested_files.extend(get_list_of_nested_files(
+ yml["resources"],
+ path.dirname(filename)))
except yaml.YAMLError as e:
print(e) # pylint: disable=superfluous-parens
continue
return nested_files
-def list_filenames_in_template_dir(
- metafunc, extensions, template_type="", sub_dirs=None
-):
- """
+def list_filenames_in_template_dir(metafunc,
+ extensions,
+ template_type='',
+ sub_dirs=None):
+ '''
returns the filenames in a template_dir, either as its passed in
on CLI or, during --self-test, the directory whos name matches
the current tests module name
- """
+ '''
sub_dirs = [] if sub_dirs is None else sub_dirs
template_dir = get_template_dir(metafunc)
filenames = []
- if metafunc.config.getoption("self_test"):
- filenames = [
- path.join(template_dir, s, f)
- for s in sub_dirs
- for f in listdir(path.join(template_dir, s))
- if (path.isfile(path.join(template_dir, s, f)) and
- path.splitext(f)[-1] in extensions and
- check_basename_ending(template_type, path.splitext(f)[0]))
- ]
+ if metafunc.config.getoption('self_test'):
+ filenames = [path.join(template_dir, s, f)
+ for s in sub_dirs
+ for f in listdir(path.join(template_dir, s))
+ if path.isfile(path.join(template_dir, s, f))
+ and path.splitext(f)[-1] in extensions
+ and check_basename_ending(template_type,
+ path.splitext(f)[0])]
else:
- filenames = [
- path.join(template_dir, f)
- for f in listdir(template_dir)
- if (path.isfile(path.join(template_dir, f)) and
- path.splitext(f)[-1] in extensions and
- check_basename_ending(template_type, path.splitext(f)[0]))
- ]
+ filenames = [path.join(template_dir, f)
+ for f in listdir(template_dir)
+ if path.isfile(path.join(template_dir, f))
+ and path.splitext(f)[-1] in extensions
+ and check_basename_ending(template_type,
+ path.splitext(f)[0])]
return filenames
-def list_template_dir(
- metafunc, extensions, exclude_nested=True, template_type="", sub_dirs=None
-):
- """
+def list_template_dir(metafunc,
+ extensions,
+ exclude_nested=True,
+ template_type='',
+ sub_dirs=None):
+ '''
returns the filenames excluding the nested files for a template_dir,
either as its passed in on CLI or, during --self-test, the
directory whos name matches the current tests module name
- """
+ '''
sub_dirs = [] if sub_dirs is None else sub_dirs
filenames = []
nested_files = []
- filenames = list_filenames_in_template_dir(
- metafunc, extensions, template_type, sub_dirs
- )
+ filenames = list_filenames_in_template_dir(metafunc,
+ extensions,
+ template_type,
+ sub_dirs)
if exclude_nested:
nested_files = get_nested_files(filenames)
return list(set(filenames) - set(nested_files))
-def get_filenames_list(
- metafunc, extensions=None, exclude_nested=False, template_type=""
-):
- """
+def get_filenames_list(metafunc,
+ extensions=None,
+ exclude_nested=False,
+ template_type=''):
+ '''
returns the filename fixtures for the template dir, either as by how its
passed in on CLI or, during --self-test, the directory whos name
matches the current tests module name
- """
- extensions = [".yaml", ".yml", ".env"] if extensions is None else extensions
- if metafunc.config.getoption("self_test"):
- filenames_list = list_template_dir(
- metafunc, extensions, exclude_nested, template_type, ["pass"]
- )
- filenames_list += [
- pytest.mark.xfail(f, strict=True)
- for f in list_template_dir(
- metafunc, extensions, exclude_nested, template_type, ["fail"]
- )
- ]
+ '''
+ extensions = [".yaml",
+ ".yml",
+ ".env"] if extensions is None else extensions
+ if metafunc.config.getoption('self_test'):
+ filenames_list = list_template_dir(metafunc,
+ extensions,
+ exclude_nested,
+ template_type,
+ ['pass'])
+ filenames_list += [pytest.mark.xfail(f, strict=True)
+ for f in list_template_dir(metafunc,
+ extensions,
+ exclude_nested,
+ template_type,
+ ['fail'])]
else:
- filenames_list = list_template_dir(
- metafunc, extensions, exclude_nested, template_type
- )
+ filenames_list = list_template_dir(metafunc,
+ extensions,
+ exclude_nested,
+ template_type)
return filenames_list
-def get_filenames_lists(
- metafunc, extensions=None, exclude_nested=False, template_type=""
-):
- """
+def get_filenames_lists(metafunc,
+ extensions=None,
+ exclude_nested=False,
+ template_type=''):
+ '''
returns the list of files in the template dir, either as by how its
passed in on CLI or, during --self-test, the directory whos name
matches the current tests module name
- """
- extensions = [".yaml", ".yml", ".env"] if extensions is None else extensions
+ '''
+ extensions = [".yaml",
+ ".yml",
+ ".env"] if extensions is None else extensions
filenames_lists = []
- if metafunc.config.getoption("self_test"):
- filenames_lists.append(
- list_template_dir(
- metafunc, extensions, exclude_nested, template_type, ["pass"]
- )
- )
- filenames_lists.append(
- pytest.mark.xfail(
- list_template_dir(
- metafunc, extensions, exclude_nested, template_type, ["fail"]
- ),
- strict=True,
- )
- )
+ if metafunc.config.getoption('self_test'):
+ filenames_lists.append(list_template_dir(metafunc,
+ extensions,
+ exclude_nested,
+ template_type,
+ ['pass']))
+ filenames_lists.append(pytest.mark.xfail(
+ list_template_dir(metafunc,
+ extensions,
+ exclude_nested,
+ template_type,
+ ['fail']), strict=True))
else:
- filenames_lists.append(
- list_template_dir(metafunc, extensions, exclude_nested, template_type)
- )
+ filenames_lists.append(list_template_dir(metafunc,
+ extensions,
+ exclude_nested,
+ template_type))
return filenames_lists
-def get_parsed_yaml_files(
- metafunc, extensions, exclude_nested=True, template_type="", sections=None
-):
- """
+def get_parsed_yaml_files(metafunc,
+ extensions,
+ exclude_nested=True,
+ template_type='',
+ sections=None):
+ '''
returns the list of parsed yaml files in the specified template dir,
either as by how its passed in on CLI or, during --self-test, the
directory whos name matches the current tests module name
- """
+ '''
sections = [] if sections is None else sections
extensions = [".yaml", ".yml"]
- if metafunc.config.getoption("self_test"):
- yaml_files = list_template_dir(
- metafunc, extensions, exclude_nested, template_type, ["pass"]
- )
- parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files, sections)
-
- yaml_files = list_template_dir(
- metafunc, extensions, exclude_nested, template_type, ["fail"]
- )
- parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files, sections)
- parsed_yml_list += [
- pytest.mark.xfail(parsed_yml, strict=True) for parsed_yml in parsed_yml_list
- ]
+ if metafunc.config.getoption('self_test'):
+ yaml_files = list_template_dir(metafunc, extensions, exclude_nested,
+ template_type, ['pass'])
+ parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files,
+ sections)
+
+ yaml_files = list_template_dir(metafunc, extensions, exclude_nested,
+ template_type, ['fail'])
+ parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files,
+ sections)
+ parsed_yml_list += [pytest.mark.xfail(parsed_yml, strict=True)
+ for parsed_yml in parsed_yml_list]
else:
yaml_files = list_template_dir(metafunc, extensions)
- parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files, sections)
+ parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files,
+ sections)
return parsed_yml_list
def parametrize_filenames(metafunc):
- """
+ '''
This param runs tests all files in the template dir
- """
+ '''
filenames = get_filenames_lists(metafunc)
- metafunc.parametrize("filenames", filenames)
+ metafunc.parametrize('filenames', filenames)
def parametrize_filename(metafunc):
- """
+ '''
This param runs tests once for every file in the template dir
- """
+ '''
filenames = get_filenames_list(metafunc)
- metafunc.parametrize("filename", filenames)
+ metafunc.parametrize('filename', filenames)
def parametrize_yaml_files(metafunc):
- """
+ '''
This param runs tests for the yaml files in the template dir
- """
- yaml_files = get_filenames_lists(metafunc, [".yaml", ".yml"], False)
+ '''
+ yaml_files = get_filenames_lists(metafunc, ['.yaml', '.yml'], False)
metafunc.parametrize("yaml_files", yaml_files)
def parametrize_yaml_file(metafunc):
- """
+ '''
This param runs tests for every yaml file in the template dir
- """
- yaml_files = get_filenames_list(metafunc, [".yaml", ".yml"], False)
- metafunc.parametrize("yaml_file", yaml_files)
+ '''
+ yaml_files = get_filenames_list(metafunc, ['.yaml', '.yml'], False)
+ metafunc.parametrize('yaml_file', yaml_files)
def parametrize_templates(metafunc):
- """
+ '''
This param runs tests for the template in the template dir
- """
- templates = get_filenames_lists(metafunc, [".yaml", ".yml"], True)
+ '''
+ templates = get_filenames_lists(metafunc, ['.yaml', '.yml'], True)
metafunc.parametrize("templates", templates)
def parametrize_template(metafunc):
- """
+ '''
This param runs tests for every template in the template dir
- """
- templates = get_filenames_list(metafunc, [".yaml", ".yml"], True)
- metafunc.parametrize("template", templates)
+ '''
+ templates = get_filenames_list(metafunc, ['.yaml', '.yml'], True)
+ metafunc.parametrize('template', templates)
def parametrize_parsed_yaml_file(metafunc):
- """
+ '''
This param runs tests for a parsed version of each yaml file
in the template dir
- """
- parsed_yaml_files = get_parsed_yaml_files(metafunc, [".yaml", ".yml"], False)
- metafunc.parametrize("parsed_yaml_file", parsed_yaml_files)
+ '''
+ parsed_yaml_files = get_parsed_yaml_files(metafunc, ['.yaml', '.yml'],
+ False)
+ metafunc.parametrize('parsed_yaml_file', parsed_yaml_files)
def parametrize_heat_templates(metafunc):
- """
+ '''
This param runs tests for all heat templates in the template dir
- """
- heat_templates = get_filenames_lists(metafunc, [".yaml", ".yml"], True, "heat")
- metafunc.parametrize("heat_templates", heat_templates)
+ '''
+ heat_templates = get_filenames_lists(metafunc, ['.yaml', '.yml'],
+ True, 'heat')
+ metafunc.parametrize('heat_templates', heat_templates)
def parametrize_heat_template(metafunc):
- """
+ '''
This param runs tests for every heat template in the template dir
- """
- heat_templates = get_filenames_list(metafunc, [".yaml", ".yml"], True, "heat")
- metafunc.parametrize("heat_template", heat_templates)
+ '''
+ heat_templates = get_filenames_list(metafunc, ['.yaml', '.yml'],
+ True, 'heat')
+ metafunc.parametrize('heat_template', heat_templates)
def parametrize_volume_templates(metafunc):
- """
+ '''
This param runs tests for all volume templates in the template dir
- """
- volume_templates = get_filenames_lists(metafunc, [".yaml", ".yml"], True, "volume")
- metafunc.parametrize("volume_templates", volume_templates)
+ '''
+ volume_templates = get_filenames_lists(metafunc, ['.yaml', '.yml'],
+ True, 'volume')
+ metafunc.parametrize('volume_templates', volume_templates)
def parametrize_volume_template(metafunc):
- """
+ '''
This param runs tests for every volume template in the template dir
- """
- volume_templates = get_filenames_list(metafunc, [".yaml", ".yml"], True, "volume")
- metafunc.parametrize("volume_template", volume_templates)
+ '''
+ volume_templates = get_filenames_list(metafunc, ['.yaml', '.yml'],
+ True, 'volume')
+ metafunc.parametrize('volume_template', volume_templates)
def parametrize_environment_files(metafunc):
- """
+ '''
This param runs tests for all environment files in the template dir
- """
- env_files = get_filenames_lists(metafunc, [".env"])
- metafunc.parametrize("env_files", env_files)
+ '''
+ env_files = get_filenames_lists(metafunc, ['.env'])
+ metafunc.parametrize('env_files', env_files)
def parametrize_environment_file(metafunc):
- """
+ '''
This param runs tests for every environment file in the template dir
- """
- env_files = get_filenames_list(metafunc, [".env"])
- metafunc.parametrize("env_file", env_files)
+ '''
+ env_files = get_filenames_list(metafunc, ['.env'])
+ metafunc.parametrize('env_file', env_files)
def parametrize_parsed_environment_file(metafunc):
- """
+ '''
This param runs tests for every parsed environment file
in the template dir
- """
- parsed_env_files = get_parsed_yaml_files(metafunc, [".env"])
- metafunc.parametrize("parsed_env_file", parsed_env_files)
+ '''
+ parsed_env_files = get_parsed_yaml_files(metafunc, ['.env'])
+ metafunc.parametrize('parsed_env_file', parsed_env_files)
def parametrize_template_dir(metafunc):
- """
+ '''
This param passes a the template_dir as passed in on CLI
or, during --self-test, passes in the sub directories of
template_dir/pass/ and template_dir/fail
template_dir = get_template_dir(metafunc)
- """
+ '''
template_dir = get_template_dir(metafunc)
- if metafunc.config.getoption("self_test"):
- dirs = [
- path.join(template_dir, s, t)
- for s in ["pass"]
- for t in listdir(path.join(template_dir, s))
- if path.isdir(path.join(template_dir, s, t))
- ]
-
- dirs += [
- pytest.mark.xfail(path.join(template_dir, s, t))
- for s in ["fail"]
- for t in listdir(path.join(template_dir, s))
- if path.isdir(path.join(template_dir, s, t))
- ]
+ if metafunc.config.getoption('self_test'):
+ dirs = [path.join(template_dir, s, t)
+ for s in ['pass']
+ for t in listdir(path.join(template_dir, s))
+ if path.isdir(path.join(template_dir, s, t))]
+
+ dirs += [pytest.mark.xfail(path.join(template_dir, s, t))
+ for s in ['fail']
+ for t in listdir(path.join(template_dir, s))
+ if path.isdir(path.join(template_dir, s, t))]
else:
dirs = [template_dir]
- metafunc.parametrize("template_dir", dirs)
+ metafunc.parametrize('template_dir', dirs)
-def parametrize_environment_pair(metafunc, template_type=""):
- """
+def parametrize_environment_pair(metafunc, template_type=''):
+ '''
Define a list of pairs of parsed yaml from the heat templates and
environment files
- """
+ '''
pairs = []
- if metafunc.config.getoption("self_test"):
- sub_dirs = ["pass", "fail"]
- env_files = list_template_dir(metafunc, [".env"], True, template_type, sub_dirs)
- yaml_files = list_template_dir(
- metafunc, [".yaml", ".yml"], True, template_type, sub_dirs
- )
+ if metafunc.config.getoption('self_test'):
+ sub_dirs = ['pass', 'fail']
+ env_files = list_template_dir(metafunc, ['.env'], True,
+ template_type, sub_dirs)
+ yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'], True,
+ template_type, sub_dirs)
else:
- env_files = list_template_dir(metafunc, [".env"], True, template_type)
- yaml_files = list_template_dir(metafunc, [".yaml", ".yml"], True, template_type)
+ env_files = list_template_dir(metafunc, ['.env'], True,
+ template_type)
+ yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'],
+ True, template_type)
for filename in env_files:
basename = path.splitext(filename)[0]
- if basename + ".yml" in yaml_files:
- yfilename = basename + ".yml"
+ if basename + '.yml' in yaml_files:
+ yfilename = basename + '.yml'
else:
- yfilename = basename + ".yaml"
+ yfilename = basename + '.yaml'
try:
with open(filename) as fh:
@@ -401,44 +414,44 @@ def parametrize_environment_pair(metafunc, template_type=""):
with open(yfilename) as fh:
yyml = yaml.load(fh)
- if "fail" in filename:
- pairs.append(
- pytest.mark.xfail(
- {"name": basename, "yyml": yyml, "eyml": eyml}, strict=True
- )
- )
+ if 'fail' in filename:
+ pairs.append(pytest.mark.xfail({"name": basename,
+ "yyml": yyml,
+ "eyml": eyml},
+ strict=True))
else:
pairs.append({"name": basename, "yyml": yyml, "eyml": eyml})
except yaml.YAMLError as e:
print(e) # pylint: disable=superfluous-parens
- metafunc.parametrize("environment_pair", pairs)
+ metafunc.parametrize('environment_pair', pairs)
def parametrize_heat_volume_pair(metafunc):
- """
+ '''
Define a list of pairs of parsed yaml from the a heat and volume
template
- """
+ '''
pairs = []
- if metafunc.config.getoption("self_test"):
- sub_dirs = ["pass", "fail"]
- volume_files = list_template_dir(
- metafunc, [".yaml", ".yml"], True, "volume", sub_dirs
- )
- yaml_files = list_template_dir(metafunc, [".yaml", ".yml"], True, "", sub_dirs)
+ if metafunc.config.getoption('self_test'):
+ sub_dirs = ['pass', 'fail']
+ volume_files = list_template_dir(metafunc, ['.yaml', '.yml'],
+ True, 'volume', sub_dirs)
+ yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'],
+ True, '', sub_dirs)
else:
- volume_files = list_template_dir(metafunc, [".yaml", ".yml"], True, "volume")
- yaml_files = list_template_dir(metafunc, [".yaml", ".yml"], True)
+ volume_files = list_template_dir(metafunc, ['.yaml', '.yml'],
+ True, 'volume')
+ yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'], True)
- pattern = re.compile(r"\_volume$")
+ pattern = re.compile(r'\_volume$')
for vfilename in volume_files:
- basename = pattern.sub("", path.splitext(vfilename)[0])
- if basename + ".yml" in yaml_files:
- yfilename = basename + ".yml"
+ basename = pattern.sub('', path.splitext(vfilename)[0])
+ if basename + '.yml' in yaml_files:
+ yfilename = basename + '.yml'
else:
- yfilename = basename + ".yaml"
+ yfilename = basename + '.yaml'
try:
with open(vfilename) as fh:
@@ -446,16 +459,15 @@ def parametrize_heat_volume_pair(metafunc):
with open(yfilename) as fh:
yyml = yaml.load(fh)
- if "fail" in vfilename:
- pairs.append(
- pytest.mark.xfail(
- {"name": basename, "yyml": yyml, "vyml": vyml}, strict=True
- )
- )
+ if 'fail' in vfilename:
+ pairs.append(pytest.mark.xfail({"name": basename,
+ "yyml": yyml,
+ "vyml": vyml},
+ strict=True))
else:
pairs.append({"name": basename, "yyml": yyml, "vyml": vyml})
except yaml.YAMLError as e:
print(e) # pylint: disable=superfluous-parens
- metafunc.parametrize("heat_volume_pair", pairs)
+ metafunc.parametrize('heat_volume_pair', pairs)
diff --git a/ice_validator/tests/report.html.jinja2 b/ice_validator/tests/report.html.jinja2
new file mode 100644
index 0000000..5bc59e5
--- /dev/null
+++ b/ice_validator/tests/report.html.jinja2
@@ -0,0 +1,220 @@
+{## ============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============================================#}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="x-ua-compatible" content="ie=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+ <title>HEAT Validation Report</title>
+ <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="https://cdn.datatables.net/v/zf/jszip-2.5.0/dt-1.10.18/b-1.5.2/b-flash-1.5.2/b-html5-1.5.2/b-print-1.5.2/fh-3.1.4/datatables.min.css"/>
+ <link rel="stylesheet" type="text/css"
+ href="https://cdn.datatables.net/buttons/1.5.2/css/buttons.dataTables.min.css"/>
+ <link rel="stylesheet"
+ href="https://cdn.jsdelivr.net/npm/foundation-sites@6.5.0-rc.2/dist/css/foundation.min.css"
+ integrity="sha256-iJQ8dZac/jUYHxiEnZJsyVpKcdq2sQvdA7t02QFmp30= sha384-SplqNBo/0ZlvSdwrP/riIPDozO5ck8+yIm++KVqyMAC53S6m3BaV+2OLpi7ULOOh sha512-ho6hK4sAWdCeqopNZWNy1d9Ok2hzfTLQLcGSr8ZlRzDzh6tNHkVoqSl6wgLsqls3yazwiG9H9dBCtSfPuiLRCQ=="
+ crossorigin="anonymous">
+
+ <script type="text/javascript"
+ src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
+ <script type="text/javascript"
+ src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
+ <script type="text/javascript"
+ src="https://cdn.datatables.net/v/zf/jszip-2.5.0/dt-1.10.18/b-1.5.2/b-flash-1.5.2/b-html5-1.5.2/b-print-1.5.2/fh-3.1.4/datatables.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/foundation-sites@6.5.0-rc.2/dist/js/foundation.min.js"
+ integrity="sha256-G6jsRyH1fxbsvFIXSCuwYmI1aIDYBa28xscrvmYjJy0= sha384-vtoG68NvPc9azmFJr447vvY8qgdyA4FdaJ5/bqvzIM4eAdZfO0iyRRF8l2AAscYI sha512-43seCcNrHA0BQgrtyajB9sp8yOdv5c8QdYvgjP7zJ7v+dmzAcxYDQ2gupb9aztsNWBq1COIp/3NHYkQs4l/dkg=="
+ crossorigin="anonymous"></script>
+</head>
+<style>
+ #collection_failures {
+ table-layout: fixed;
+ }
+ .fileNames {
+ width: 25%;
+ word-wrap: break-word;
+ word-break: break-all;
+ white-space: normal;
+ }
+ .fixtures {
+ width: 10%;
+ }
+ .errorColumn {
+ width: 40%;
+ }
+ .fileLinks, .errorMessage {
+ word-wrap: break-word;
+ word-break: break-all;
+ white-space: normal;
+ }
+ .details {
+ white-space: nowrap;
+ }
+
+ .codeCell {
+ width: 100%;
+ overflow: auto;
+ }
+</style>
+<body>
+<div class="grid-container fluid">
+
+ <div class="callout {{ "alert" if failures or collection_failures else "success" }}">
+ <h1>Validation Report</h1>
+ <ul>
+ <li><b>Profile:</b> {{ profile_name }}</li>
+ <li><b>Directory Validated:</b> {{ template_dir }}</li>
+ <li><b>Checksum:</b> {{ checksum }}</li>
+ <li><b>Generated:</b> {{ timestamp }}</li>
+ <li><b>Total Failures:</b> {{ num_failures }}</li>
+ </ul>
+ </div>
+ {% if collection_failures %}
+ <div class="callout alert">
+ <h2>WARNING: Errors Occurred During Validation Setup</h2>
+ <p>
+ The following unexpected errors occurred while preparing to validate
+ the the input files. Some validations may not have been executed.
+ Please refer these issue to the VNF Validation Tool team.
+ </p>
+ </div>
+ <table id="collection_failures">
+ <thead>
+ <tr>
+ <th class="fileNames">Validation File</th>
+ <th class="fileNames">Test</th>
+ <th class="fixtures">Fixtures</th>
+ <th class="errorColumnn">Error</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for failure in collection_failures %}
+ <tr>
+ <td class="fileNames">{{ failure.module }}</td>
+ <td class="fileNames">{{ failure.test }}</td>
+ <td class="fixtures">{{ failure.fixtures }}</td>
+ <td class="errorColumn">
+ <div class="codeCell">
+ <pre class="code">{{ failure.error }}</pre>
+ </div>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+
+ {% if failures %}
+ <h2>Validation Failures</h2>
+ <table id="failures">
+ <thead>
+ <tr>
+ <th>File(s)</th>
+ <th>Error Message</th>
+ <th>Requirement(s)</th>
+ <th>Resolution Steps</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for failure in failures %}
+ <tr>
+ <td>
+ {{ failure.file_links }}
+ </td>
+ <td>
+ <p><b>Failed:</b> {{ failure.test_id }}</p>
+ <p>{{ failure.error_message }}
+ <a class="details" href="#"
+ data-open="raw-output-{{ loop.index }}">Full&nbsp;Details</a>
+ </p>
+ </td>
+ <td>
+ {{ failure.requirements }}
+ </td>
+ <td>
+ {{ failure.resolution_steps }}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ {% for failure in failures %}
+ <div id="raw-output-{{ loop.index }}" class="large reveal" data-reveal
+ aria-labelledby="modalTitle"
+ aria-hidden="true" role="dialog">
+ <h2 id="modalTitle">{{ failure.test_id }}</h2>
+ <pre class="code">
+ {{ failure.raw_output }}
+ </pre>
+ <button class="close-button" data-close aria-label="Close modal"
+ type="button">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ <a class="close-reveal-modal" aria-label="Close">&#215;</a>
+ </div>
+ {% endfor %}
+ </table>
+ {% else %}
+ <h2>No validation errors found.</h2>
+ {% endif %}
+ <script lang="javascript">
+ $(document).foundation();
+ $(document).ready(function () {
+ $('#failures').DataTable({
+ dom: 'Bfrtip',
+ buttons: [
+ 'csv',
+ 'excel',
+ {
+ extend: 'pdfHtml5',
+ orientation: 'landscape',
+ },
+ 'print'
+ ],
+ fixedHeader: true,
+ pageLength: 50,
+ columns: [
+ {width: "25%", className: "fileLinks"},
+ {width: "25%", className: "errorMessage"},
+ {width: "25%", className: "requirements"},
+ {width: "25%", className: "resolutionSteps"},
+ ]
+ });
+ });
+ </script>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/ice_validator/tests/structures.py b/ice_validator/tests/structures.py
index d10c5ea..8d66220 100644
--- a/ice_validator/tests/structures.py
+++ b/ice_validator/tests/structures.py
@@ -38,16 +38,16 @@
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-"""structures
-"""
+'''structures
+'''
import os
-import yaml
+from tests import cached_yaml as yaml
from .utils import nested_dict
-VERSION = "1.4.0"
+VERSION = '1.4.0'
class Heat(object):
@@ -55,7 +55,6 @@ class Heat(object):
filepath - absolute path to template file.
envpath - absolute path to environmnt file.
"""
-
def __init__(self, filepath=None, envpath=None):
self.filepath = None
self.basename = None
@@ -82,13 +81,13 @@ class Heat(object):
self.dirname = os.path.dirname(self.filepath)
with open(self.filepath) as fi:
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.parameters = self.yml.get("parameters", {})
- self.resources = self.yml.get("resources", {})
- self.outputs = self.yml.get("outputs", {})
- self.conditions = self.yml.get("conditions", {})
+ 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.parameters = self.yml.get('parameters', {})
+ self.resources = self.yml.get('resources', {})
+ self.outputs = self.yml.get('outputs', {})
+ self.conditions = self.yml.get('conditions', {})
def load_env(self, envpath):
"""Load the Environment template given a envpath.
@@ -105,21 +104,22 @@ class Heat(object):
class Env(Heat):
"""An Environment file
"""
-
pass
class Resource(object):
"""A Resource
"""
-
def __init__(self, resource_id=None, resource=None):
- self.resource_id = resource_id or ""
+ self.resource_id = resource_id or ''
self.resource = resource or {}
@staticmethod
def get_index_var(resource):
"""Return the index_var for this resource.
"""
- index_var = nested_dict.get(resource, "properties", "index_var") or "index"
+ index_var = nested_dict.get(resource,
+ 'properties',
+ 'index_var') or 'index'
return index_var
+
diff --git a/ice_validator/tests/test_all_referenced_resources_exists.py b/ice_validator/tests/test_all_referenced_resources_exists.py
deleted file mode 100644
index e77f4f8..0000000
--- a/ice_validator/tests/test_all_referenced_resources_exists.py
+++ /dev/null
@@ -1,76 +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.
-#
-
-"""test_all_referenced_resources_exists
-"""
-
-import pytest
-import yaml
-
-from .utils.nested_iterables import find_all_get_resource_in_yml
-
-VERSION = "1.0.0"
-
-# pylint: disable=invalid-name
-
-
-def test_all_referenced_resources_exists(yaml_file):
- """
- Check that all resources referenced by get_resource
- actually exists in all yaml files
- """
- with open(yaml_file) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the yaml file")
-
- resource_ids = yml["resources"].keys()
- referenced_resource_ids = find_all_get_resource_in_yml(yml)
-
- missing_referenced_resources = set()
- for referenced_resource_id in referenced_resource_ids:
- if referenced_resource_id not in resource_ids:
- missing_referenced_resources.add(referenced_resource_id)
-
- assert not missing_referenced_resources, "missing referenced resources %s" % list(
- missing_referenced_resources
- )
diff --git a/ice_validator/tests/test_allowed_address_pair_format.py b/ice_validator/tests/test_allowed_address_pair_format.py
deleted file mode 100644
index 816f486..0000000
--- a/ice_validator/tests/test_allowed_address_pair_format.py
+++ /dev/null
@@ -1,177 +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.
-#
-
-"""
-test_allowed_address_pairs_format
-"""
-
-import re
-
-import pytest
-import yaml
-
-from .utils.network_roles import get_network_role_from_port, property_uses_get_resource
-
-VERSION = "1.0.0"
-
-# pylint: disable=invalid-name
-
-
-def test_allowed_address_pairs_format(heat_template):
- """
- Make sure all allowed_address_pairs properties follow the allowed
- naming conventions
- """
- allowed_formats = [
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_floating_v6_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_floating_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "external",
- re.compile(r"(.+?)_floating_v6_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "external",
- re.compile(r"(.+?)_floating_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_v6_ip_\d+"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_ip_\d+"),
- ],
- ["allowed_address_pairs", "string", "external", re.compile(r"(.+?)_v6_ip_\d+")],
- ["allowed_address_pairs", "string", "external", re.compile(r"(.+?)_ip_\d+")],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_v6_ips"),
- ],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_ips"),
- ],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "external",
- re.compile(r"(.+?)_v6_ips"),
- ],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "external",
- re.compile(r"(.+?)_ips"),
- ],
- ]
-
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- # check both valid and invalid patterns to catch edge cases
- invalid_allowed_address_pairs = []
-
- for v1 in yml["resources"].values():
- if (
- not isinstance(v1, dict) or
- "properties" not in v1 or
- v1.get("type") != "OS::Neutron::Port" or
- property_uses_get_resource(v1, "network")
- ):
- continue
- network_role = get_network_role_from_port(v1)
-
- v2 = v1["properties"].get("allowed_address_pairs", {})
- for v3 in v2:
- if "ip_address" not in v3 or "get_param" not in v3["ip_address"]:
- continue
-
- param = v3["ip_address"]["get_param"]
- if isinstance(param, list):
- param = param[0]
-
- for v4 in allowed_formats:
- # check if pattern matches
- m = v4[3].match(param)
- if m:
- if (
- v4[2] == "internal" and
- len(m.groups()) > 1 and
- m.group(2) == network_role
- ):
- break
- elif (
- v4[2] == "external"
- and len(m.groups()) > 0
- and m.group(1).endswith("_" + network_role)
- ):
- break
- else:
- invalid_allowed_address_pairs.append(param)
-
- assert not set(
- invalid_allowed_address_pairs
- ), "invalid_allowed_address_pairs %s" % list(set(invalid_allowed_address_pairs))
diff --git a/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py b/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
index 7ce9c43..0d4bbdf 100644
--- a/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
+++ b/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
@@ -38,28 +38,30 @@
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-"""
+'''
test_allowed_address_pairs_include_vm_type_network_role
-"""
+'''
import pytest
-import yaml
+from tests import cached_yaml as yaml
from .helpers import validates
from .utils.ports import get_invalid_ip_addresses
-VERSION = "1.0.0"
+VERSION = '1.0.0'
# pylint: disable=invalid-name
-@validates("R-41492", "R-35735")
+@validates('R-41492',
+ 'R-35735',
+ 'R-98748')
def test_allowed_address_pairs_include_vm_type_network_role(heat_template):
- """
+ '''
Check that all allowed_address_pairs include the {vm_type} of the
nova server it is associated to and also contains the
{network_role} of the network it is associated with
- """
+ '''
with open(heat_template) as fh:
yml = yaml.load(fh)
@@ -67,10 +69,14 @@ def test_allowed_address_pairs_include_vm_type_network_role(heat_template):
if "resources" not in yml:
pytest.skip("No resources specified in the heat template")
- invalid_ip_addresses = get_invalid_ip_addresses(
- yml["resources"], "allowed_address_pairs"
- )
+ if "parameters" not in yml:
+ pytest.skip("No parameters specified in the heat template")
+
+ invalid_ip_addresses = get_invalid_ip_addresses(yml['resources'],
+ "allowed_address_pairs",
+ yml["parameters"])
+
+ assert not set(invalid_ip_addresses), (
+ 'invalid ip addresses allowed address pairs %s' % list(
+ set(invalid_ip_addresses)))
- assert not set(
- invalid_ip_addresses
- ), "invalid ip addresses allowed address pairs %s" % list(set(invalid_ip_addresses))
diff --git a/ice_validator/tests/test_availability_zone_get_param.py b/ice_validator/tests/test_availability_zone_get_param.py
deleted file mode 100644
index 456f74b..0000000
--- a/ice_validator/tests/test_availability_zone_get_param.py
+++ /dev/null
@@ -1,73 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-import pytest
-import yaml
-
-
-def test_availability_zone_naming_use_get_param(heat_template):
- '''
- Make sure all availability zones only use get_param
- '''
-
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- invalid_availability_zones = []
-
- for v1 in yml["resources"].values():
- if not isinstance(v1, dict):
- continue
- if "properties" not in v1:
- continue
- if "type" not in v1:
- continue
- if v1["type"] != "OS::Nova::Server":
- continue
-
- for k2, v2 in v1["properties"].items():
- if k2 == 'availability_zone' and not v2["get_param"]:
- invalid_availability_zones.append(v2["get_param"])
-
- assert not set(invalid_availability_zones)
diff --git a/ice_validator/tests/test_base_template_outputs_consumed.py b/ice_validator/tests/test_base_template_outputs_consumed.py
deleted file mode 100644
index 5d5bcd9..0000000
--- a/ice_validator/tests/test_base_template_outputs_consumed.py
+++ /dev/null
@@ -1,100 +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.
-#
-
-"""
-test_base_template_outputs_consumed
-"""
-
-from os import path, sep
-
-import pytest
-import yaml
-
-from .helpers import validates
-
-VERSION = "1.0.0"
-
-# pylint: disable=invalid-name
-
-
-@validates("R-52753")
-def test_base_template_outputs_consumed(heat_templates):
- """
- Check that all outputs in the base template is consumed
- by another template. The exception is the predefined output
- parameters.
- """
- base_template = ""
- base_template_yml = ""
- for heat_template in heat_templates:
- with open(heat_template) as fh:
- yml = yaml.load(fh)
- basename = path.splitext(heat_template)[0].rsplit(sep, 1)[1]
- if (
- basename.endswith("_base") or
- basename.startswith("base_") or
- basename.find("_base_") > 0
- ):
- base_template = heat_template
- base_template_yml = yml
-
- # get the base template outputs
- if "outputs" not in base_template_yml:
- pytest.skip("No outputs specified in the base template")
-
- predefined_outputs = ["oam_management_v4_address", "oam_management_v6_address"]
- base_outputs = set(base_template_yml["outputs"]) - set(predefined_outputs)
-
- # get all add-on templates
- addon_heat_templates = set(heat_templates) - set([base_template])
-
- # get all parameters from add-on templates
- non_base_parameters = []
- for addon_heat_template in addon_heat_templates:
- with open(addon_heat_template) as fh:
- yml = yaml.load(fh)
- if "parameters" not in yml:
- continue
- parameters = yml["parameters"].keys()
- non_base_parameters.extend(parameters)
-
- assert base_outputs <= set(non_base_parameters), "unconsumed outputs %s" % list(
- base_outputs - set(non_base_parameters)
- )
diff --git a/ice_validator/tests/test_fixed_ips_format.py b/ice_validator/tests/test_fixed_ips_format.py
deleted file mode 100644
index 77a515e..0000000
--- a/ice_validator/tests/test_fixed_ips_format.py
+++ /dev/null
@@ -1,123 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-import pytest
-import yaml
-from .utils.ports import is_reserved_port
-from .utils.network_roles import get_network_role_from_port, property_uses_get_resource
-import re
-
-
-def test_fixed_ips_format(heat_template):
- '''
- Make sure all fixed_ips properties follow the allowed
- naming conventions
- '''
- formats = [
- ["fixed_ips", "string", "internal",
- re.compile(r'(.+?)_int_(.+?)_ip_\d+')],
- ["fixed_ips", "string", "internal",
- re.compile(r'(.+?)_int_(.+?)_v6_ip_\d+')],
- ["fixed_ips", "string", "external",
- re.compile(r'(.+?)_ip_\d+')],
- ["fixed_ips", "string", "external",
- re.compile(r'(.+?)_v6_ip_\d+')],
- ["fixed_ips", "comma_delimited_list", "internal",
- re.compile(r'(.+?)_int_(.+?)_ips')],
- ["fixed_ips", "comma_delimited_list", "internal",
- re.compile(r'(.+?)_int_(.+?)_v6_ips')],
- ["fixed_ips", "comma_delimited_list", "external",
- re.compile(r'(.+?)_ips')],
- ["fixed_ips", "comma_delimited_list", "external",
- re.compile(r'(.+?)_v6_ips')],
- ]
-
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- invalid_fixed_ips = []
- for k1, v1 in yml["resources"].items():
- if not isinstance(v1, dict):
- continue
- if "properties" not in v1:
- continue
- if v1.get("type") != "OS::Neutron::Port":
- continue
- if is_reserved_port(k1):
- continue
- if property_uses_get_resource(v1, "network"):
- continue
- network_role = get_network_role_from_port(v1)
-
- for k2, v2 in v1["properties"].items():
- if k2 != "fixed_ips":
- continue
- for v3 in v2:
- if "ip_address" not in v3:
- continue
- if "get_param" not in v3["ip_address"]:
- continue
-
- valid_fixed_ip = False
- for v4 in formats:
- param = v3["ip_address"]["get_param"]
- if isinstance(param, list):
- param = param[0]
- m = v4[3].match(param)
- if m:
- if v4[2] == "internal" and\
- len(m.groups()) > 1 and\
- m.group(2) == network_role:
- valid_fixed_ip = True
- break
- elif v4[2] == "external" and\
- len(m.groups()) > 0 and\
- m.group(1).endswith("_" + network_role):
- valid_fixed_ip = True
- break
-
- if not valid_fixed_ip:
- invalid_fixed_ips.append(param)
-
- assert not set(invalid_fixed_ips)
diff --git a/ice_validator/tests/test_fixed_ips_format_use_get_param.py b/ice_validator/tests/test_fixed_ips_format_use_get_param.py
deleted file mode 100644
index df57c01..0000000
--- a/ice_validator/tests/test_fixed_ips_format_use_get_param.py
+++ /dev/null
@@ -1,81 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-import pytest
-import yaml
-from .utils.ports import is_reserved_port
-
-
-def test_fixed_ips_format_use_get_parm(heat_template):
- """
- Make sure all fixed_ips properties only use get_param
- """
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- invalid_fixed_ips = []
- for k, v in yml["resources"].items():
- if not isinstance(v, dict):
- continue
- if "properties" not in v:
- continue
- if v.get("type") != "OS::Neutron::Port":
- continue
- if is_reserved_port(k):
- continue
-
- valid_fixed_ip = True
- for k2, v2 in v["properties"].items():
- if k2 != "fixed_ips":
- continue
- for v3 in v2:
- if "ip_address" not in v3:
- continue
- if "get_param" not in v3["ip_address"]:
- valid_fixed_ip = False
-
- if not valid_fixed_ip:
- invalid_fixed_ips.append(k)
-
- assert not set(invalid_fixed_ips)
diff --git a/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py b/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
index 53f6453..428b72e 100644
--- a/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
+++ b/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
@@ -2,7 +2,7 @@
# ============LICENSE_START=======================================================
# org.onap.vvp/validation-scripts
# ===================================================================
-# Copyright © 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
# ===================================================================
#
# Unless otherwise specified, all software contained herein is licensed
@@ -37,10 +37,11 @@
#
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-from .helpers import validates
import pytest
-import yaml
+from tests import cached_yaml as yaml
+
+from .helpers import validates
from .utils.ports import get_invalid_ip_addresses
@@ -51,7 +52,8 @@ from .utils.ports import get_invalid_ip_addresses
'R-78380',
'R-23503',
'R-71577',
- 'R-04697')
+ 'R-04697',
+ 'R-34037')
def test_fixed_ips_include_vm_type_network_role(heat_template):
'''
Check that all fixed_ips ip addresses include the {vm_type} of the
@@ -65,7 +67,11 @@ def test_fixed_ips_include_vm_type_network_role(heat_template):
if "resources" not in yml:
pytest.skip("No resources specified in the heat template")
+ if "parameters" not in yml:
+ pytest.skip("No parameters specified in the heat template")
+
invalid_ip_addresses = get_invalid_ip_addresses(yml['resources'],
- "fixed_ips")
+ "fixed_ips",
+ yml["parameters"])
assert not set(invalid_ip_addresses)
diff --git a/ice_validator/tests/test_heat_template_and_env_file_extension.py b/ice_validator/tests/test_heat_template_and_env_file_extension.py
deleted file mode 100644
index de83745..0000000
--- a/ice_validator/tests/test_heat_template_and_env_file_extension.py
+++ /dev/null
@@ -1,82 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-import yaml
-import pytest
-
-
-def test_heat_template_file_extension(yaml_file):
- '''
- Check that all heat templates are in fact heat
- templates
- '''
- with open(yaml_file) as fh:
- yml = yaml.load(fh)
-
- # skip if parameters are not defined
- if "parameters" not in yml:
- pytest.skip("No parameters specified in the heat template")
-
- invalid_params = []
- for k, v in yml["parameters"].items():
- if not isinstance(v, dict):
- invalid_params.append(k)
-
- assert not set(invalid_params)
-
-
-def test_environment_file_extension(env_file):
- '''
- Check that all environments files are in fact environment
- files
- '''
- with open(env_file) as fh:
- yml = yaml.load(fh)
-
- # skip if parameters are not defined
- if "parameters" not in yml:
- pytest.skip("No parameters specified in the environment file")
-
- invalid_params = []
- for k, v in yml["parameters"].items():
- if isinstance(v, dict):
- invalid_params.append(k)
-
- assert not set(invalid_params)
diff --git a/ice_validator/tests/test_heat_templates_provided.py b/ice_validator/tests/test_heat_templates_provided.py
deleted file mode 100644
index 168dbe0..0000000
--- a/ice_validator/tests/test_heat_templates_provided.py
+++ /dev/null
@@ -1,46 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-
-def test_heat_templates_provided(heat_templates):
- '''
- Make sure heat templates have been provided
- '''
- assert len(heat_templates) > 0
diff --git a/ice_validator/tests/test_nested_templates.py b/ice_validator/tests/test_nested_templates.py
deleted file mode 100644
index c9caa19..0000000
--- a/ice_validator/tests/test_nested_templates.py
+++ /dev/null
@@ -1,69 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-from .helpers import validates
-import yaml
-from os import path
-from .utils.nested_files import get_list_of_nested_files
-
-
-@validates("R-70276")
-def test_all_nested_templates_provided(yaml_files):
- """
- Check that all templates marked as volume templates are
- in fact volume templates
- """
- nested_yaml_files = []
-
- for yaml_file in yaml_files:
- with open(yaml_file) as fh:
- yml = yaml.load(fh)
- if "resources" not in yml:
- continue
- nested_yaml_files.extend(
- get_list_of_nested_files(yml["resources"], path.dirname(yaml_file))
- )
-
- # detect all provided nested files
- provided_nested_yaml_files = [
- f1 for f1 in nested_yaml_files for f2 in yaml_files if f1 in f2
- ]
-
- assert set(provided_nested_yaml_files) == set(nested_yaml_files)
diff --git a/ice_validator/tests/test_nested_templates_invalid_nesting.py b/ice_validator/tests/test_nested_templates_invalid_nesting.py
deleted file mode 100644
index edd5ca3..0000000
--- a/ice_validator/tests/test_nested_templates_invalid_nesting.py
+++ /dev/null
@@ -1,63 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-import yaml
-from os import path
-from .utils.nested_files import check_for_invalid_nesting
-
-
-def test_valid_nesting(yaml_files):
- '''
- Check that the nesting is following the proper format and
- that all nested files exists and are parsable
- '''
- invalid_nesting = []
-
- for yaml_file in yaml_files:
- with open(yaml_file) as fh:
- yml = yaml.load(fh)
- if "resources" not in yml:
- continue
- invalid_nesting.extend(check_for_invalid_nesting(
- yml["resources"],
- yaml_file,
- path.dirname(yaml_file)))
-
- assert not set(invalid_nesting)
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
index 781f35d..81cfc9a 100644
--- 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
@@ -37,13 +37,39 @@
#
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-from .helpers import validates
+import os
+import pytest
+from .helpers import validates, get_environment_pair
+
+@pytest.mark.heat_only
@validates('R-90279', 'R-01896', 'R-26124')
-def test_no_unused_parameters_between_env_and_templates(environment_pair):
- '''
+def test_no_unused_parameters_between_env_and_templates(heat_template):
+ """
Check all defined parameters are used in the appropiate Heat template.
- '''
- assert (set(environment_pair["eyml"]['parameters']) ==
- set(environment_pair["yyml"]['parameters']))
+ """
+ environment_pair = get_environment_pair(heat_template)
+ if not environment_pair:
+ pytest.skip("No heat/env pair could be identified")
+
+ env_parameters = set(environment_pair["eyml"]["parameters"].keys())
+ template_parameters = set(environment_pair["yyml"]["parameters"].keys())
+
+ 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 " \
+ "with basename ({basename}). "
+ 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_nova_servers_correct_parameter_types.py b/ice_validator/tests/test_nova_servers_correct_parameter_types.py
deleted file mode 100644
index 8364d38..0000000
--- a/ice_validator/tests/test_nova_servers_correct_parameter_types.py
+++ /dev/null
@@ -1,114 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-from .helpers import validates
-
-import pytest
-import yaml
-import re
-
-
-@validates('R-71152', 'R-50436')
-def test_nova_servers_correct_parameter_types(heat_template):
- '''
- Make sure all nova servers have properly assigned types for the parameters
- used for their name, image and flavor
- '''
- key_values = ["name", "flavor", "image"]
- key_value_formats = [
- ["name", "string",
- re.compile(r'(.+?)_name_\d+')],
- ["name", "comma_delimited_list",
- re.compile(r'(.+?)_names')],
- ["flavor", "string",
- re.compile(r'(.+?)_flavor_name')],
- ["image", "string",
- re.compile(r'(.+?)_image_name')],
- ]
-
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if parameters are not defined
- if "parameters" not in yml:
- pytest.skip("No parameters specified in the heat template")
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- parameters = yml["parameters"]
-
- invalid_nova_servers = []
-
- for k1, v1 in yml["resources"].items():
- if not isinstance(v1, dict):
- continue
- if "properties" not in v1:
- continue
- if v1.get("type") != "OS::Nova::Server":
- continue
-
- valid_nova_server = True
- for k2, v2 in v1["properties"].items():
- if k2 not in key_values:
- continue
- formats = [v for v in key_value_formats if v[0] == k2]
- for v3 in formats:
- if "get_param" not in v2:
- continue
-
- param = v2["get_param"]
- if isinstance(param, list):
- param = param[0]
-
- m = v3[2].match(param)
- if m and m.group(1):
- if parameters[param]:
- param_spec = parameters[param]
- if not param_spec["type"]:
- valid_nova_server = False
- elif param_spec["type"] != v3[1]:
- valid_nova_server = False
-
- if not valid_nova_server:
- invalid_nova_servers.append(k1)
-
- assert not set(invalid_nova_servers)
diff --git a/ice_validator/tests/test_parse_yaml.py b/ice_validator/tests/test_parse_yaml.py
deleted file mode 100644
index 637e93d..0000000
--- a/ice_validator/tests/test_parse_yaml.py
+++ /dev/null
@@ -1,62 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-
-from os import path
-from .helpers import validates
-import pytest
-import yaml
-
-
-@validates('R-95303')
-def test_parse_yaml(filename):
- '''
- Read in each .yaml or .env file. If it is successfully parsed as yaml, save
- contents, else add filename to list of bad yaml files. Log the result of
- parse attempt.
- '''
- if path.splitext(filename)[-1] in [".yml", ".yaml", ".env"]:
- try:
- yaml.load(open(filename, 'r'))
- assert True
- except Exception:
- assert False
- else:
- pytest.skip("The file does not have any of the extensions .yml,\
- .yaml, or .env")
diff --git a/ice_validator/tests/test_referenced_and_defined_parameters_match.py b/ice_validator/tests/test_referenced_and_defined_parameters_match.py
deleted file mode 100644
index 918d396..0000000
--- a/ice_validator/tests/test_referenced_and_defined_parameters_match.py
+++ /dev/null
@@ -1,54 +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============================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-import yaml
-from .helpers import validates
-from .utils.nested_iterables import find_all_get_param_in_yml
-
-
-@validates('R-23664')
-def test_referenced_and_defined_parameters_match(yaml_file):
- '''
- Check that all referenced parameters are actually defined
- as parameters
- '''
- with open(yaml_file) as fh:
- yml = yaml.load(fh)
- resource_params = find_all_get_param_in_yml(yml)
- assert set(yml['parameters'].keys()) == set(resource_params)
diff --git a/ice_validator/tests/test_required_parameters_specified_in_env_files.py b/ice_validator/tests/test_required_parameters_specified_in_env_files.py
index 15894c3..63b890c 100644
--- a/ice_validator/tests/test_required_parameters_specified_in_env_files.py
+++ b/ice_validator/tests/test_required_parameters_specified_in_env_files.py
@@ -2,7 +2,7 @@
# ============LICENSE_START=======================================================
# org.onap.vvp/validation-scripts
# ===================================================================
-# Copyright © 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
# ===================================================================
#
# Unless otherwise specified, all software contained herein is licensed
@@ -40,13 +40,20 @@
import pytest
+from .helpers import get_environment_pair
-def test_required_parameters_provided_in_env_file(environment_pair):
+
+@pytest.mark.heat_only
+def test_required_parameters_provided_in_env_file(heat_template):
'''
Make sure all required parameters are specified properly
in the environment file if a server is defined in the
corresponding heat template
'''
+ environment_pair = get_environment_pair(heat_template)
+ if not environment_pair:
+ pytest.skip("No heat/env pair could be identified")
+
required_parameters = ["vnf_id", "vf_module_id", "vnf_name"]
if "resources" not in environment_pair["yyml"]:
diff --git a/ice_validator/tests/test_reserve_port_fixed_ips_format.py b/ice_validator/tests/test_reserve_port_fixed_ips_format.py
deleted file mode 100644
index 5b28d06..0000000
--- a/ice_validator/tests/test_reserve_port_fixed_ips_format.py
+++ /dev/null
@@ -1,118 +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.
-#
-
-import pytest
-import yaml
-from .utils.network_roles import get_network_role_from_port
-from .utils.ports import is_reserved_port
-import re
-
-
-def test_reserve_port_fixed_ips_format(heat_template):
- '''
- Make sure all fixed_ips properties for a reserved port
- follow the allowed naming conventions
- '''
- allowed_formats = [
- ["fixed_ips", "string", "internal",
- re.compile(r'(.+?)_int_(.+?)_floating_v6_ip')],
- ["fixed_ips", "string", "internal",
- re.compile(r'(.+?)_int_(.+?)_floating_ip')],
- ["fixed_ips", "string", "external",
- re.compile(r'(.+?)_floating_v6_ip')],
- ["fixed_ips", "string", "external",
- re.compile(r'(.+?)_floating_ip')],
- ]
-
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- # check both valid and invalid patterns to catch edge cases
- invalid_fixed_ips = []
-
- for k1, v1 in yml["resources"].items():
- if not isinstance(v1, dict):
- continue
- if "properties" not in v1:
- continue
- if v1.get("type") != "OS::Neutron::Port":
- continue
- if not is_reserved_port(k1):
- continue
-
- network_role = get_network_role_from_port(v1)
-
- for k2, v2 in v1["properties"].items():
- if k2 != "fixed_ips":
- continue
- for v3 in v2:
- if "ip_address" not in v3:
- continue
- if "get_param" not in v3["ip_address"]:
- continue
-
- valid_fixed_ip = False
- for v4 in allowed_formats:
- param = v3["ip_address"]["get_param"]
- if isinstance(param, list):
- param = param[0]
-
- # check if pattern matches
- m = v4[3].match(param)
- if m:
- if v4[2] == "internal" and\
- len(m.groups()) > 1 and\
- m.group(2) == network_role:
- valid_fixed_ip = True
- break
- elif v4[2] == "external" and\
- len(m.groups()) > 0 and\
- m.group(1).endswith("_" + network_role):
- valid_fixed_ip = True
- break
-
- if not valid_fixed_ip:
- invalid_fixed_ips.append(param)
-
- assert not set(invalid_fixed_ips)
diff --git a/ice_validator/tests/test_reserve_port_fixed_ips_has_base_outputs.py b/ice_validator/tests/test_reserve_port_fixed_ips_has_base_outputs.py
deleted file mode 100644
index 7245ba8..0000000
--- a/ice_validator/tests/test_reserve_port_fixed_ips_has_base_outputs.py
+++ /dev/null
@@ -1,114 +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.
-#
-
-import pytest
-from os import path, sep
-import yaml
-from .utils.ports import is_reserved_port
-
-
-def test_reserve_port_fixed_ips_has_base_outputs(heat_template):
- '''
- Make sure all fixed ips specified in reserved ports are
- also exported as outputs in the same base template
- '''
- basename = path.splitext(heat_template)[0].rsplit(sep, 1)[1]
- if not (basename.endswith("_base") or
- basename.startswith("base_") or
- basename.find("_base_") > 0):
- pytest.skip("Skipping as it is not a base template")
-
- # parse the yml
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # get the outputs
- try:
- outputs = yml["outputs"]
- except (TypeError, KeyError):
- outputs = {}
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- invalid_fixed_ips = []
- for k1, v1 in yml["resources"].items():
- if not isinstance(v1, dict):
- continue
- if "properties" not in v1:
- continue
- if v1.get("type") != "OS::Neutron::Port":
- continue
- if not is_reserved_port(k1):
- continue
-
- for k2, v2 in v1["properties"].items():
- if k2 != "fixed_ips":
- continue
- for v3 in v2:
- if "ip_address" not in v3:
- continue
- if "get_param" not in v3["ip_address"]:
- continue
-
- param = v3["ip_address"]["get_param"]
-
- # construct the expected output param
- if 'v6' in param:
- output_param = param.replace('floating_v6_ip', 'v6_vip')
- else:
- output_param = param.replace('floating_ip', 'vip')
-
- # check the output is constructed correctly
- try:
- output_vip = outputs[output_param]
- if not output_vip:
- invalid_fixed_ips.append(param)
- else:
- # make sure the value is set properly using the
- # original param value
- output_value_param = output_vip["value"]["get_param"]
- if output_value_param != param:
- invalid_fixed_ips.append(param)
- except (TypeError, KeyError):
- invalid_fixed_ips.append(param)
-
- assert not set(invalid_fixed_ips)
diff --git a/ice_validator/tests/test_reserve_port_only_in_base_template.py b/ice_validator/tests/test_reserve_port_only_in_base_template.py
deleted file mode 100644
index 52cbec2..0000000
--- a/ice_validator/tests/test_reserve_port_only_in_base_template.py
+++ /dev/null
@@ -1,78 +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.
-#
-
-import pytest
-from os import path, sep
-import yaml
-from .utils.ports import is_reserved_port
-
-
-def test_reserve_port_only_in_base_template(heat_template):
- '''
- Make sure reserved ports are only specified in the base template
- '''
- basename = path.splitext(heat_template)[0].rsplit(sep, 1)[1]
- if (basename.endswith("_base") or
- basename.startswith("base_") or
- basename.find("_base_") > 0):
- pytest.skip("A base template may or may not have reserved ports")
-
- # parse the yaml
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- # skip if resources are not defined
- if "resources" not in yml:
- pytest.skip("No resources specified in the heat template")
-
- has_reserved_ports = False
- for k1, v1 in yml["resources"].items():
- if not isinstance(v1, dict):
- continue
- if "properties" not in v1:
- continue
- if v1.get("type") != "OS::Neutron::Port":
- continue
- if not is_reserved_port(k1):
- continue
-
- has_reserved_ports = True
-
- assert not has_reserved_ports
diff --git a/ice_validator/tests/test_volume_templates_outputs_resources.py b/ice_validator/tests/test_volume_templates_outputs_resources.py
index 90096e3..d3cec1e 100644
--- a/ice_validator/tests/test_volume_templates_outputs_resources.py
+++ b/ice_validator/tests/test_volume_templates_outputs_resources.py
@@ -2,7 +2,7 @@
# ============LICENSE_START=======================================================
# org.onap.vvp/validation-scripts
# ===================================================================
-# Copyright © 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
# ===================================================================
#
# Unless otherwise specified, all software contained herein is licensed
@@ -38,7 +38,7 @@
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-import yaml
+from tests import cached_yaml as yaml
import pytest
from .utils.nested_iterables import find_all_get_resource_in_yml
diff --git a/ice_validator/tests/utils/nested_dict.py b/ice_validator/tests/utils/nested_dict.py
index 9bc3e99..24f7e5e 100644
--- a/ice_validator/tests/utils/nested_dict.py
+++ b/ice_validator/tests/utils/nested_dict.py
@@ -62,3 +62,4 @@ def is_dict_has_key(obj, key):
'''return True/False `obj` is a dict and has `key`
'''
return isinstance(obj, dict) and key in obj
+
diff --git a/ice_validator/tests/utils/nested_files.py b/ice_validator/tests/utils/nested_files.py
index 02f733d..c551646 100644
--- a/ice_validator/tests/utils/nested_files.py
+++ b/ice_validator/tests/utils/nested_files.py
@@ -43,17 +43,17 @@
from os import path
import re
-import yaml
+from tests import cached_yaml as yaml
-VERSION = "1.0.2"
+VERSION = '1.0.2'
def get_list_of_nested_files(yml, dirpath):
- """
+ '''
return a list of all nested files
- """
+ '''
- if not hasattr(yml, "items"):
+ if not hasattr(yml, 'items'):
return []
nested_files = []
@@ -63,34 +63,41 @@ def get_list_of_nested_files(yml, dirpath):
t = v["type"]
if t.endswith(".yml") or t.endswith(".yaml"):
filepath = path.join(dirpath, t)
- with open(filepath) as fh:
- t_yml = yaml.load(fh)
- nested_files.append(filepath)
- nested_files.extend(get_list_of_nested_files(t_yml, dirpath))
+ if path.exists(filepath):
+ with open(filepath) as fh:
+ t_yml = yaml.load(fh)
+ nested_files.append(filepath)
+ nested_files.extend(get_list_of_nested_files(t_yml, dirpath))
elif t == "OS::Heat::ResourceGroup":
- rdt = v.get("properties", {}).get("resource_def", {}).get("type", None)
+ rdt = (v.get("properties", {})
+ .get("resource_def", {})
+ .get("type", None))
if rdt and (rdt.endswith(".yml") or rdt.endswith(".yaml")):
filepath = path.join(dirpath, rdt)
- with open(filepath) as fh:
- rdt_yml = yaml.load(fh)
- nested_files.append(filepath)
- nested_files.extend(get_list_of_nested_files(rdt_yml, dirpath))
+ if path.exists(filepath):
+ with open(filepath) as fh:
+ rdt_yml = yaml.load(fh)
+ nested_files.append(filepath)
+ nested_files.extend(
+ get_list_of_nested_files(rdt_yml, dirpath))
if isinstance(v, dict):
- nested_files.extend(get_list_of_nested_files(v, dirpath))
+ nested_files.extend(
+ get_list_of_nested_files(v, dirpath))
elif isinstance(v, list):
for d in v:
- nested_files.extend(get_list_of_nested_files(d, dirpath))
+ nested_files.extend(
+ get_list_of_nested_files(d, dirpath))
return nested_files
def check_for_invalid_nesting(yml, yaml_file, dirpath):
- """
+ '''
return a list of all nested files
- """
- if not hasattr(yml, "items"):
+ '''
+ if not hasattr(yml, 'items'):
return []
invalid_nesting = []
- p = re.compile("^[A-z]*::[A-z]*::[A-z]*$")
+ p = re.compile('^[A-z]*::[A-z]*::[A-z]*$')
for v in yml.values():
if isinstance(v, dict) and "type" in v:
@@ -102,9 +109,7 @@ def check_for_invalid_nesting(yml, yaml_file, dirpath):
if not isinstance(rd, dict) or "type" not in rd:
invalid_nesting.append(yaml_file)
continue
- elif not p.match(rd["type"]) and not (
- rd["type"].endswith(".yml") or rd["type"].endswith(".yaml")
- ):
+ elif not p.match(rd["type"]):
filepath = path.join(dirpath, rd["type"])
else:
continue
@@ -115,11 +120,21 @@ def check_for_invalid_nesting(yml, yaml_file, dirpath):
yml = yaml.load(fh)
except yaml.YAMLError as e:
invalid_nesting.append(filepath)
- print(e) # pylint: disable=superfluous-parens
- invalid_nesting.extend(check_for_invalid_nesting(yml, filepath, dirpath))
+ print(e) # pylint: disable=superfluous-parens
+ invalid_nesting.extend(check_for_invalid_nesting(
+ yml,
+ filepath,
+ dirpath))
if isinstance(v, dict):
- invalid_nesting.extend(check_for_invalid_nesting(v, yaml_file, dirpath))
+ invalid_nesting.extend(check_for_invalid_nesting(
+ v,
+ yaml_file,
+ dirpath))
elif isinstance(v, list):
for d in v:
- invalid_nesting.extend(check_for_invalid_nesting(d, yaml_file, dirpath))
+ invalid_nesting.extend(check_for_invalid_nesting(
+ d,
+ yaml_file,
+ dirpath))
return invalid_nesting
+
diff --git a/ice_validator/tests/utils/network_roles.py b/ice_validator/tests/utils/network_roles.py
index d4b2cce..bed3a5a 100644
--- a/ice_validator/tests/utils/network_roles.py
+++ b/ice_validator/tests/utils/network_roles.py
@@ -43,31 +43,36 @@ import socket
def get_network_role_from_port(resource):
- """
+ '''
get the network role from a neutron port resource
- """
+ '''
if not isinstance(resource, dict):
return None
- if "type" not in resource:
+ if 'type' not in resource:
return None
- if resource["type"] != "OS::Neutron::Port":
+ if resource['type'] != 'OS::Neutron::Port':
return None
- if "properties" not in resource:
+ if 'properties' not in resource:
return None
formats = [
- ["network", "string", "internal", re.compile(r"int_(.+?)_net_id")],
- ["network", "string", "internal", re.compile(r"int_(.+?)_net_name")],
- ["network", "string", "external", re.compile(r"(.+?)_net_id")],
- ["network", "string", "external", re.compile(r"(.+?)_net_name")],
- ]
+ ["network", "string", "internal",
+ re.compile(r'int_(.+?)_net_id')],
+ ["network", "string", "internal",
+ re.compile(r'int_(.+?)_net_name')],
+ ["network", "string", "external",
+ re.compile(r'(.+?)_net_id')],
+ ["network", "string", "external",
+ re.compile(r'(.+?)_net_name')]]
for k1, v1 in resource["properties"].items():
- if k1 != "network":
+ if k1 != 'network':
continue
# get the network id or name
- network = v1.get("get_param") or v1.get("get_resource")
+ network = (
+ v1.get('get_param') or
+ v1.get('get_resource'))
if not network:
continue
@@ -79,28 +84,41 @@ def get_network_role_from_port(resource):
return None
+def get_network_roles(resources):
+ network_roles = []
+ for v in resources.values():
+ nr = get_network_role_from_port(v)
+ if nr:
+ network_roles.append(nr)
+
+ return set(network_roles)
+
+
def get_network_type_from_port(resource):
- """
+ '''
get the network type from a neutron port resource
- """
+ '''
if not isinstance(resource, dict):
return None
- if "type" not in resource:
+ if 'type' not in resource:
return None
- if resource["type"] != "OS::Neutron::Port":
+ if resource['type'] != 'OS::Neutron::Port':
return None
- if "properties" not in resource:
+ if 'properties' not in resource:
return None
formats = [
- ["network", "string", "internal", re.compile(r"int_(.+?)_net_id")],
- ["network", "string", "internal", re.compile(r"int_(.+?)_net_name")],
- ["network", "string", "external", re.compile(r"(.+?)_net_id")],
- ["network", "string", "external", re.compile(r"(.+?)_net_name")],
- ]
+ ["network", "string", "internal",
+ re.compile(r'int_(.+?)_net_id')],
+ ["network", "string", "internal",
+ re.compile(r'int_(.+?)_net_name')],
+ ["network", "string", "external",
+ re.compile(r'(.+?)_net_id')],
+ ["network", "string", "external",
+ re.compile(r'(.+?)_net_name')]]
for k1, v1 in resource["properties"].items():
- if k1 != "network":
+ if k1 != 'network':
continue
if "get_param" not in v1:
continue
@@ -112,22 +130,22 @@ def get_network_type_from_port(resource):
return None
-def is_valid_ip_address(ip_address, ip_type="ipv4"):
- """
+def is_valid_ip_address(ip_address, ip_type='ipv4'):
+ '''
check if an ip address is valid
- """
- if ip_type == "ipv4":
+ '''
+ if ip_type == 'ipv4':
return is_valid_ipv4_address(ip_address)
- elif ip_type == "ipv6":
+ elif ip_type == 'ipv6':
return is_valid_ipv6_address(ip_address)
return False
def is_valid_ipv4_address(ip_address):
- """
+ '''
check if an ip address of the type ipv4
is valid
- """
+ '''
try:
socket.inet_pton(socket.AF_INET, ip_address)
except AttributeError:
@@ -135,17 +153,17 @@ def is_valid_ipv4_address(ip_address):
socket.inet_aton(ip_address)
except (OSError, socket.error):
return False
- return ip_address.count(".") == 3
+ return ip_address.count('.') == 3
except (OSError, socket.error):
return False
return True
def is_valid_ipv6_address(ip_address):
- """
+ '''
check if an ip address of the type ipv6
is valid
- """
+ '''
try:
socket.inet_pton(socket.AF_INET6, ip_address)
except (OSError, socket.error):
@@ -154,13 +172,13 @@ def is_valid_ipv6_address(ip_address):
def property_uses_get_resource(resource, property_name):
- """
+ '''
returns true if a port's network property
uses the get_resource function
- """
+ '''
if not isinstance(resource, dict):
return False
- if "properties" not in resource:
+ if 'properties' not in resource:
return False
for k1, v1 in resource["properties"].items():
if k1 != property_name:
diff --git a/ice_validator/tests/utils/ports.py b/ice_validator/tests/utils/ports.py
index e479201..a2ae8a9 100644
--- a/ice_validator/tests/utils/ports.py
+++ b/ice_validator/tests/utils/ports.py
@@ -43,125 +43,89 @@ from .vm_types import get_vm_type_for_nova_server
import re
-def is_valid_ip_address(ip_address, vm_type, network_role, port_property):
- """
+def is_valid_ip_address(ip_address, vm_type, network_role, port_property, parameter_type):
+ '''
Check the ip_address to make sure it is properly formatted and
also contains {vm_type} and {network_role}
- """
+ '''
allowed_formats = [
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_floating_v6_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_floating_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "external",
- re.compile(r"(.+?)_floating_v6_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "external",
- re.compile(r"(.+?)_floating_ip"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_v6_ip_\d+"),
- ],
- [
- "allowed_address_pairs",
- "string",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_ip_\d+"),
- ],
- ["allowed_address_pairs", "string", "external", re.compile(r"(.+?)_v6_ip_\d+")],
- ["allowed_address_pairs", "string", "external", re.compile(r"(.+?)_ip_\d+")],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_v6_ips"),
- ],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_ips"),
- ],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "external",
- re.compile(r"(.+?)_v6_ips"),
- ],
- [
- "allowed_address_pairs",
- "comma_delimited_list",
- "external",
- re.compile(r"(.+?)_ips"),
- ],
- ["fixed_ips", "string", "internal", re.compile(r"(.+?)_int_(.+?)_v6_ip_\d+")],
- ["fixed_ips", "string", "internal", re.compile(r"(.+?)_int_(.+?)_ip_\d+")],
- ["fixed_ips", "string", "external", re.compile(r"(.+?)_v6_ip_\d+")],
- ["fixed_ips", "string", "external", re.compile(r"(.+?)_ip_\d+")],
- [
- "fixed_ips",
- "comma_delimited_list",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_v6_ips"),
- ],
- [
- "fixed_ips",
- "comma_delimited_list",
- "internal",
- re.compile(r"(.+?)_int_(.+?)_ips"),
- ],
- ["fixed_ips", "comma_delimited_list", "external", re.compile(r"(.+?)_v6_ips")],
- ["fixed_ips", "comma_delimited_list", "external", re.compile(r"(.+?)_ips")],
- ]
+ ["allowed_address_pairs", "string", "internal",
+ re.compile(r'(.+?)_int_(.+?)_floating_v6_ip')],
+ ["allowed_address_pairs", "string", "internal",
+ re.compile(r'(.+?)_int_(.+?)_floating_ip')],
+ ["allowed_address_pairs", "string", "external",
+ re.compile(r'(.+?)_floating_v6_ip')],
+ ["allowed_address_pairs", "string", "external",
+ re.compile(r'(.+?)_floating_ip')],
+ ["allowed_address_pairs", "string", "internal",
+ re.compile(r'(.+?)_int_(.+?)_v6_ip_\d+')],
+ ["allowed_address_pairs", "string", "internal",
+ re.compile(r'(.+?)_int_(.+?)_ip_\d+')],
+ ["allowed_address_pairs", "string", "external",
+ re.compile(r'(.+?)_v6_ip_\d+')],
+ ["allowed_address_pairs", "string", "external",
+ re.compile(r'(.+?)_ip_\d+')],
+ ["allowed_address_pairs", "comma_delimited_list",
+ "internal", re.compile(r'(.+?)_int_(.+?)_v6_ips')],
+ ["allowed_address_pairs", "comma_delimited_list",
+ "internal", re.compile(r'(.+?)_int_(.+?)_ips')],
+ ["allowed_address_pairs", "comma_delimited_list",
+ "external", re.compile(r'(.+?)_v6_ips')],
+ ["allowed_address_pairs", "comma_delimited_list",
+ "external", re.compile(r'(.+?)_ips')],
+ ["fixed_ips", "string", "internal",
+ re.compile(r'(.+?)_int_(.+?)_v6_ip_\d+')],
+ ["fixed_ips", "string", "internal",
+ re.compile(r'(.+?)_int_(.+?)_ip_\d+')],
+ ["fixed_ips", "string", "external",
+ re.compile(r'(.+?)_v6_ip_\d+')],
+ ["fixed_ips", "string", "external",
+ re.compile(r'(.+?)_ip_\d+')],
+ ["fixed_ips", "comma_delimited_list", "internal",
+ re.compile(r'(.+?)_int_(.+?)_v6_ips')],
+ ["fixed_ips", "comma_delimited_list", "internal",
+ re.compile(r'(.+?)_int_(.+?)_ips')],
+ ["fixed_ips", "comma_delimited_list", "external",
+ re.compile(r'(.+?)_v6_ips')],
+ ["fixed_ips", "comma_delimited_list", "external",
+ re.compile(r'(.+?)_ips')]]
for v3 in allowed_formats:
+ if v3[1] != parameter_type:
+ continue
if v3[0] != port_property:
continue
# check if pattern matches
m = v3[3].match(ip_address)
if m:
- if v3[2] == "internal" and len(m.groups()) > 1:
- return m.group(1) == vm_type and m.group(2) == network_role
- elif v3[2] == "external" and len(m.groups()) > 0:
+ if (v3[2] == "internal" and
+ len(m.groups()) > 1):
+ return m.group(1) == vm_type and\
+ m.group(2) == network_role
+ elif (v3[2] == "external" and
+ len(m.groups()) > 0):
return m.group(1) == vm_type + "_" + network_role
return False
-def get_invalid_ip_addresses(resources, port_property):
- """
+def get_invalid_ip_addresses(resources, port_property, parameters):
+ '''
Get a list of valid ip addresses for a heat resources section
- """
+ '''
invalid_ip_addresses = []
for k, v in resources.items():
if not isinstance(v, dict):
continue
- if "type" not in v:
+ if 'type' not in v:
continue
- if v["type"] not in "OS::Nova::Server":
+ if v['type'] not in 'OS::Nova::Server':
continue
- if "properties" not in v:
+ if 'properties' not in v:
continue
- if "networks" not in v["properties"]:
+ if 'networks' not in v['properties']:
continue
port_resource = None
@@ -171,16 +135,16 @@ def get_invalid_ip_addresses(resources, port_property):
continue
# get all ports associated with the nova server
- properties = v["properties"]
- for network in properties["networks"]:
+ properties = v['properties']
+ for network in properties['networks']:
for k3, v3 in network.items():
- if k3 != "port":
+ if k3 != 'port':
continue
if not isinstance(v3, dict):
continue
- if "get_resource" in v3:
- port_id = v3["get_resource"]
+ if 'get_resource' in v3:
+ port_id = v3['get_resource']
if not resources[port_id]:
continue
port_resource = resources[port_id]
@@ -199,15 +163,23 @@ def get_invalid_ip_addresses(resources, port_property):
continue
if "get_param" not in v2["ip_address"]:
continue
-
ip_address = v2["ip_address"]["get_param"]
if isinstance(ip_address, list):
ip_address = ip_address[0]
- valid_ip_address = is_valid_ip_address(
- ip_address, vm_type, network_role, port_property
- )
+ if ip_address not in parameters:
+ continue
+
+ parameter_type = parameters[ip_address].get("type")
+ if not parameter_type:
+ continue
+
+ valid_ip_address = is_valid_ip_address(ip_address,
+ vm_type,
+ network_role,
+ port_property,
+ parameter_type)
if not valid_ip_address:
invalid_ip_addresses.append(ip_address)
@@ -216,14 +188,15 @@ def get_invalid_ip_addresses(resources, port_property):
def is_reserved_port(port_id):
- """
+ '''
Checks to see if the resource id for a port follows
the reserve port concept
- """
+ '''
formats = [
- ["port_id", re.compile(r"reserve_port_(.+?)_floating_ip_\d+")],
- ["port_id", re.compile(r"reserve_port_(.+?)_floating_v6_ip_\d+")],
- ]
+ ["port_id",
+ re.compile(r'reserve_port_(.+?)_floating_ip_\d+')],
+ ["port_id",
+ re.compile(r'reserve_port_(.+?)_floating_v6_ip_\d+')]]
for f in formats:
m = f[1].match(port_id.lower())
if m and m.group(1):
diff --git a/ice_validator/tests/utils/vm_types.py b/ice_validator/tests/utils/vm_types.py
index 78006b9..6802666 100644
--- a/ice_validator/tests/utils/vm_types.py
+++ b/ice_validator/tests/utils/vm_types.py
@@ -42,33 +42,36 @@ import re
def get_vm_types_for_resource(resource):
- """
+ '''
Get all unique vm_types for a resource
Notes:
- Returns set([]) if the resource is not formatted
properly, the passed resource is not a nova server
- If more than one vm_type is detected all vm_types will
be returned
- """
+ '''
if not isinstance(resource, dict):
return set()
- if "type" not in resource:
+ if 'type' not in resource:
return set()
- if resource["type"] != "OS::Nova::Server":
+ if resource['type'] != 'OS::Nova::Server':
return set()
- if "properties" not in resource:
+ if 'properties' not in resource:
return set()
key_values = ["name", "flavor", "image"]
key_value_formats = [
- ["name", "string", re.compile(r"(.+?)_name_\d+")],
- ["name", "comma_delimited_list", re.compile(r"(.+?)_names")],
- ["flavor", "string", re.compile(r"(.+?)_flavor_name")],
- ["image", "string", re.compile(r"(.+?)_image_name")],
- ]
+ ["name", "string",
+ re.compile(r'(.+?)_name_\d+')],
+ ["name", "comma_delimited_list",
+ re.compile(r'(.+?)_names')],
+ ["flavor", "string",
+ re.compile(r'(.+?)_flavor_name')],
+ ["image", "string",
+ re.compile(r'(.+?)_image_name')]]
vm_types = []
- for k2, v2 in resource["properties"].items():
+ for k2, v2 in resource['properties'].items():
if k2 not in key_values:
continue
if "get_param" not in v2:
@@ -86,12 +89,12 @@ def get_vm_types_for_resource(resource):
def get_vm_type_for_nova_server(resource):
- """
+ '''
Get the vm_type for a resource
Note: Returns None if not exactly one vm_type
is detected, if the resource is not formatted properly, or
the passed resource is not a nova server
- """
+ '''
vm_types = get_vm_types_for_resource(resource)
# if more than one vm_type was identified, return None
@@ -102,10 +105,10 @@ def get_vm_type_for_nova_server(resource):
def get_vm_types(resources):
- """
+ '''
Get all vm_types for a list of heat resources, do note that
some of the values retrieved may be invalid
- """
+ '''
vm_types = []
for v in resources.values():
vm_types.extend(list(get_vm_types_for_resource(v)))
diff --git a/ice_validator/tests/utils/volumes.py b/ice_validator/tests/utils/volumes.py
index c64c0ee..40731bf 100644
--- a/ice_validator/tests/utils/volumes.py
+++ b/ice_validator/tests/utils/volumes.py
@@ -42,7 +42,7 @@
"""
from os import path
-import yaml
+from tests import cached_yaml as yaml
VERSION = '1.0.0'