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,etime): 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 if l[0] == 'failures': 46 if len(l)>1: 47 summary[l[0]] += l[1:] 48 elif l[0] == 'time': 49 if len(l)==1: continue 50 summary[l[0]] += float(l[1]) 51 timesummary[cfile]=float(l[1]) 52 timelist.append(float(l[1])) 53 elif l[0] not in summary: 54 continue 55 else: 56 summary[l[0]] += int(l[1]) 57 58 failstr=' '.join(summary['failures']) 59 print("\n# -------------") 60 print("# Summary ") 61 print("# -------------") 62 if failstr.strip(): print("# FAILED " + failstr) 63 64 for t in "success failed todo skip".split(): 65 percent=summary[t]/float(summary['total'])*100 66 print("# %s %d/%d tests (%3.1f%%)" % (t, summary[t], summary['total'], percent)) 67 print("#") 68 if etime: 69 print("# Wall clock time for tests: %s sec"% etime) 70 print("# Approximate CPU time (not incl. build time): %s sec"% summary['time']) 71 72 if failstr.strip(): 73 fail_targets=( 74 re.sub('(?<=[0-9]_\w)_.*','', 75 re.sub('cmd-','', 76 re.sub('diff-','',failstr+' '))) 77 ) 78 # Strip off characters from subtests 79 fail_list=[] 80 for failure in fail_targets.split(): 81 if failure.count('-')>1: 82 fail_list.append('-'.join(name.split('-')[:-1])) 83 else: 84 fail_list.append(failure) 85 fail_list=list(set(fail_list)) 86 fail_targets=' '.join(fail_list) 87 88 #Make the message nice 89 makefile="gmakefile.test" if inInstallDir() else "gmakefile" 90 91 print("#\n# To rerun failed tests: ") 92 print("# "+make+" -f "+makefile+" test search='" + fail_targets.strip()+"'") 93 94 if ntime>0: 95 print("#\n# Timing summary: ") 96 timelist=list(set(timelist)) 97 timelist.sort(reverse=True) 98 nlim=(ntime if ntime<len(timelist) else len(timelist)) 99 # Do a double loop to sort in order 100 for timelimit in timelist[0:nlim]: 101 for cf in timesummary: 102 if timesummary[cf] == timelimit: 103 print("# %s: %.2f sec" % (re.sub('.counts','',cf), timesummary[cf])) 104 105 return 106 107def main(): 108 parser = optparse.OptionParser(usage="%prog [options]") 109 parser.add_option('-d', '--directory', dest='directory', 110 help='Directory containing results of petsc test system', 111 default=os.path.join(os.environ.get('PETSC_ARCH',''), 112 'tests','counts')) 113 parser.add_option('-e', '--elapsed_time', dest='elapsed_time', 114 help='Report elapsed time in output', 115 default=None) 116 parser.add_option('-m', '--make', dest='make', 117 help='make executable to report in summary', 118 default='make') 119 parser.add_option('-t', '--time', dest='time', 120 help='-t n: Report on the n number expensive jobs', 121 default=0) 122 options, args = parser.parse_args() 123 124 # Process arguments 125 if len(args) > 0: 126 parser.print_usage() 127 return 128 129 summarize_results(options.directory,options.make,int(options.time),options.elapsed_time) 130 131if __name__ == "__main__": 132 main() 133