[VVP] updating validation scripts in dublin
[vvp/validation-scripts.git] / ice_validator / tests / parametrizers.py
1 # -*- coding: utf8 -*-
2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
7 #
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
12 #
13 #             http://www.apache.org/licenses/LICENSE-2.0
14 #
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.
20 #
21 #
22 #
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
27 #
28 #             https://creativecommons.org/licenses/by/4.0/
29 #
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.
35 #
36 # ============LICENSE_END============================================
37 #
38 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
39 #
40
41 """parametrizers
42 """
43
44 from os import path, listdir
45 import re
46 from tests import cached_yaml as yaml
47 import pytest
48 from .helpers import get_parsed_yml_for_yaml_files, check_basename_ending
49 from .utils.nested_files import get_list_of_nested_files
50
51 VERSION = "1.0.0"
52
53 # pylint: disable=invalid-name
54
55
56 def get_template_dir(metafunc):
57     """
58     returns template_dir, either as its passed in on CLI
59     or, during --self-test, the directory whos name matches
60     the current tests module name
61     """
62     if metafunc.config.getoption("template_dir") is None:
63         return path.join(
64             path.dirname(metafunc.module.__file__),
65             "fixtures",
66             metafunc.function.__module__.split(".")[-1],
67         )
68     else:
69         return metafunc.config.getoption("template_dir")[0]
70
71
72 def file_is_a_nested_template(file):
73     directory = path.dirname(file)
74     nested_files = []
75     for filename in listdir(directory):
76         if filename.endswith(".yaml") or filename.endswith(".yml"):
77             filename = "{}/{}".format(directory, filename)
78             try:
79                 with open(filename) as fh:
80                     yml = yaml.load(fh)
81                 if "resources" not in yml:
82                     continue
83                 nested_files.extend(
84                     get_list_of_nested_files(yml["resources"], path.dirname(filename))
85                 )
86             except yaml.YAMLError as e:
87                 print(e)  # pylint: disable=superfluous-parens
88                 continue
89     return file in nested_files
90
91
92 def get_nested_files(filenames):
93     """
94     returns all the nested files for a set of filenames
95     """
96     nested_files = []
97     for filename in filenames:
98         if file_is_a_nested_template(filename):
99             nested_files.append(filename)
100     return nested_files
101
102
103 def list_filenames_in_template_dir(
104     metafunc, extensions, template_type="", sub_dirs=None
105 ):
106     """
107     returns the filenames in a template_dir, either as its passed in
108     on CLI or, during --self-test, the directory whos name matches
109     the current tests module name
110     """
111     sub_dirs = [] if sub_dirs is None else sub_dirs
112     template_dir = get_template_dir(metafunc)
113     filenames = []
114     if metafunc.config.getoption("self_test"):
115         filenames = [
116             path.join(template_dir, s, f)
117             for s in sub_dirs
118             for f in listdir(path.join(template_dir, s))
119             if path.isfile(path.join(template_dir, s, f))
120             and path.splitext(f)[-1] in extensions
121             and check_basename_ending(template_type, path.splitext(f)[0])
122         ]
123     else:
124         filenames = [
125             path.join(template_dir, f)
126             for f in listdir(template_dir)
127             if path.isfile(path.join(template_dir, f))
128             and path.splitext(f)[-1] in extensions
129             and check_basename_ending(template_type, path.splitext(f)[0])
130         ]
131     return filenames
132
133
134 def list_template_dir(
135     metafunc, extensions, exclude_nested=True, template_type="", sub_dirs=None
136 ):
137     """
138     returns the filenames excluding the nested files for a template_dir,
139     either as its passed in on CLI or, during --self-test, the
140     directory whos name matches the current tests module name
141     """
142     sub_dirs = [] if sub_dirs is None else sub_dirs
143     filenames = []
144     nested_files = []
145     filenames = list_filenames_in_template_dir(
146         metafunc, extensions, template_type, sub_dirs
147     )
148     if exclude_nested:
149         nested_files = get_nested_files(filenames)
150     return list(set(filenames) - set(nested_files))
151
152
153 def get_filenames_list(
154     metafunc, extensions=None, exclude_nested=False, template_type=""
155 ):
156     """
157     returns the filename fixtures for the template dir, either as by how its
158     passed in on CLI or, during --self-test, the directory whos name
159     matches the current tests module name
160     """
161     extensions = [".yaml", ".yml", ".env"] if extensions is None else extensions
162     if metafunc.config.getoption("self_test"):
163         filenames_list = list_template_dir(
164             metafunc, extensions, exclude_nested, template_type, ["pass"]
165         )
166         filenames_list += [
167             pytest.mark.xfail(f, strict=True)
168             for f in list_template_dir(
169                 metafunc, extensions, exclude_nested, template_type, ["fail"]
170             )
171         ]
172     else:
173         filenames_list = list_template_dir(
174             metafunc, extensions, exclude_nested, template_type
175         )
176
177     return filenames_list
178
179
180 def get_filenames_lists(
181     metafunc, extensions=None, exclude_nested=False, template_type=""
182 ):
183     """
184     returns the list of files in the template dir, either as by how its
185     passed in on CLI or, during --self-test, the directory whos name
186     matches the current tests module name
187     """
188     extensions = [".yaml", ".yml", ".env"] if extensions is None else extensions
189     filenames_lists = []
190     if metafunc.config.getoption("self_test"):
191         filenames_lists.append(
192             list_template_dir(
193                 metafunc, extensions, exclude_nested, template_type, ["pass"]
194             )
195         )
196         filenames_lists.append(
197             pytest.mark.xfail(
198                 list_template_dir(
199                     metafunc, extensions, exclude_nested, template_type, ["fail"]
200                 ),
201                 strict=True,
202             )
203         )
204     else:
205         filenames_lists.append(
206             list_template_dir(metafunc, extensions, exclude_nested, template_type)
207         )
208     return filenames_lists
209
210
211 def get_parsed_yaml_files(
212     metafunc, extensions, exclude_nested=True, template_type="", sections=None
213 ):
214     """
215     returns the list of parsed yaml files in the specified template dir,
216     either as by how its passed in on CLI or, during --self-test, the
217     directory whos name matches the current tests module name
218     """
219     sections = [] if sections is None else sections
220     extensions = [".yaml", ".yml"]
221
222     if metafunc.config.getoption("self_test"):
223         yaml_files = list_template_dir(
224             metafunc, extensions, exclude_nested, template_type, ["pass"]
225         )
226         parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files, sections)
227
228         yaml_files = list_template_dir(
229             metafunc, extensions, exclude_nested, template_type, ["fail"]
230         )
231         parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files, sections)
232         parsed_yml_list += [
233             pytest.mark.xfail(parsed_yml, strict=True) for parsed_yml in parsed_yml_list
234         ]
235     else:
236         yaml_files = list_template_dir(metafunc, extensions)
237         parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files, sections)
238     return parsed_yml_list
239
240
241 def parametrize_filenames(metafunc):
242     """
243     This param runs tests all files in the template dir
244     """
245     filenames = get_filenames_lists(metafunc)
246     metafunc.parametrize("filenames", filenames)
247
248
249 def parametrize_filename(metafunc):
250     """
251     This param runs tests once for every file in the template dir
252     """
253     filenames = get_filenames_list(metafunc)
254     metafunc.parametrize("filename", filenames)
255
256
257 def parametrize_yaml_files(metafunc):
258     """
259     This param runs tests for the yaml files in the template dir
260     """
261     yaml_files = get_filenames_lists(metafunc, [".yaml", ".yml"], False)
262     metafunc.parametrize("yaml_files", yaml_files)
263
264
265 def parametrize_yaml_file(metafunc):
266     """
267     This param runs tests for every yaml file in the template dir
268     """
269     yaml_files = get_filenames_list(metafunc, [".yaml", ".yml"], False)
270     metafunc.parametrize("yaml_file", yaml_files)
271
272
273 def parametrize_templates(metafunc):
274     """
275     This param runs tests for the template in the template dir
276     """
277     templates = get_filenames_lists(metafunc, [".yaml", ".yml"], True)
278     metafunc.parametrize("templates", templates)
279
280
281 def parametrize_template(metafunc):
282     """
283     This param runs tests for every template in the template dir
284     """
285     templates = get_filenames_list(metafunc, [".yaml", ".yml"], True)
286     metafunc.parametrize("template", templates)
287
288
289 def parametrize_parsed_yaml_file(metafunc):
290     """
291     This param runs tests for a parsed version of each yaml file
292     in the template dir
293     """
294     parsed_yaml_files = get_parsed_yaml_files(metafunc, [".yaml", ".yml"], False)
295     metafunc.parametrize("parsed_yaml_file", parsed_yaml_files)
296
297
298 def parametrize_heat_templates(metafunc):
299     """
300     This param runs tests for all heat templates in the template dir
301     """
302     heat_templates = get_filenames_lists(metafunc, [".yaml", ".yml"], True, "heat")
303     metafunc.parametrize("heat_templates", heat_templates)
304
305
306 def parametrize_heat_template(metafunc):
307     """
308     This param runs tests for every heat template in the template dir
309     """
310     heat_templates = get_filenames_list(metafunc, [".yaml", ".yml"], True, "heat")
311     metafunc.parametrize("heat_template", heat_templates)
312
313
314 def parametrize_volume_templates(metafunc):
315     """
316     This param runs tests for all volume templates in the template dir
317     """
318     volume_templates = get_filenames_lists(metafunc, [".yaml", ".yml"], True, "volume")
319     metafunc.parametrize("volume_templates", volume_templates)
320
321
322 def parametrize_volume_template(metafunc):
323     """
324
325     This param runs tests for every volume template in the template dir
326     """
327     volume_templates = get_filenames_list(metafunc, [".yaml", ".yml"], True, "volume")
328     metafunc.parametrize("volume_template", volume_templates)
329
330
331 def parametrize_environment_files(metafunc):
332     """
333     This param runs tests for all environment files in the template dir
334     """
335     env_files = get_filenames_lists(metafunc, [".env"])
336     metafunc.parametrize("env_files", env_files)
337
338
339 def parametrize_environment_file(metafunc):
340     """
341     This param runs tests for every environment file in the template dir
342     """
343     env_files = get_filenames_list(metafunc, [".env"])
344     metafunc.parametrize("env_file", env_files)
345
346
347 def parametrize_parsed_environment_file(metafunc):
348     """
349     This param runs tests for every parsed environment file
350     in the template dir
351     """
352     parsed_env_files = get_parsed_yaml_files(metafunc, [".env"])
353     metafunc.parametrize("parsed_env_file", parsed_env_files)
354
355
356 def parametrize_template_dir(metafunc):
357     """
358     This param passes a  the template_dir as passed in on CLI
359     or, during --self-test, passes in the sub directories of
360     template_dir/pass/ and template_dir/fail
361     template_dir = get_template_dir(metafunc)
362     """
363     template_dir = get_template_dir(metafunc)
364
365     if metafunc.config.getoption("self_test"):
366         dirs = [
367             path.join(template_dir, s, t)
368             for s in ["pass"]
369             for t in listdir(path.join(template_dir, s))
370             if path.isdir(path.join(template_dir, s, t))
371         ]
372
373         dirs += [
374             pytest.mark.xfail(path.join(template_dir, s, t))
375             for s in ["fail"]
376             for t in listdir(path.join(template_dir, s))
377             if path.isdir(path.join(template_dir, s, t))
378         ]
379     else:
380         dirs = [template_dir]
381
382     metafunc.parametrize("template_dir", dirs)
383
384
385 def parametrize_environment_pair(metafunc, template_type=""):
386     """
387     Define a list of pairs of parsed yaml from the heat templates and
388     environment files
389     """
390     pairs = []
391     if metafunc.config.getoption("self_test"):
392         sub_dirs = ["pass", "fail"]
393         env_files = list_template_dir(metafunc, [".env"], True, template_type, sub_dirs)
394         yaml_files = list_template_dir(
395             metafunc, [".yaml", ".yml"], True, template_type, sub_dirs
396         )
397     else:
398         env_files = list_template_dir(metafunc, [".env"], True, template_type)
399         yaml_files = list_template_dir(metafunc, [".yaml", ".yml"], True, template_type)
400
401     for filename in env_files:
402         basename = path.splitext(filename)[0]
403         if basename + ".yml" in yaml_files:
404             yfilename = basename + ".yml"
405         else:
406             yfilename = basename + ".yaml"
407
408         try:
409             with open(filename) as fh:
410                 eyml = yaml.load(fh)
411             with open(yfilename) as fh:
412                 yyml = yaml.load(fh)
413
414             if "fail" in filename:
415                 pairs.append(
416                     pytest.mark.xfail(
417                         {"name": basename, "yyml": yyml, "eyml": eyml}, strict=True
418                     )
419                 )
420             else:
421                 pairs.append({"name": basename, "yyml": yyml, "eyml": eyml})
422
423         except yaml.YAMLError as e:
424             print(e)  # pylint: disable=superfluous-parens
425
426     metafunc.parametrize("environment_pair", pairs)
427
428
429 def parametrize_heat_volume_pair(metafunc):
430     """
431     Define a list of pairs of parsed yaml from the a heat and volume
432     template
433     """
434     pairs = []
435     if metafunc.config.getoption("self_test"):
436         sub_dirs = ["pass", "fail"]
437         volume_files = list_template_dir(
438             metafunc, [".yaml", ".yml"], True, "volume", sub_dirs
439         )
440         yaml_files = list_template_dir(metafunc, [".yaml", ".yml"], True, "", sub_dirs)
441     else:
442         volume_files = list_template_dir(metafunc, [".yaml", ".yml"], True, "volume")
443         yaml_files = list_template_dir(metafunc, [".yaml", ".yml"], True)
444
445     pattern = re.compile(r"\_volume$")
446     for vfilename in volume_files:
447         basename = pattern.sub("", path.splitext(vfilename)[0])
448         if basename + ".yml" in yaml_files:
449             yfilename = basename + ".yml"
450         else:
451             yfilename = basename + ".yaml"
452
453         try:
454             with open(vfilename) as fh:
455                 vyml = yaml.load(fh)
456             with open(yfilename) as fh:
457                 yyml = yaml.load(fh)
458
459             if "fail" in vfilename:
460                 pairs.append(
461                     pytest.mark.xfail(
462                         {"name": basename, "yyml": yyml, "vyml": vyml}, strict=True
463                     )
464                 )
465             else:
466                 pairs.append({"name": basename, "yyml": yyml, "vyml": vyml})
467
468         except yaml.YAMLError as e:
469             print(e)  # pylint: disable=superfluous-parens
470
471     metafunc.parametrize("heat_volume_pair", pairs)