[RECV-94] Separate docker/robot invoking
[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
34 def run_testcase(testcase):
35     """Runs a single testcase
36     """
37     name = testcase.get('name')
38     skip = testcase.get('skip', "False")
39     if skip.lower() == "true":
40         # skip is mentioned and true.
41         print('Skipping {}'.format(name))
42         return
43     show_stopper = testcase.get('show_stopper', "False")
44     what = testcase.get('what')
45     mypath = Path(__file__).absolute()
46     results_path = mypath.parents[2].joinpath(
47         "results/"+testcase.get('layer')+"/"+what)
48     test_path = mypath.parents[1].joinpath(
49         "tests/"+testcase.get('layer')+"/"+what)
50
51     # add to the variables file the path to where to sotre the logs
52     variables_file = mypath.parents[1].joinpath("tests/variables.yaml")
53     variables_dict = yaml.safe_load(variables_file.open())
54     variables_dict['log_path'] = str(results_path)
55     variables_file.write_text(str(variables_dict))
56
57     # run the test
58     args = ["robot", "-V", str(variables_file), "-d",
59             str(results_path), str(test_path)]
60
61     print('Executing testcase {}'.format(name))
62     print('show_stopper {}'.format(show_stopper))
63     print('Invoking {}'.format(args))
64     try:
65         status = subprocess.call(args, shell=False)
66         if status != 0 and show_stopper.lower() == "true":
67             raise ShowStopperError(name)
68     except OSError:
69         #print('Error while executing {}'.format(args))
70         raise BluvalError(OSError)
71
72
73 def validate_layer(blueprint, layer):
74     """validates a layer by validating all testcases under that layer
75     """
76     print('## Layer {}'.format(layer))
77     for testcase in blueprint[layer]:
78         testcase['layer'] = layer
79         run_testcase(testcase)
80
81
82 def validate_blueprint(yaml_loc, layer):
83     """Parse yaml file and validates given layer. If no layer given all layers
84     validated
85     """
86     with open(str(yaml_loc)) as yaml_file:
87         yamldoc = yaml.safe_load(yaml_file)
88     blueprint = yamldoc['blueprint']
89     validate_layer(blueprint, layer)
90
91
92 @click.command()
93 @click.argument('blueprint')
94 @click.option('--layer', '-l')
95 def main(blueprint, layer):
96     """Takes blueprint name and optional layer. Validates inputs and derives
97     yaml location from blueprint name. Invokes validate on blue print.
98     """
99     mypath = Path(__file__).absolute()
100     yaml_loc = mypath.parents[0].joinpath('bluval-{}.yaml'.format(blueprint))
101     if layer is not None:
102         layer = layer.lower()
103     try:
104         validate_blueprint(yaml_loc, layer)
105     except ShowStopperError as err:
106         print('ShowStopperError:', err)
107     except BluvalError as err:
108         print('Unexpected BluvalError', err)
109         raise
110     except:
111         print("Exception in user code:")
112         print("-"*60)
113         traceback.print_exc(file=sys.stdout)
114         print("-"*60)
115         raise
116
117
118 if __name__ == "__main__":
119     # pylint: disable=no-value-for-parameter
120     main()