Add a new variable Robot loglevel
[validation.git] / bluval / bluval.py
1 #!/usr/bin/python3
2 ##############################################################################
3 # Copyright (c) 2019 AT&T Intellectual Property.                             #
4 # Copyright (c) 2019 Nokia.                                                  #
5 #                                                                            #
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7 # not use this file except in compliance with the License.                   #
8 #                                                                            #
9 # You may obtain a copy of the License at                                    #
10 #       http://www.apache.org/licenses/LICENSE-2.0                           #
11 #                                                                            #
12 # Unless required by applicable law or agreed to in writing, software        #
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  #
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.           #
15 # See the License for the specific language governing permissions and        #
16 # limitations under the License.                                             #
17 ##############################################################################
18 """This module parses yaml file, reads layers, testcases and executes each
19 testcase
20 """
21
22 import subprocess
23 import sys
24 import traceback
25 from pathlib import Path
26
27 import click
28 import yaml
29
30 from bluutil import BluvalError
31 from bluutil import ShowStopperError
32
33 _OPTIONAL_ALSO = False
34
35 def run_testcase(testcase):
36     """Runs a single testcase
37     """
38     name = testcase.get('name')
39     skip = testcase.get('skip', "False")
40     optional = testcase.get('optional', "False")
41     if skip.lower() == "true":
42         # skip is mentioned and true.
43         print('Skipping {}'.format(name))
44         return
45     print("_OPTIONAL_ALSO {}".format(_OPTIONAL_ALSO))
46     if  not _OPTIONAL_ALSO and optional.lower() == "true":
47         # Optional Test case.
48         print('Ignoring Optional {} testcase'.format(name))
49         return
50     show_stopper = testcase.get('show_stopper', "False")
51     what = testcase.get('what')
52     mypath = Path(__file__).absolute()
53     results_path = mypath.parents[2].joinpath(
54         "results/"+testcase.get('layer')+"/"+what)
55     test_path = mypath.parents[1].joinpath(
56         "tests/"+testcase.get('layer')+"/"+what)
57
58     # add to the variables file the path to where to sotre the logs
59     variables_file = mypath.parents[1].joinpath("tests/variables.yaml")
60     variables_dict = yaml.safe_load(variables_file.open())
61     variables_dict['log_path'] = str(results_path)
62     variables_updated_file = mypath.parents[1].joinpath("tests/variables_updated.yaml")
63     variables_updated_file.write_text(str(variables_dict))
64     variables_loglevel = variables_dict['loglevel']
65
66     # run the test
67     args = ["robot", "-V", str(variables_updated_file),
68             "-d", str(results_path),
69             "-n", "non-critical",
70             "-b", "debug.log",
71             "-L", str(variables_loglevel),
72             str(test_path)]
73
74     print('Executing testcase {}'.format(name))
75     print('show_stopper {}'.format(show_stopper))
76     print('Invoking {}'.format(args), flush=True)
77     try:
78         status = subprocess.call(args, shell=False)
79         if status != 0 and show_stopper.lower() == "true":
80             raise ShowStopperError(name)
81     except OSError:
82         #print('Error while executing {}'.format(args))
83         raise BluvalError(OSError)
84
85
86 def validate_layer(blueprint, layer):
87     """validates a layer by validating all testcases under that layer
88     """
89     print('## Layer {}'.format(layer))
90     for testcase in blueprint[layer]:
91         testcase['layer'] = layer
92         run_testcase(testcase)
93
94
95 def validate_blueprint(yaml_loc, layer):
96     """Parse yaml file and validates given layer. If no layer given all layers
97     validated
98     """
99     with open(str(yaml_loc)) as yaml_file:
100         yamldoc = yaml.safe_load(yaml_file)
101     blueprint = yamldoc['blueprint']
102     validate_layer(blueprint, layer)
103
104
105 def write_test_info(layer):
106     """writes testing info to test_info.yaml
107     """
108     data = dict(
109         test_info=dict(
110             layer=layer,
111             optional=_OPTIONAL_ALSO,
112         )
113     )
114
115     with open('/opt/akraino/results/test_info.yaml', 'w') as outfile:
116         yaml.dump(data, outfile, default_flow_style=False)
117
118
119 @click.command()
120 @click.argument('blueprint')
121 @click.option('--layer', '-l')
122 @click.option('--optional_also', '-o', is_flag=True)
123 def main(blueprint, layer, optional_also):
124     """Takes blueprint name and optional layer. Validates inputs and derives
125     yaml location from blueprint name. Invokes validate on blue print.
126     """
127     global _OPTIONAL_ALSO  # pylint: disable=global-statement
128     mypath = Path(__file__).absolute()
129     yaml_loc = mypath.parents[0].joinpath('bluval-{}.yaml'.format(blueprint))
130     if layer is not None:
131         layer = layer.lower()
132     if optional_also:
133         _OPTIONAL_ALSO = True
134         print("_OPTIONAL_ALSO {}".format(_OPTIONAL_ALSO))
135
136     try:
137         write_test_info(layer)
138         validate_blueprint(yaml_loc, layer)
139     except ShowStopperError as err:
140         print('ShowStopperError:', err)
141     except BluvalError as err:
142         print('Unexpected BluvalError', err)
143         raise
144     except:
145         print("Exception in user code:")
146         print("-"*60)
147         traceback.print_exc(file=sys.stdout)
148         print("-"*60)
149         raise
150
151
152 if __name__ == "__main__":
153     # pylint: disable=no-value-for-parameter
154     main()