Fixed error message get_attr test
[vvp/validation-scripts.git] / ice_validator / tests / test_get_attr_usage.py
1 import os
2
3 import pytest
4
5 from tests.helpers import validates, traverse, load_yaml
6 from tests.structures import Resource
7 from tests.utils import nested_dict
8
9
10 class GetAttrValidator:
11     def __init__(self, yaml, base_dir):
12         self.yaml = yaml
13         self.base_dir = base_dir
14         self.errors = []
15
16     @property
17     def resources(self):
18         return self.yaml.get("resources", {})
19
20     def __call__(self, path, get_attr_arg):
21         if not isinstance(get_attr_arg, list):
22             self.add_error(path, get_attr_arg, "get_attr argument is not a list")
23         elif len(get_attr_arg) < 1:
24             self.add_error(
25                 path, get_attr_arg, "get_attr argument must have a parameter"
26             )
27         elif get_attr_arg[0] not in self.resources:
28             self.add_error(
29                 path,
30                 get_attr_arg,
31                 "Resource ID could not be found.  Please ensure "
32                 "the resource is spelled correctly and defined "
33                 "under the resources section of the YAML file.",
34             )
35         else:
36             r_id = get_attr_arg[0]
37             r = Resource(r_id, self.yaml["resources"][r_id])
38             if not r.is_nested():
39                 return
40             if len(get_attr_arg) < 2:
41                 self.add_error(
42                     path,
43                     get_attr_arg,
44                     "get_attr used on nested "
45                     "resource, but no attribute "
46                     "value specified",
47                 )
48                 return
49             expected_param = get_attr_arg[1]
50             nested_yaml = r.get_nested_yaml(self.base_dir)
51             param = nested_dict.get(nested_yaml, "outputs", expected_param)
52             if not param:
53                 self.add_error(
54                     path,
55                     get_attr_arg,
56                     "Attribute key "
57                     + expected_param
58                     + " not found in outputs "
59                     + r.get_nested_filename(),
60                 )
61
62     def add_error(self, path, arg, message):
63         path_str = ".".join(map(str, path))
64         self.errors.append("{} {}: {}".format(path_str, arg, message))
65
66     @property
67     def error_message(self):
68         errs = "\n".join(self.errors)
69         return "Invalid get_attr usage detected: {}".format(errs)
70
71
72 @pytest.mark.base
73 @validates("R-95303")
74 def test_08_validate_get_attr_usage(yaml_file):
75     """Ensures that every get_attr refers to a valid resource name,
76     and if that resource is a nested YAML that the attribute exists as
77     an output of the nested YAML file.  It does not validate the
78     attribute keys are always valid because of the attributes could
79     refer to intrinsic attributes of the resource that are not present
80     in the YAML file."""
81
82     yml = load_yaml(yaml_file)
83     base_dir, _ = os.path.split(yaml_file)
84     validator = GetAttrValidator(yml, base_dir)
85     traverse(yml, "get_attr", validator)
86     assert not validator.errors, validator.error_message