blob: eed3435aa22c876635c2325c371837e168d249b7 [file] [log] [blame]
Ian Zernydcb172e2022-02-22 15:36:45 +01001#!/usr/bin/env python3
Tamas Kenez507481b2017-06-06 15:01:33 +02002# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
6# Compare multiple CTS test_result.xml files
7
8from __future__ import print_function
9from os.path import basename
10import argparse
11import os
Tamas Kenez507481b2017-06-06 15:01:33 +020012import sys
13
Tamas Kenez82efeb52017-06-12 13:56:22 +020014import utils
15
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020016
Tamas Kenez507481b2017-06-06 15:01:33 +020017class Module:
Tamas Kenez507481b2017-06-06 15:01:33 +020018
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020019 def __init__(self):
20 self.test_cases = {}
21 self.bf_covered_in_file = 0 # bitfield, one bit per file
Tamas Kenez507481b2017-06-06 15:01:33 +020022
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020023 def get_test_case_maybe_create(self, test_case_name):
24 return self.test_cases.setdefault(test_case_name, TestCase())
Tamas Kenez507481b2017-06-06 15:01:33 +020025
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020026 def set_file_index_present(self, file_idx):
27 self.bf_covered_in_file |= (1 << file_idx)
28
29 def report(self, module_name, files, diff_only):
30 bf_all_files = self.bf_covered_in_file
31 for test_case_name, test_case in self.test_cases.iteritems():
32 if test_case.bf_covered_in_file != bf_all_files:
33 report_missing_thing('test_case',
34 module_name + '/' + test_case_name,
35 test_case.bf_covered_in_file, files)
36 for test_case_name, test_case in self.test_cases.iteritems():
37 test_case.report(module_name, test_case_name, files, diff_only)
38
Tamas Kenez507481b2017-06-06 15:01:33 +020039
40class TestCase:
Tamas Kenez507481b2017-06-06 15:01:33 +020041
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020042 def __init__(self):
43 self.tests = {}
44 self.bf_covered_in_file = 0 # bitfield, one bit per file
Tamas Kenez507481b2017-06-06 15:01:33 +020045
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020046 def get_test_maybe_create(self, test_name):
47 return self.tests.setdefault(test_name, Test())
Tamas Kenez507481b2017-06-06 15:01:33 +020048
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020049 def set_file_index_present(self, file_idx):
50 self.bf_covered_in_file |= (1 << file_idx)
51
52 def report(self, module_name, test_case_name, files, diff_only):
53 bf_all_files = self.bf_covered_in_file
54 for test_name, test in self.tests.iteritems():
55 do_report = test.bf_passing_in_file != bf_all_files
56 if diff_only:
57 do_report = do_report and test.bf_failing_in_file != bf_all_files
58 if do_report:
59 test.report(module_name, test_case_name, test_name, files)
60
Tamas Kenez507481b2017-06-06 15:01:33 +020061
62class Test:
Tamas Kenez507481b2017-06-06 15:01:33 +020063
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020064 def __init__(self):
65 self.bf_failing_in_file = 0 # bitfields, one bit per file
66 self.bf_passing_in_file = 0
Tamas Kenez507481b2017-06-06 15:01:33 +020067
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020068 def set_file_index_outcome(self, outcome_is_passed, file_idx):
69 bf_value = (1 << file_idx)
70 if outcome_is_passed:
71 self.bf_passing_in_file |= bf_value
72 else:
73 self.bf_failing_in_file |= bf_value
74
75 # Report test's status in all files: pass/fail/missing
76 def report(self, module_name, test_case_name, test_name, files):
77 print('Test: {}/{}/{}:'.format(module_name, test_case_name, test_name))
78 for file_idx, f in enumerate(files):
79 bf_value = 1 << file_idx
80 print('\t- {:20}'.format(basename(f)), end='')
81 if self.bf_passing_in_file & bf_value:
82 print('PASS')
83 elif self.bf_failing_in_file & bf_value:
84 print(' FAIL')
85 else:
86 print(' -- -- (missing)')
87
Tamas Kenez507481b2017-06-06 15:01:33 +020088
89def parse_arguments():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +020090 parser = argparse.ArgumentParser(
91 description='Compare multiple Android CTS test_result.xml files.')
92 parser.add_argument('files',
93 nargs='+',
94 help='List of (possibly renamed) test_result.xml files')
95 parser.add_argument(
96 '--diff-only',
97 action='store_true',
98 help="Don't list tests that consistently fail in all result files,"
99 " list only differences.")
100 return parser.parse_args()
101
Tamas Kenez507481b2017-06-06 15:01:33 +0200102
103# Read CTS test_result.xml from file and merge into result_tree
104def add_to_result_tree(result_tree, file_xml, file_idx):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200105 module = None
106 test_case = None
107 for x in utils.read_cts_test_result(file_xml):
108 if type(x) is utils.CtsModule:
109 module = result_tree.setdefault(x.name, Module())
110 module.set_file_index_present(file_idx)
111 elif type(x) is utils.CtsTestCase:
112 test_case = module.get_test_case_maybe_create(x.name)
113 test_case.set_file_index_present(file_idx)
114 else:
115 assert (type(x) is utils.CtsTest)
116 v = test_case.get_test_maybe_create(x.name)
117 v.set_file_index_outcome(x.outcome, file_idx)
118
Tamas Kenez507481b2017-06-06 15:01:33 +0200119
120# main tree_report function
121def tree_report(result_tree, files, diff_only):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200122 bf_all_files = (1 << len(files)) - 1
123 for module_name, module in result_tree.iteritems():
124 if module.bf_covered_in_file != bf_all_files:
125 report_missing_thing('module', module_name,
126 module.bf_covered_in_file, files)
127 for module_name, module in result_tree.iteritems():
128 module.report(module_name, files, diff_only)
129
Tamas Kenez507481b2017-06-06 15:01:33 +0200130
131def report_missing_thing(thing_type, thing_name, bf_covered_in_file, files):
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200132 print('Missing {}: {}, from:'.format(thing_type, thing_name))
133 for file_idx, f in enumerate(files):
134 if not (bf_covered_in_file & (1 << file_idx)):
135 print('\t- ' + f)
136
Tamas Kenez507481b2017-06-06 15:01:33 +0200137
138def Main():
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200139 m = Module()
140 m.get_test_case_maybe_create('qwe')
Tamas Kenez507481b2017-06-06 15:01:33 +0200141
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200142 args = parse_arguments()
Tamas Kenez507481b2017-06-06 15:01:33 +0200143
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200144 result_tree = {}
145 for file_idx, f in enumerate(args.files):
146 add_to_result_tree(result_tree, f, file_idx)
Tamas Kenez507481b2017-06-06 15:01:33 +0200147
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200148 tree_report(result_tree, args.files, args.diff_only)
Tamas Kenez507481b2017-06-06 15:01:33 +0200149
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200150 return 0
151
Tamas Kenez507481b2017-06-06 15:01:33 +0200152
153if __name__ == '__main__':
Christoffer Quist Adamsen2434a4d2023-10-16 11:29:03 +0200154 sys.exit(Main())