2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
8 # Unless otherwise specified, all software contained herein is licensed
9 # under the Apache License, Version 2.0 (the "License");
10 # you may not use this software except in compliance with the License.
11 # You may obtain a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
23 # Unless otherwise specified, all documentation contained herein is licensed
24 # under the Creative Commons License, Attribution 4.0 Intl. (the "License");
25 # you may not use this documentation except in compliance with the License.
26 # You may obtain a copy of the License at
28 # https://creativecommons.org/licenses/by/4.0/
30 # Unless required by applicable law or agreed to in writing, documentation
31 # distributed under the License is distributed on an "AS IS" BASIS,
32 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 # See the License for the specific language governing permissions and
34 # limitations under the License.
36 # ============LICENSE_END============================================
38 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
48 from .structures import CinderVolumeAttachmentProcessor
49 from .structures import NovaServerProcessor
50 from .structures import get_all_resources
51 from .helpers import validates
56 class VmClassValidator(object):
57 """validate VM class has unique type
62 self.vm_classes = None
67 def __call__(self, resources):
68 """return (possibly empty) list of error message strings
71 pytest.skip("No resources found")
72 self.vm_counts = collections.defaultdict(set)
73 self.vm_classes = collections.defaultdict(set)
74 self.vm_rids = collections.defaultdict(set)
75 self.vm_types = collections.defaultdict(set)
76 va_config, self.va_count = CinderVolumeAttachmentProcessor.get_config(resources)
78 pytest.skip("No Cinder Volume Attachment configurations found")
79 for rid, resource in resources.items():
80 vm_class = NovaServerProcessor.get_vm_class(resource)
82 vm_class["cinder_volume_attachment"] = va_config.get(rid)
83 match = NovaServerProcessor.get_rid_match_tuple(rid)[1]
85 vm_type = match.groupdict().get("vm_type")
87 self.vm_classes[vm_class].add(rid)
88 self.vm_types[vm_type].add(vm_class)
89 self.vm_counts[vm_type].add(self.va_count.get(rid))
90 self.vm_rids[vm_type].add(rid)
91 if not self.vm_classes:
92 pytest.skip("No vm_classes found")
93 return self.get_errors()
96 """return (possibly empty) list of error message strings
99 for k, v in self.vm_types.items():
102 "vm-type %s has class conflict %s"
103 % (k, ", ".join(str(list(self.vm_classes[c])) for c in v))
108 % ", ".join([str(key_diff(classes[0], c)) for c in classes[1:]])
110 for k, v in self.vm_counts.items():
113 "Attachment count conflict %s"
114 % ({rid: self.va_count.get(rid) for rid in self.vm_rids[k]})
119 def key_diff(d1, d2, prefix=""):
120 """Return list of keys which differ between d1 and d2 (dicts)
122 diff = [prefix + k for k in d1 if k not in d2]
123 diff.extend(prefix + k for k in d2 if k not in d1)
124 if isinstance(d1, dict) and isinstance(d2, dict):
125 for k, v1 in d1.items():
126 if k in d2 and v1 != d2[k]:
128 if isinstance(v1, type(v2)) and isinstance(v1, (dict, frozenset)):
129 diff.extend(key_diff(v1, v2, prefix=prefix + k + "."))
131 diff.append(prefix + k)
135 @validates("R-01455")
136 def test_vm_class_has_unique_type(yaml_files):
138 When a VNF’s Heat Orchestration Template creates a Virtual
139 Machine (i.e., OS::Nova::Server), each “class” of VMs MUST be
140 assigned a VNF unique vm-type; where “class” defines VMs that
141 MUST have the following identical characteristics:
143 1. OS::Nova::Server resource property flavor value
144 2. OS::Nova::Server resource property image value
145 3. Cinder Volume attachments
146 Each VM in the “class” MUST have the identical Cinder
148 4. Network attachments and IP address requirements
149 Each VM in the “class” MUST have the the identical number of
150 ports connecting to the identical networks and requiring the
151 identical IP address configuration
153 resources = get_all_resources(yaml_files)
154 errors = VmClassValidator()(resources)
155 assert not errors, "\n".join(errors)