1#!/usr/bin/env python 2from __future__ import print_function 3import glob, os, re 4import optparse 5import inspect 6 7""" 8Quick script for parsing the output of the test system and summarizing the results. 9""" 10 11def inInstallDir(): 12 """ 13 When petsc is installed then this file in installed in: 14 <PREFIX>/share/petsc/examples/config/gmakegentest.py 15 otherwise the path is: 16 <PETSC_DIR>/config/gmakegentest.py 17 We use this difference to determine if we are in installdir 18 """ 19 thisscriptdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 20 dirlist=thisscriptdir.split(os.path.sep) 21 if len(dirlist)>4: 22 lastfour=os.path.sep.join(dirlist[len(dirlist)-4:]) 23 if lastfour==os.path.join('share','petsc','examples','config'): 24 return True 25 else: 26 return False 27 else: 28 return False 29 30def summarize_results(directory,make,ntime): 31 ''' Loop over all of the results files and summarize the results''' 32 startdir=os.path.realpath(os.path.curdir) 33 try: 34 os.chdir(directory) 35 except OSError: 36 print('# No tests run') 37 return 38 summary={'total':0,'success':0,'failed':0,'failures':[],'todo':0,'skip':0, 39 'time':0} 40 timesummary={} 41 timelist=[] 42 for cfile in glob.glob('*.counts'): 43 with open(cfile, 'r') as f: 44 for line in f: 45 l = line.split() 46 summary[l[0]] += l[1:] if l[0] == 'failures' else int(l[1]) 47 if l[0] == 'time' and int(l[1])>0: 48 timesummary[cfile]=int(l[1]) 49 timelist.append(int(l[1])) 50 51 failstr=' '.join(summary['failures']) 52 print("\n# -------------") 53 print("# Summary ") 54 print("# -------------") 55 if failstr.strip(): print("# FAILED " + failstr) 56 57 for t in "success failed todo skip".split(): 58 percent=summary[t]/float(summary['total'])*100 59 print("# %s %d/%d tests (%3.1f%%)" % (t, summary[t], summary['total'], percent)) 60 print("#\n# Approximate time (not incl. build time): %s sec"% summary['time']) 61 62 if failstr.strip(): 63 fail_targets=( 64 re.sub('(?<=[0-9]_\w)_.*','', 65 re.sub('_1 ',' ', 66 re.sub('cmd-','', 67 re.sub('diff-','',failstr+' ')))) 68 ) 69 # Need to make sure we have a unique list 70 fail_targets=' '.join(list(set(fail_targets.split()))) 71 72 #Make the message nice 73 makefile="gmakefile.test" if inInstallDir() else "gmakefile" 74 75 print("#\n# To rerun failed tests: ") 76 print("# "+make+" -f "+makefile+" test search='" + fail_targets.strip()+"'") 77 78 if ntime>0: 79 print("# Timing summary: ") 80 timelist=list(set(timelist)) 81 timelist.sort(reverse=True) 82 nlim=(ntime if ntime<len(timelist) else len(timelist)) 83 # Do a double loop to sort in order 84 for timelimit in timelist[0:nlim]: 85 for cf in timesummary: 86 if timesummary[cf] == timelimit: 87 print("# %s: %d sec" % (re.sub('.counts','',cf), timesummary[cf])) 88 89 return 90 91def main(): 92 parser = optparse.OptionParser(usage="%prog [options]") 93 parser.add_option('-d', '--directory', dest='directory', 94 help='Directory containing results of petsc test system', 95 default=os.path.join(os.environ.get('PETSC_ARCH',''), 96 'tests','counts')) 97 parser.add_option('-m', '--make', dest='make', 98 help='make executable to report in summary', 99 default='make') 100 parser.add_option('-t', '--time', dest='time', 101 help='-t n: Report on the n number expensive jobs', 102 default=0) 103 options, args = parser.parse_args() 104 105 # Process arguments 106 if len(args) > 0: 107 parser.print_usage() 108 return 109 110 summarize_results(options.directory,options.make,int(options.time)) 111 112if __name__ == "__main__": 113 main() 114