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