641d53ab13942fcdd94181d3d5e3ca57113c1689
[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(path.realpath(__file__)),
65             'fixtures',
66             metafunc.function.__module__.split('.')[-1])
67     else:
68         return metafunc.config.getoption('template_dir')[0]
69
70
71 def get_nested_files(filenames):
72     '''
73     returns all the nested files for a set of filenames
74     '''
75     nested_files = []
76     for filename in filenames:
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(get_list_of_nested_files(
83                 yml["resources"],
84                 path.dirname(filename)))
85         except yaml.YAMLError as e:
86             print(e)  # pylint: disable=superfluous-parens
87             continue
88     return nested_files
89
90
91 def list_filenames_in_template_dir(metafunc,
92                                    extensions,
93                                    template_type='',
94                                    sub_dirs=None):
95     '''
96     returns the filenames in a template_dir, either as its passed in
97     on CLI or, during --self-test, the directory whos name matches
98     the current tests module name
99     '''
100     sub_dirs = [] if sub_dirs is None else sub_dirs
101     template_dir = get_template_dir(metafunc)
102     filenames = []
103     if metafunc.config.getoption('self_test'):
104         filenames = [path.join(template_dir, s, f)
105                      for s in sub_dirs
106                      for f in listdir(path.join(template_dir, s))
107                      if path.isfile(path.join(template_dir, s, f))
108                      and path.splitext(f)[-1] in extensions
109                      and check_basename_ending(template_type,
110                                                path.splitext(f)[0])]
111     else:
112         filenames = [path.join(template_dir, f)
113                      for f in listdir(template_dir)
114                      if path.isfile(path.join(template_dir, f))
115                      and path.splitext(f)[-1] in extensions
116                      and check_basename_ending(template_type,
117                                                path.splitext(f)[0])]
118     return filenames
119
120
121 def list_template_dir(metafunc,
122                       extensions,
123                       exclude_nested=True,
124                       template_type='',
125                       sub_dirs=None):
126     '''
127     returns the filenames excluding the nested files for a template_dir,
128     either as its passed in on CLI or, during --self-test, the
129     directory whos name matches the current tests module name
130     '''
131     sub_dirs = [] if sub_dirs is None else sub_dirs
132     filenames = []
133     nested_files = []
134     filenames = list_filenames_in_template_dir(metafunc,
135                                                extensions,
136                                                template_type,
137                                                sub_dirs)
138     if exclude_nested:
139         nested_files = get_nested_files(filenames)
140     return list(set(filenames) - set(nested_files))
141
142
143 def get_filenames_list(metafunc,
144                        extensions=None,
145                        exclude_nested=False,
146                        template_type=''):
147     '''
148     returns the filename fixtures for the template dir, either as by how its
149     passed in on CLI or, during --self-test, the directory whos name
150     matches the current tests module name
151     '''
152     extensions = [".yaml",
153                   ".yml",
154                   ".env"] if extensions is None else extensions
155     if metafunc.config.getoption('self_test'):
156         filenames_list = list_template_dir(metafunc,
157                                            extensions,
158                                            exclude_nested,
159                                            template_type,
160                                            ['pass'])
161         filenames_list += [pytest.mark.xfail(f, strict=True)
162                            for f in list_template_dir(metafunc,
163                                                       extensions,
164                                                       exclude_nested,
165                                                       template_type,
166                                                       ['fail'])]
167     else:
168         filenames_list = list_template_dir(metafunc,
169                                            extensions,
170                                            exclude_nested,
171                                            template_type)
172
173     return filenames_list
174
175
176 def get_filenames_lists(metafunc,
177                         extensions=None,
178                         exclude_nested=False,
179                         template_type=''):
180     '''
181     returns the list of files in the template dir, either as by how its
182     passed in on CLI or, during --self-test, the directory whos name
183     matches the current tests module name
184     '''
185     extensions = [".yaml",
186                   ".yml",
187                   ".env"] if extensions is None else extensions
188     filenames_lists = []
189     if metafunc.config.getoption('self_test'):
190         filenames_lists.append(list_template_dir(metafunc,
191                                                  extensions,
192                                                  exclude_nested,
193                                                  template_type,
194                                                  ['pass']))
195         filenames_lists.append(pytest.mark.xfail(
196             list_template_dir(metafunc,
197                               extensions,
198                               exclude_nested,
199                               template_type,
200                               ['fail']), strict=True))
201     else:
202         filenames_lists.append(list_template_dir(metafunc,
203                                                  extensions,
204                                                  exclude_nested,
205                                                  template_type))
206     return filenames_lists
207
208
209 def get_parsed_yaml_files(metafunc,
210                           extensions,
211                           exclude_nested=True,
212                           template_type='',
213                           sections=None):
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(metafunc, extensions, exclude_nested,
224                                        template_type, ['pass'])
225         parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files,
226                                                         sections)
227
228         yaml_files = list_template_dir(metafunc, extensions, exclude_nested,
229                                        template_type, ['fail'])
230         parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files,
231                                                         sections)
232         parsed_yml_list += [pytest.mark.xfail(parsed_yml, strict=True)
233                             for parsed_yml in parsed_yml_list]
234     else:
235         yaml_files = list_template_dir(metafunc, extensions)
236         parsed_yml_list = get_parsed_yml_for_yaml_files(yaml_files,
237                                                         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'],
295                                               False)
296     metafunc.parametrize('parsed_yaml_file', parsed_yaml_files)
297
298
299 def parametrize_heat_templates(metafunc):
300     '''
301     This param runs tests for all heat templates in the template dir
302     '''
303     heat_templates = get_filenames_lists(metafunc, ['.yaml', '.yml'],
304                                          True, 'heat')
305     metafunc.parametrize('heat_templates', heat_templates)
306
307
308 def parametrize_heat_template(metafunc):
309     '''
310     This param runs tests for every heat template in the template dir
311     '''
312     heat_templates = get_filenames_list(metafunc, ['.yaml', '.yml'],
313                                         True, 'heat')
314     metafunc.parametrize('heat_template', heat_templates)
315
316
317 def parametrize_volume_templates(metafunc):
318     '''
319     This param runs tests for all volume templates in the template dir
320     '''
321     volume_templates = get_filenames_lists(metafunc, ['.yaml', '.yml'],
322                                            True, 'volume')
323     metafunc.parametrize('volume_templates', volume_templates)
324
325
326 def parametrize_volume_template(metafunc):
327     '''
328
329     This param runs tests for every volume template in the template dir
330     '''
331     volume_templates = get_filenames_list(metafunc, ['.yaml', '.yml'],
332                                           True, 'volume')
333     metafunc.parametrize('volume_template', volume_templates)
334
335
336 def parametrize_environment_files(metafunc):
337     '''
338     This param runs tests for all environment files in the template dir
339     '''
340     env_files = get_filenames_lists(metafunc, ['.env'])
341     metafunc.parametrize('env_files', env_files)
342
343
344 def parametrize_environment_file(metafunc):
345     '''
346     This param runs tests for every environment file in the template dir
347     '''
348     env_files = get_filenames_list(metafunc, ['.env'])
349     metafunc.parametrize('env_file', env_files)
350
351
352 def parametrize_parsed_environment_file(metafunc):
353     '''
354     This param runs tests for every parsed environment file
355     in the template dir
356     '''
357     parsed_env_files = get_parsed_yaml_files(metafunc, ['.env'])
358     metafunc.parametrize('parsed_env_file', parsed_env_files)
359
360
361 def parametrize_template_dir(metafunc):
362     '''
363     This param passes a  the template_dir as passed in on CLI
364     or, during --self-test, passes in the sub directories of
365     template_dir/pass/ and template_dir/fail
366     template_dir = get_template_dir(metafunc)
367     '''
368     template_dir = get_template_dir(metafunc)
369
370     if metafunc.config.getoption('self_test'):
371         dirs = [path.join(template_dir, s, t)
372                 for s in ['pass']
373                 for t in listdir(path.join(template_dir, s))
374                 if path.isdir(path.join(template_dir, s, t))]
375
376         dirs += [pytest.mark.xfail(path.join(template_dir, s, t))
377                  for s in ['fail']
378                  for t in listdir(path.join(template_dir, s))
379                  if path.isdir(path.join(template_dir, s, t))]
380     else:
381         dirs = [template_dir]
382
383     metafunc.parametrize('template_dir', dirs)
384
385
386 def parametrize_environment_pair(metafunc, template_type=''):
387     '''
388     Define a list of pairs of parsed yaml from the heat templates and
389     environment files
390     '''
391     pairs = []
392     if metafunc.config.getoption('self_test'):
393         sub_dirs = ['pass', 'fail']
394         env_files = list_template_dir(metafunc, ['.env'], True,
395                                       template_type, sub_dirs)
396         yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'], True,
397                                        template_type, sub_dirs)
398     else:
399         env_files = list_template_dir(metafunc, ['.env'], True,
400                                       template_type)
401         yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'],
402                                        True, template_type)
403
404     for filename in env_files:
405         basename = path.splitext(filename)[0]
406         if basename + '.yml' in yaml_files:
407             yfilename = basename + '.yml'
408         else:
409             yfilename = basename + '.yaml'
410
411         try:
412             with open(filename) as fh:
413                 eyml = yaml.load(fh)
414             with open(yfilename) as fh:
415                 yyml = yaml.load(fh)
416
417             if 'fail' in filename:
418                 pairs.append(pytest.mark.xfail({"name": basename,
419                                                 "yyml": yyml,
420                                                 "eyml": eyml},
421                              strict=True))
422             else:
423                 pairs.append({"name": basename, "yyml": yyml, "eyml": eyml})
424
425         except yaml.YAMLError as e:
426             print(e)  # pylint: disable=superfluous-parens
427
428     metafunc.parametrize('environment_pair', pairs)
429
430
431 def parametrize_heat_volume_pair(metafunc):
432     '''
433     Define a list of pairs of parsed yaml from the a heat and volume
434     template
435     '''
436     pairs = []
437     if metafunc.config.getoption('self_test'):
438         sub_dirs = ['pass', 'fail']
439         volume_files = list_template_dir(metafunc, ['.yaml', '.yml'],
440                                          True, 'volume', sub_dirs)
441         yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'],
442                                        True, '', sub_dirs)
443     else:
444         volume_files = list_template_dir(metafunc, ['.yaml', '.yml'],
445                                          True, 'volume')
446         yaml_files = list_template_dir(metafunc, ['.yaml', '.yml'], True)
447
448     pattern = re.compile(r'\_volume$')
449     for vfilename in volume_files:
450         basename = pattern.sub('', path.splitext(vfilename)[0])
451         if basename + '.yml' in yaml_files:
452             yfilename = basename + '.yml'
453         else:
454             yfilename = basename + '.yaml'
455
456         try:
457             with open(vfilename) as fh:
458                 vyml = yaml.load(fh)
459             with open(yfilename) as fh:
460                 yyml = yaml.load(fh)
461
462             if 'fail' in vfilename:
463                 pairs.append(pytest.mark.xfail({"name": basename,
464                                                 "yyml": yyml,
465                                                 "vyml": vyml},
466                              strict=True))
467             else:
468                 pairs.append({"name": basename, "yyml": yyml, "vyml": vyml})
469
470         except yaml.YAMLError as e:
471             print(e)  # pylint: disable=superfluous-parens
472
473     metafunc.parametrize('heat_volume_pair', pairs)