blob: 00901ecb8f9880cb80ca5360315c4f32b8d16ea7 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# Compare multiple CTS test_result.xml files
from __future__ import print_function
from os.path import basename
import argparse
import os
import sys
import utils
class Module:
def __init__(self):
self.test_cases = {}
self.bf_covered_in_file = 0 # bitfield, one bit per file
def get_test_case_maybe_create(self, test_case_name):
return self.test_cases.setdefault(test_case_name, TestCase())
def set_file_index_present(self, file_idx):
self.bf_covered_in_file |= (1 << file_idx)
def report(self, module_name, files, diff_only):
bf_all_files = self.bf_covered_in_file
for test_case_name, test_case in self.test_cases.iteritems():
if test_case.bf_covered_in_file != bf_all_files:
report_missing_thing('test_case', module_name + '/' + test_case_name,
test_case.bf_covered_in_file, files)
for test_case_name, test_case in self.test_cases.iteritems():
test_case.report(module_name, test_case_name, files, diff_only)
class TestCase:
def __init__(self):
self.tests = {}
self.bf_covered_in_file = 0 # bitfield, one bit per file
def get_test_maybe_create(self, test_name):
return self.tests.setdefault(test_name, Test())
def set_file_index_present(self, file_idx):
self.bf_covered_in_file |= (1 << file_idx)
def report(self, module_name, test_case_name, files, diff_only):
bf_all_files = self.bf_covered_in_file
for test_name, test in self.tests.iteritems():
do_report = test.bf_passing_in_file != bf_all_files
if diff_only:
do_report = do_report and test.bf_failing_in_file != bf_all_files
if do_report:
test.report(module_name, test_case_name, test_name, files)
class Test:
def __init__(self):
self.bf_failing_in_file = 0 # bitfields, one bit per file
self.bf_passing_in_file = 0
def set_file_index_outcome(self, outcome_is_passed, file_idx):
bf_value = (1 << file_idx)
if outcome_is_passed:
self.bf_passing_in_file |= bf_value
else:
self.bf_failing_in_file |= bf_value
# Report test's status in all files: pass/fail/missing
def report(self, module_name, test_case_name, test_name, files):
print('Test: {}/{}/{}:'.format(module_name, test_case_name, test_name))
for file_idx, f in enumerate(files):
bf_value = 1 << file_idx
print('\t- {:20}'.format(basename(f)), end = '')
if self.bf_passing_in_file & bf_value:
print('PASS')
elif self.bf_failing_in_file & bf_value:
print(' FAIL')
else:
print(' -- -- (missing)')
def parse_arguments():
parser = argparse.ArgumentParser(
description = 'Compare multiple Android CTS test_result.xml files.')
parser.add_argument('files', nargs = '+',
help = 'List of (possibly renamed) test_result.xml files')
parser.add_argument('--diff-only',
action = 'store_true',
help = "Don't list tests that consistently fail in all result files,"
" list only differences.")
return parser.parse_args()
# Read CTS test_result.xml from file and merge into result_tree
def add_to_result_tree(result_tree, file_xml, file_idx):
module = None
test_case = None
for x in utils.read_cts_test_result(file_xml):
if type(x) is utils.CtsModule:
module = result_tree.setdefault(x.name, Module())
module.set_file_index_present(file_idx)
elif type(x) is utils.CtsTestCase:
test_case = module.get_test_case_maybe_create(x.name)
test_case.set_file_index_present(file_idx)
else:
assert(type(x) is utils.CtsTest)
v = test_case.get_test_maybe_create(x.name)
v.set_file_index_outcome(x.outcome, file_idx)
# main tree_report function
def tree_report(result_tree, files, diff_only):
bf_all_files = (1 << len(files)) - 1
for module_name, module in result_tree.iteritems():
if module.bf_covered_in_file != bf_all_files:
report_missing_thing('module', module_name, module.bf_covered_in_file,
files)
for module_name, module in result_tree.iteritems():
module.report(module_name, files, diff_only)
def report_missing_thing(thing_type, thing_name, bf_covered_in_file, files):
print('Missing {}: {}, from:'.format(thing_type, thing_name))
for file_idx, f in enumerate(files):
if not (bf_covered_in_file & (1 << file_idx)):
print('\t- ' + f)
def Main():
m = Module()
m.get_test_case_maybe_create('qwe')
args = parse_arguments()
result_tree = {}
for file_idx, f in enumerate(args.files):
add_to_result_tree(result_tree, f, file_idx)
tree_report(result_tree, args.files, args.diff_only)
return 0
if __name__ == '__main__':
sys.exit(Main())