18ccd5183SScott Kruger#!/usr/bin/env python 291bc3e46SScott Krugerimport glob, os, re 38ccd5183SScott Krugerimport optparse 43054ff8cSScott Krugerimport inspect 53054ff8cSScott Kruger 68ccd5183SScott Kruger""" 78ccd5183SScott KrugerQuick script for parsing the output of the test system and summarizing the results. 88ccd5183SScott Kruger""" 98ccd5183SScott Kruger 103054ff8cSScott Krugerdef inInstallDir(): 113054ff8cSScott Kruger """ 123054ff8cSScott Kruger When petsc is installed then this file in installed in: 133054ff8cSScott Kruger <PREFIX>/share/petsc/examples/config/gmakegentest.py 143054ff8cSScott Kruger otherwise the path is: 153054ff8cSScott Kruger <PETSC_DIR>/config/gmakegentest.py 163054ff8cSScott Kruger We use this difference to determine if we are in installdir 173054ff8cSScott Kruger """ 183054ff8cSScott Kruger thisscriptdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 193054ff8cSScott Kruger dirlist=thisscriptdir.split(os.path.sep) 203054ff8cSScott Kruger if len(dirlist)>4: 213054ff8cSScott Kruger lastfour=os.path.sep.join(dirlist[len(dirlist)-4:]) 223054ff8cSScott Kruger if lastfour==os.path.join('share','petsc','examples','config'): 233054ff8cSScott Kruger return True 243054ff8cSScott Kruger else: 253054ff8cSScott Kruger return False 263054ff8cSScott Kruger else: 273054ff8cSScott Kruger return False 283054ff8cSScott Kruger 2932f4009dSScott Krugerdef summarize_results(directory,make,ntime,etime): 308ccd5183SScott Kruger ''' Loop over all of the results files and summarize the results''' 318ccd5183SScott Kruger startdir=os.path.realpath(os.path.curdir) 326d7e7da8SJed Brown try: 338ccd5183SScott Kruger os.chdir(directory) 346d7e7da8SJed Brown except OSError: 356d7e7da8SJed Brown print('# No tests run') 366d7e7da8SJed Brown return 37bbf1c217SScott Kruger summary={'total':0,'success':0,'failed':0,'failures':[],'todo':0,'skip':0, 38bbf1c217SScott Kruger 'time':0} 39bbf1c217SScott Kruger timesummary={} 40bbf1c217SScott Kruger timelist=[] 418ccd5183SScott Kruger for cfile in glob.glob('*.counts'): 42100ef3c7SJed Brown with open(cfile, 'r') as f: 43100ef3c7SJed Brown for line in f: 44100ef3c7SJed Brown l = line.split() 45521be42fSScott Kruger if l[0] == 'failures': 46*d8e31410SScott Kruger if len(l)>1: 470bffd254SScott Kruger summary[l[0]] += l[1:] 48521be42fSScott Kruger elif l[0] == 'time': 49521be42fSScott Kruger if len(l)==1: continue 50521be42fSScott Kruger summary[l[0]] += float(l[1]) 51521be42fSScott Kruger timesummary[cfile]=float(l[1]) 52521be42fSScott Kruger timelist.append(float(l[1])) 53*d8e31410SScott Kruger elif l[0] not in summary: 54*d8e31410SScott Kruger continue 55521be42fSScott Kruger else: 56521be42fSScott Kruger summary[l[0]] += int(l[1]) 57a2766241SScott Kruger 5891bc3e46SScott Kruger failstr=' '.join(summary['failures']) 59100ef3c7SJed Brown print("\n# -------------") 60100ef3c7SJed Brown print("# Summary ") 61100ef3c7SJed Brown print("# -------------") 621a3f486dSScott Kruger if failstr.strip(): print("# FAILED " + failstr) 638ccd5183SScott Kruger 648ccd5183SScott Kruger for t in "success failed todo skip".split(): 658ccd5183SScott Kruger percent=summary[t]/float(summary['total'])*100 66100ef3c7SJed Brown print("# %s %d/%d tests (%3.1f%%)" % (t, summary[t], summary['total'], percent)) 6732f4009dSScott Kruger print("#") 6832f4009dSScott Kruger if etime: 6932f4009dSScott Kruger print("# Wall clock time for tests: %s sec"% etime) 7032f4009dSScott Kruger print("# Approximate CPU time (not incl. build time): %s sec"% summary['time']) 7191bc3e46SScott Kruger 72c687a870SSatish Balay if failstr.strip(): 7391bc3e46SScott Kruger fail_targets=( 7491bc3e46SScott Kruger re.sub('(?<=[0-9]_\w)_.*','', 7591bc3e46SScott Kruger re.sub('cmd-','', 76521be42fSScott Kruger re.sub('diff-','',failstr+' '))) 7791bc3e46SScott Kruger ) 78*d8e31410SScott Kruger # Strip off characters from subtests 79*d8e31410SScott Kruger fail_list=[] 80*d8e31410SScott Kruger for failure in fail_targets.split(): 81*d8e31410SScott Kruger if failure.count('-')>1: 82*d8e31410SScott Kruger fail_list.append('-'.join(name.split('-')[:-1])) 83*d8e31410SScott Kruger else: 84*d8e31410SScott Kruger fail_list.append(failure) 85*d8e31410SScott Kruger fail_list=list(set(fail_list)) 86*d8e31410SScott Kruger fail_targets=' '.join(fail_list) 873054ff8cSScott Kruger 883054ff8cSScott Kruger #Make the message nice 893054ff8cSScott Kruger makefile="gmakefile.test" if inInstallDir() else "gmakefile" 903054ff8cSScott Kruger 9191bc3e46SScott Kruger print("#\n# To rerun failed tests: ") 923054ff8cSScott Kruger print("# "+make+" -f "+makefile+" test search='" + fail_targets.strip()+"'") 93bbf1c217SScott Kruger 94bbf1c217SScott Kruger if ntime>0: 95*d8e31410SScott Kruger print("#\n# Timing summary: ") 96bbf1c217SScott Kruger timelist=list(set(timelist)) 97bbf1c217SScott Kruger timelist.sort(reverse=True) 98bbf1c217SScott Kruger nlim=(ntime if ntime<len(timelist) else len(timelist)) 99bbf1c217SScott Kruger # Do a double loop to sort in order 100bbf1c217SScott Kruger for timelimit in timelist[0:nlim]: 101bbf1c217SScott Kruger for cf in timesummary: 102bbf1c217SScott Kruger if timesummary[cf] == timelimit: 103521be42fSScott Kruger print("# %s: %.2f sec" % (re.sub('.counts','',cf), timesummary[cf])) 104bbf1c217SScott Kruger 1058ccd5183SScott Kruger return 1068ccd5183SScott Kruger 1078ccd5183SScott Krugerdef main(): 1088ccd5183SScott Kruger parser = optparse.OptionParser(usage="%prog [options]") 1098ccd5183SScott Kruger parser.add_option('-d', '--directory', dest='directory', 1108ccd5183SScott Kruger help='Directory containing results of petsc test system', 111e57812dcSJed Brown default=os.path.join(os.environ.get('PETSC_ARCH',''), 112bbf1c217SScott Kruger 'tests','counts')) 11332f4009dSScott Kruger parser.add_option('-e', '--elapsed_time', dest='elapsed_time', 11432f4009dSScott Kruger help='Report elapsed time in output', 11532f4009dSScott Kruger default=None) 1163054ff8cSScott Kruger parser.add_option('-m', '--make', dest='make', 1173054ff8cSScott Kruger help='make executable to report in summary', 1183054ff8cSScott Kruger default='make') 119bbf1c217SScott Kruger parser.add_option('-t', '--time', dest='time', 120bbf1c217SScott Kruger help='-t n: Report on the n number expensive jobs', 121bbf1c217SScott Kruger default=0) 1228ccd5183SScott Kruger options, args = parser.parse_args() 1238ccd5183SScott Kruger 1248ccd5183SScott Kruger # Process arguments 1258ccd5183SScott Kruger if len(args) > 0: 1268ccd5183SScott Kruger parser.print_usage() 1278ccd5183SScott Kruger return 1288ccd5183SScott Kruger 12932f4009dSScott Kruger summarize_results(options.directory,options.make,int(options.time),options.elapsed_time) 1308ccd5183SScott Kruger 1318ccd5183SScott Krugerif __name__ == "__main__": 1328ccd5183SScott Kruger main() 133