#!/usr/bin/env python from __future__ import print_function import sys import os import re import collections debug = False class Arch: def __init__(self, arch): arch = re.sub("^rv(32|64|128)g", 'rv\\1imafd', arch) m = re.match('rv(32|64|128)', arch) self.base_arch = m.group(0) self.ext = [] i = len(self.base_arch) while i < len(arch): ext = arch[i] if ext in ['x', 's', 'z']: extlen = 1 while (i+extlen) < len(arch) and arch[i+extlen] != '_': extlen += 1 self.ext.append(arch[i:i + extlen]) i += extlen elif ext == '_': i += 1 else: self.ext.append(ext) i += 1 def usage(): print("%s " \ " " % sys.argv[0]) def get_white_list_files(raw_arch, abi, libc, white_list_base_dir): """ Return white file list according the arch, abi, libc name and component. """ white_list_files = [] arch = Arch(raw_arch) def append_if_exist(filename): if debug: print ("Try append: %s" % filename) filepath = os.path.join(white_list_base_dir, filename) if os.path.exists(filepath): if debug: print ("Got: %s" % filename) white_list_files.append(filepath) libc_filename = "common.log" append_if_exist(libc_filename) libc_filename = "%s.log" % (libc) append_if_exist(libc_filename) filename = "%s.log" % (arch.base_arch) append_if_exist(filename) filename = "%s.log" % (abi) append_if_exist(filename) filename = "%s.%s.log" % (arch.base_arch, abi) append_if_exist(filename) filename = "%s.%s.log" % (libc, arch.base_arch) append_if_exist(filename) filename = "%s.%s.log" % (libc, abi) append_if_exist(filename) filename = "%s.%s.%s.log" % (libc, arch.base_arch, abi) append_if_exist(filename) for ext in arch.ext: filename = "%s.log" % (ext) append_if_exist(filename) filename = "%s.%s.log" % (arch.base_arch, ext) append_if_exist(filename) filename = "%s.%s.log" % (ext, abi) append_if_exist(filename) filename = "%s.%s.%s.log" % (arch.base_arch, ext, abi) append_if_exist(filename) filename = "%s.%s.log" % (libc, ext) append_if_exist(filename) filename = "%s.%s.%s.log" % (libc, arch.base_arch, ext) append_if_exist(filename) filename = "%s.%s.%s.log" % (libc, ext, abi) append_if_exist(filename) filename = "%s.%s.%s.%s.log" % (libc, arch.base_arch, ext, abi) append_if_exist(filename) return white_list_files def read_white_lists(white_list_files, is_gcc): if is_gcc: white_lists = dict() else: white_lists = set() for fname in white_list_files: with open(fname) as f: content = f.readlines() for l in content: l = l.strip() if len(l) == 0: continue if l[0] == '#': continue if is_gcc: try: key = l.split(' ')[1] except: print ("Corrupt allowlist file?") print ("Each line must contail : .*") print ("e.g. FAIL: g++.dg/pr83239.C") print ("Or starts with # for comment") if key not in white_lists: white_lists[key] = [] white_lists[key].append(l) else: white_lists.add(l) return white_lists def read_sum(sum_files): unexpected_results = dict() for sum_file in sum_files: with open(sum_file) as f: content = f.readlines() current_target = None variations = [] scan_variations = False unexpected_result = dict() tool = os.path.basename(sum_file).split(".")[0] for l in content: if l.startswith("Schedule of variations"): scan_variations = True continue if scan_variations and l.startswith(" "): variations.append(l.strip()) continue scan_variations = False if l.startswith("Running target"): # Parsing current running target. current_target = l.split(" ")[-1].strip() unexpected_result[current_target] = list() elif l.startswith("FAIL") or l.startswith("XPASS") \ or l.startswith("ERROR"): unexpected_result[current_target].append(l.strip()) unexpected_results[tool] = unexpected_result # tool -> variation(target) -> list of unexpected result return unexpected_results def get_white_list(arch, abi, libc, white_list_base_dir, is_gcc): white_list_files = \ get_white_list_files(arch, abi, libc, white_list_base_dir) white_list = read_white_lists(white_list_files, is_gcc) return white_list def filter_result(tool, libc, white_list_base_dir, unexpected_results): summary = dict() any_fail = False is_gcc = tool == 'gcc' # Filter with white list. for testtool, variation_unexpected_result in unexpected_results.items(): for variation, unexpected_result in variation_unexpected_result.items(): # Extract variation to arch/abi arch = "" abi = "" cmodel = "" for info in variation.split('/'): if info.startswith('-march'): arch = info[7:] elif info.startswith('-mabi'): abi = info[6:] elif info.startswith('-mcmodel'): cmodel = info[9:] white_list = \ get_white_list(arch, abi, libc, os.path.join(white_list_base_dir, tool), is_gcc) # filter! config = (arch, abi, cmodel) fail_count = 0 unexpected_result_list = [] if is_gcc: case_count = set() for ur in unexpected_result: key = ur.split(' ')[1] if key in white_list and \ any(map(lambda x:ur.startswith(x), white_list[key])): # This item can be ignored continue else: unexpected_result_list.append(ur) fail_count += 1 case_count.add(key) any_fail = True if config not in summary: summary[config] = dict() summary[config][testtool] = (fail_count, len(case_count)) else: for ur in unexpected_result: if ur not in white_list: unexpected_result_list.append(ur) fail_count += 1 any_fail = True if config not in summary: summary[config] = dict() summary[config][testtool] = fail_count if len(unexpected_result_list) != 0: print ("\t\t=== %s: Unexpected fails for %s %s %s ===" \ % (testtool, arch, abi, cmodel)) for ur in unexpected_result_list: print (ur) # Generate summary report. if tool == 'gcc': toollist = ['gcc', 'g++', 'gfortran'] elif tool == 'binutils': toollist = ['binutils', 'ld', 'gas'] else: raise Exception("Unsupported tool `%s`" % tool) bar_item = map(lambda x: "%13s" % x, toollist) bar = " |".join(bar_item) print ("\n ========= Summary of %s testsuite =========" % tool) if is_gcc: print (" | # of unexpected case / # of unique unexpected case") else: print (" | # of unexpected case") print (" |%s |" % bar) for config, result in summary.items(): arch, abi, cmodel = config print (" %10s/ %6s/ %6s |" % (arch, abi, cmodel), end='') for tool in toollist: if tool not in summary[config]: print ("%7s |" % '-', end='') continue if is_gcc: fail_count, case_count = summary[config][tool] print ("%5d / %5d |" % (fail_count, case_count), end='') else: fail_count = summary[config][tool] print ("%13d |" % fail_count, end='') print ("") if any_fail: return 1 else: return 0 def main(): if len(sys.argv) < 5: usage() sys.exit() tool, libc, white_list_base_dir, sum_files = sys.argv[1:5] rv = 0 sum_files = sum_files.split(',') unexpected_results = read_sum(sum_files) if tool in ['gcc', 'binutils']: rv = filter_result(tool, libc, white_list_base_dir, unexpected_results) else: print ("Unsupported tool: `%s`" % tool) rv = 1 sys.exit(rv) if __name__ == '__main__': main()