#
# ============LICENSE_END============================================
#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-#
-import os
-from os import listdir
from os import path
import pytest
+from yaml import YAMLError
from yaml.constructor import ConstructorError
from tests import cached_yaml as yaml
from tests.utils import yaml_custom_utils
-from .helpers import validates
-from yamllint.config import YamlLintConfig
-from yamllint import linter
-from .utils.nested_files import check_for_invalid_nesting
-from .utils.nested_files import get_list_of_nested_files
-from .utils.nested_iterables import find_all_get_resource_in_yml
-from .utils.nested_iterables import find_all_get_param_in_yml
-
-"""
-Order tests by number so they execute in order for base tests
-"""
+from tests.helpers import validates, load_yaml
+from tests.utils.nested_files import check_for_invalid_nesting
+from tests.utils.nested_iterables import find_all_get_resource_in_yml
+from tests.utils.nested_iterables import find_all_get_param_in_yml
@pytest.mark.base
@validates("R-95303")
def test_00_valid_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.
- """
- conf = YamlLintConfig("rules: {}")
+ if path.splitext(filename)[-1].lower() not in (".yml", ".yaml", ".env"):
+ pytest.skip("Not a YAML file")
+ try:
+ load_yaml(filename)
+ except YAMLError as e:
+ assert False, (
+ "Invalid YAML detected: {} "
+ "NOTE: Online YAML checkers such as yamllint.com "
+ "can helpful in diagnosing errors in YAML"
+ ).format(str(e).replace("\n", " "))
- if path.splitext(filename)[-1] in [".yml", ".yaml", ".env"]:
- gen = linter.run(open(filename), conf)
- errors = list(gen)
- assert not errors, "Error parsing file {} with error {}".format(
- filename, errors
- )
- else:
- pytest.skip(
- "The file does not have any of the extensions .yml,\
- .yaml, or .env"
- )
+def check_duplicate_keys(yaml_path):
+ import yaml as normal_yaml
+
+ try:
+ with open(yaml_path) as fh:
+ normal_yaml.load(fh, yaml_custom_utils.UniqueKeyLoader) # nosec
+ except ConstructorError as e:
+ pytest.fail("{} {}".format(e.problem, e.problem_mark))
@pytest.mark.base
@validates("R-92635")
def test_02_no_duplicate_keys_in_file(yaml_file):
- """
- Checks that no duplicate keys exist in a given YAML file.
- """
- import yaml as normal_yaml # we can't use the caching version in this test
+ check_duplicate_keys(yaml_file)
- normal_yaml.add_constructor(
- yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
- yaml_custom_utils.raise_duplicates_keys,
- )
- try:
- with open(yaml_file) as fh:
- normal_yaml.load(fh)
- except ConstructorError as e:
- pytest.fail("{} {}".format(e.problem, e.problem_mark))
+@pytest.mark.base
+@validates("R-92635")
+def test_02a_no_duplicate_keys_in_env(env_file):
+ check_duplicate_keys(env_file)
@pytest.mark.base
+@validates("R-92635")
def test_03_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)
+ yml = yaml.safe_load(fh)
# skip if resources are not defined
if "resources" not in yml:
@pytest.mark.base
+@validates("R-92635")
def test_04_valid_nesting(yaml_file):
"""
Check that the nesting is following the proper format and
@pytest.mark.base
+@validates("R-92635")
def test_05_all_get_param_have_defined_parameter(yaml_file):
"""
Check that all referenced parameters are actually defined
@validates("R-90152")
@pytest.mark.base
-def test_06_heat_template_resource_section_has_resources(heat_template):
-
- found_resource = False
-
- with open(heat_template) as fh:
- yml = yaml.load(fh)
-
- resources = yml.get("resources")
- if resources:
- for k1, v1 in yml["resources"].items():
- if not isinstance(v1, dict):
- continue
-
- found_resource = True
- break
-
- assert found_resource, "Heat templates must contain at least one resource"
-
-
-@validates("R-52530")
-@pytest.mark.base
-def test_07_nested_template_in_same_directory(yaml_file):
-
- missing_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 heat template")
-
- dirname = os.path.dirname(yaml_file)
- list_of_files = get_list_of_nested_files(yml, dirname)
- dir_files = listdir(dirname)
- for file in list_of_files:
- base_name = path.basename(file)
- if base_name not in dir_files:
- missing_files.append(base_name)
-
+def test_06_heat_template_resource_section_has_resources(yaml_file):
+ template = load_yaml(yaml_file)
+ if "resources" not in template:
+ pytest.skip("No resources section")
assert (
- not missing_files
- ), "Missing nested files in heat template directory {}".format(missing_files)
+ len(template["resources"]) > 0
+ ), "If resources section present, then there must be at least 1 resource defined."