Skip to content

Commit 8214bf2

Browse files
author
Petr Vesely
committed
[UR][CTS] Upstream CTS parser
1 parent 21aaf94 commit 8214bf2

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

scripts/ctest_parser.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/usr/bin/env python
2+
"""
3+
Copyright (C) 2022 Intel Corporation
4+
5+
Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
6+
See LICENSE.TXT
7+
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
"""
9+
10+
from sys import argv
11+
from subprocess import PIPE, Popen, STDOUT
12+
import argparse
13+
import os
14+
15+
16+
def run(command, env):
17+
process = Popen(command, env=env, stdout=PIPE,
18+
stderr=STDOUT, cwd=command[1])
19+
lines = process.communicate()[0].decode('utf-8').splitlines()
20+
results = {"Passed": {}, "Skipped": {}, "Failed": {}, 'Total': 0, 'Success': True}
21+
for line in lines:
22+
result_types = ['[ OK ]', '[ FAILED ]', '[ SKIPPED ]']
23+
if any([x in line for x in result_types]) and line.endswith("ms)"):
24+
name, time = line[line.find(']') + 2:].split(' ', maxsplit=1)
25+
if 'OK' in line:
26+
results['Passed'][name] = {'time': time}
27+
elif 'SKIPPED' in line:
28+
results['Skipped'][name] = {'time': time}
29+
elif 'FAILED' in line:
30+
results['Failed'][name] = {'time': time}
31+
elif '[==========] Running' in line:
32+
# This is the start of a new test suite, get the number of tests in
33+
# the first line e.g: '[==========] Running 29 tests from 9 test suites.'
34+
total = line[line.find('g') + 2:line.find('t') - 1]
35+
results['Total'] += int(total)
36+
37+
if process.returncode != 0:
38+
results['Success'] = False
39+
40+
return results
41+
42+
43+
def print_results(results, result_type):
44+
print('[CTest Parser] {} tests: '.format(result_type))
45+
print("\n".join("\t{}\t{}".format(k, v['time'])
46+
for k, v in results.items()))
47+
48+
49+
def print_summary(total, total_passed, total_failed, total_skipped, total_crashed):
50+
pass_rate_incl_skipped = str(round((total_passed / total) * 100, 2))
51+
total_excl_skipped = total - total_skipped
52+
pass_rate_excl_skipped = str(
53+
round((total_passed / total_excl_skipped) * 100, 2))
54+
55+
skipped_rate = str(round((total_skipped / total) * 100, 2))
56+
failed_rate = str(round((total_failed / total) * 100, 2))
57+
crashed_rate = str(round((total_crashed / total) * 100, 2))
58+
59+
print('[CTest Parser] Results:')
60+
print('\tTotal\t[{}]'. format(total))
61+
print('\tPassed\t[{}]\t({}%) - ({}% with skipped tests excluded)'.format(
62+
total_passed, pass_rate_incl_skipped, pass_rate_excl_skipped))
63+
print('\tSkipped\t[{}]\t({}%)'.format(total_skipped, skipped_rate))
64+
print('\tFailed\t[{}]\t({}%)'.format(total_failed, failed_rate))
65+
print('\tCrashed\t[{}]\t({}%)'.format(total_crashed, crashed_rate))
66+
67+
68+
def dir_path(string):
69+
if os.path.isdir(string):
70+
return string
71+
else:
72+
raise NotADirectoryError(string)
73+
74+
75+
def main():
76+
parser = argparse.ArgumentParser(
77+
description='CTest Result Parser. Parses output from CTest and '
78+
'summarises test results. -VV argument is always passed to '
79+
'CTest capture full output.')
80+
81+
parser.add_argument('ctest_path', type=dir_path, nargs='?', default='.',
82+
help='Optional path to test directory containing '
83+
'CTestTestfile. Defaults to current directory.')
84+
parser.add_argument('-q', '--quiet', action='store_true',
85+
help='Output only failed tests.')
86+
87+
args = parser.parse_args()
88+
89+
path = args.ctest_path
90+
command = ['ctest', path, '-VV']
91+
92+
env = os.environ.copy()
93+
env['GTEST_COLOR'] = 'no'
94+
env['CTEST_OUTPUT_ON_FAILURE'] = '0'
95+
env['GTEST_BRIEF'] = '0'
96+
env['GTEST_PRINT_TIME'] = '1'
97+
env['GTEST_PRINT_UTF8'] = '1'
98+
99+
results = run(command, env)
100+
101+
total = results['Total']
102+
total_passed = len(results['Passed'])
103+
total_skipped = len(results['Skipped'])
104+
total_failed = len(results['Failed'])
105+
total_crashed = total - (total_passed + total_skipped + total_failed)
106+
107+
if total > 0:
108+
print("[CTest Parser] Preparing results...")
109+
if args.quiet == False:
110+
if total_passed > 0:
111+
print_results(results['Passed'], 'Passed')
112+
if total_skipped > 0:
113+
print_results(results['Skipped'], 'Skipped')
114+
if total_failed > 0:
115+
print_results(results['Failed'], 'Failed')
116+
117+
print_summary(total, total_passed, total_failed,
118+
total_skipped, total_crashed)
119+
if results['Success'] == False:
120+
exit(1)
121+
else:
122+
print("[CTest Parser] Error: no tests were run")
123+
124+
125+
if __name__ == '__main__':
126+
try:
127+
main()
128+
except KeyboardInterrupt:
129+
exit(130)

0 commit comments

Comments
 (0)