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