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