3 # Copyright (c) 2016 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 """Script parses the data taken by robot framework (output.xml) and dumps
17 intereted values into JSON output file."""
23 from robot.api import ExecutionResult, ResultVisitor
26 class ExecutionTestChecker(ResultVisitor):
27 """Iterates through test cases."""
29 def __init__(self, vDeviceVersion):
30 self.vDeviceVersion = vDeviceVersion
33 def visit_test(self, test):
34 """Overloaded function. Called when test is found to process data.
36 :param test: Test to process.
37 :type test: ExecutionTestChecker
40 test_id = test.longname
41 test_status = 'Failed'
48 if any("PERFTEST" in tag for tag in test.tags):
49 if test.status == 'PASS':
50 test_status = 'Passed'
51 if any("PERFTEST_LONG" in tag for tag in test.tags):
52 throughput = test.message.split(' ')[1]
53 throughput_units = test.message.split(' ')[2]
54 elif any("PERFTEST_SHORT" in tag for tag in test.tags):
55 for keyword in test.keywords:
56 for assign in keyword.assign:
57 if assign == '${rate}':
58 temp = re.findall(r"(\d*\.\d+|\d+)([A-Za-z]*)",
60 throughput = temp[0][0]
61 throughput_units = temp[0][1]
63 for keyword in test.keywords:
64 for assign in keyword.assign:
65 if assign == '${framesize}':
66 framesize = keyword.args[0]
67 if 'worker threads' in keyword.name:
68 workers = keyword.name.split('\'')[1]
69 workers_per_nic = keyword.name.split('\'')[3]
71 self.out.append({'testCase': {
73 'testStatus': test_status,
74 'workerThreads': workers,
75 'workerThreadsPerNic': workers_per_nic,
76 'testTags': [tag for tag in test.tags],
77 'l2FrameSize': {'value': framesize,
79 'throughput': {'value': throughput,
80 'units': throughput_units},
81 'vDevice': {'version': self.vDeviceVersion}}})
84 def parse_tests(xml_file, vDeviceVersion):
85 """Parser result of robot output file and return.
87 :param xml_file: Output.xml from robot run.
88 :param vDeviceVersion: vDevice version.
90 :type vDeviceVersion: str
92 :return: JSON formatted output.
96 result = ExecutionResult(xml_file)
97 checker = ExecutionTestChecker(vDeviceVersion)
104 """Print help on stdout."""
106 print "args: [-h] -i <input_log_file> -o <output_json_file>" + \
110 def print_error(msg):
111 """Print error message on stderr.
113 :param msg: Error message to print.
118 sys.stderr.write(msg+'\n')
129 opts, _ = getopt.getopt(argv, "hi:o:v:", ["help"])
130 except getopt.GetoptError:
134 for opt, arg in opts:
135 if opt in ('-h', "--help"):
145 if _log_file is None or _json_file is None or _vpp is None:
150 with open(_log_file, 'r') as input_file:
151 with open(_json_file, 'w') as output_file:
152 out = parse_tests(input_file, _vpp)
153 json.dump(out, fp=output_file, sort_keys=True,
154 indent=4, separators=(',', ': '))
155 except IOError as ex_error:
156 print_error(str(ex_error))
160 if __name__ == "__main__":