139 lines
4.8 KiB
Python
Executable file
139 lines
4.8 KiB
Python
Executable file
#!/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())
|