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 29*bbf1c217SScott Krugerdef summarize_results(directory,make,ntime): 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 37*bbf1c217SScott Kruger summary={'total':0,'success':0,'failed':0,'failures':[],'todo':0,'skip':0, 38*bbf1c217SScott Kruger 'time':0} 39*bbf1c217SScott Kruger timesummary={} 40*bbf1c217SScott 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() 45100ef3c7SJed Brown summary[l[0]] += l[1:] if l[0] == 'failures' else int(l[1]) 46*bbf1c217SScott Kruger if l[0] == 'time' and int(l[1])>0: 47*bbf1c217SScott Kruger timesummary[cfile]=int(l[1]) 48*bbf1c217SScott Kruger timelist.append(int(l[1])) 49a2766241SScott Kruger 5091bc3e46SScott Kruger failstr=' '.join(summary['failures']) 51100ef3c7SJed Brown print("\n# -------------") 52100ef3c7SJed Brown print("# Summary ") 53100ef3c7SJed Brown print("# -------------") 541a3f486dSScott Kruger if failstr.strip(): print("# FAILED " + failstr) 558ccd5183SScott Kruger 568ccd5183SScott Kruger for t in "success failed todo skip".split(): 578ccd5183SScott Kruger percent=summary[t]/float(summary['total'])*100 58100ef3c7SJed Brown print("# %s %d/%d tests (%3.1f%%)" % (t, summary[t], summary['total'], percent)) 59*bbf1c217SScott Kruger print("#\n# Approximate time (not incl. build time): %s sec"% summary['time']) 6091bc3e46SScott Kruger 61c687a870SSatish Balay if failstr.strip(): 6291bc3e46SScott Kruger fail_targets=( 6391bc3e46SScott Kruger re.sub('(?<=[0-9]_\w)_.*','', 6491bc3e46SScott Kruger re.sub('_1 ',' ', 6591bc3e46SScott Kruger re.sub('cmd-','', 666ca6af43SScott Kruger re.sub('diff-','',failstr+' ')))) 6791bc3e46SScott Kruger ) 6891bc3e46SScott Kruger # Need to make sure we have a unique list 6991bc3e46SScott Kruger fail_targets=' '.join(list(set(fail_targets.split()))) 703054ff8cSScott Kruger 713054ff8cSScott Kruger #Make the message nice 723054ff8cSScott Kruger makefile="gmakefile.test" if inInstallDir() else "gmakefile" 733054ff8cSScott Kruger 7491bc3e46SScott Kruger print("#\n# To rerun failed tests: ") 753054ff8cSScott Kruger print("# "+make+" -f "+makefile+" test search='" + fail_targets.strip()+"'") 76*bbf1c217SScott Kruger 77*bbf1c217SScott Kruger if ntime>0: 78*bbf1c217SScott Kruger print("# Timing summary: ") 79*bbf1c217SScott Kruger timelist=list(set(timelist)) 80*bbf1c217SScott Kruger timelist.sort(reverse=True) 81*bbf1c217SScott Kruger nlim=(ntime if ntime<len(timelist) else len(timelist)) 82*bbf1c217SScott Kruger # Do a double loop to sort in order 83*bbf1c217SScott Kruger for timelimit in timelist[0:nlim]: 84*bbf1c217SScott Kruger for cf in timesummary: 85*bbf1c217SScott Kruger if timesummary[cf] == timelimit: 86*bbf1c217SScott Kruger print("# %s: %d sec" % (re.sub('.counts','',cf), timesummary[cf])) 87*bbf1c217SScott Kruger 888ccd5183SScott Kruger return 898ccd5183SScott Kruger 908ccd5183SScott Krugerdef main(): 918ccd5183SScott Kruger parser = optparse.OptionParser(usage="%prog [options]") 928ccd5183SScott Kruger parser.add_option('-d', '--directory', dest='directory', 938ccd5183SScott Kruger help='Directory containing results of petsc test system', 94*bbf1c217SScott Kruger default=os.path.join(os.environ.get('PETSC_ARCH'), 95*bbf1c217SScott Kruger 'tests','counts')) 963054ff8cSScott Kruger parser.add_option('-m', '--make', dest='make', 973054ff8cSScott Kruger help='make executable to report in summary', 983054ff8cSScott Kruger default='make') 99*bbf1c217SScott Kruger parser.add_option('-t', '--time', dest='time', 100*bbf1c217SScott Kruger help='-t n: Report on the n number expensive jobs', 101*bbf1c217SScott Kruger default=0) 1028ccd5183SScott Kruger options, args = parser.parse_args() 1038ccd5183SScott Kruger 1048ccd5183SScott Kruger # Process arguments 1058ccd5183SScott Kruger if len(args) > 0: 1068ccd5183SScott Kruger parser.print_usage() 1078ccd5183SScott Kruger return 1088ccd5183SScott Kruger 109*bbf1c217SScott Kruger summarize_results(options.directory,options.make,int(options.time)) 1108ccd5183SScott Kruger 1118ccd5183SScott Krugerif __name__ == "__main__": 1128ccd5183SScott Kruger main() 113