18ccd5183SScott Kruger#!/usr/bin/env python 2*5b6bfdb9SJed Brownfrom __future__ import print_function 391bc3e46SScott Krugerimport glob, os, re 48ccd5183SScott Krugerimport optparse 53054ff8cSScott Krugerimport inspect 63054ff8cSScott Kruger 78ccd5183SScott Kruger""" 88ccd5183SScott KrugerQuick script for parsing the output of the test system and summarizing the results. 98ccd5183SScott Kruger""" 108ccd5183SScott Kruger 113054ff8cSScott Krugerdef inInstallDir(): 123054ff8cSScott Kruger """ 133054ff8cSScott Kruger When petsc is installed then this file in installed in: 143054ff8cSScott Kruger <PREFIX>/share/petsc/examples/config/gmakegentest.py 153054ff8cSScott Kruger otherwise the path is: 163054ff8cSScott Kruger <PETSC_DIR>/config/gmakegentest.py 173054ff8cSScott Kruger We use this difference to determine if we are in installdir 183054ff8cSScott Kruger """ 193054ff8cSScott Kruger thisscriptdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 203054ff8cSScott Kruger dirlist=thisscriptdir.split(os.path.sep) 213054ff8cSScott Kruger if len(dirlist)>4: 223054ff8cSScott Kruger lastfour=os.path.sep.join(dirlist[len(dirlist)-4:]) 233054ff8cSScott Kruger if lastfour==os.path.join('share','petsc','examples','config'): 243054ff8cSScott Kruger return True 253054ff8cSScott Kruger else: 263054ff8cSScott Kruger return False 273054ff8cSScott Kruger else: 283054ff8cSScott Kruger return False 293054ff8cSScott Kruger 30bbf1c217SScott Krugerdef summarize_results(directory,make,ntime): 318ccd5183SScott Kruger ''' Loop over all of the results files and summarize the results''' 328ccd5183SScott Kruger startdir=os.path.realpath(os.path.curdir) 336d7e7da8SJed Brown try: 348ccd5183SScott Kruger os.chdir(directory) 356d7e7da8SJed Brown except OSError: 366d7e7da8SJed Brown print('# No tests run') 376d7e7da8SJed Brown return 38bbf1c217SScott Kruger summary={'total':0,'success':0,'failed':0,'failures':[],'todo':0,'skip':0, 39bbf1c217SScott Kruger 'time':0} 40bbf1c217SScott Kruger timesummary={} 41bbf1c217SScott Kruger timelist=[] 428ccd5183SScott Kruger for cfile in glob.glob('*.counts'): 43100ef3c7SJed Brown with open(cfile, 'r') as f: 44100ef3c7SJed Brown for line in f: 45100ef3c7SJed Brown l = line.split() 46100ef3c7SJed Brown summary[l[0]] += l[1:] if l[0] == 'failures' else int(l[1]) 47bbf1c217SScott Kruger if l[0] == 'time' and int(l[1])>0: 48bbf1c217SScott Kruger timesummary[cfile]=int(l[1]) 49bbf1c217SScott Kruger timelist.append(int(l[1])) 50a2766241SScott Kruger 5191bc3e46SScott Kruger failstr=' '.join(summary['failures']) 52100ef3c7SJed Brown print("\n# -------------") 53100ef3c7SJed Brown print("# Summary ") 54100ef3c7SJed Brown print("# -------------") 551a3f486dSScott Kruger if failstr.strip(): print("# FAILED " + failstr) 568ccd5183SScott Kruger 578ccd5183SScott Kruger for t in "success failed todo skip".split(): 588ccd5183SScott Kruger percent=summary[t]/float(summary['total'])*100 59100ef3c7SJed Brown print("# %s %d/%d tests (%3.1f%%)" % (t, summary[t], summary['total'], percent)) 60bbf1c217SScott Kruger print("#\n# Approximate time (not incl. build time): %s sec"% summary['time']) 6191bc3e46SScott Kruger 62c687a870SSatish Balay if failstr.strip(): 6391bc3e46SScott Kruger fail_targets=( 6491bc3e46SScott Kruger re.sub('(?<=[0-9]_\w)_.*','', 6591bc3e46SScott Kruger re.sub('_1 ',' ', 6691bc3e46SScott Kruger re.sub('cmd-','', 676ca6af43SScott Kruger re.sub('diff-','',failstr+' ')))) 6891bc3e46SScott Kruger ) 6991bc3e46SScott Kruger # Need to make sure we have a unique list 7091bc3e46SScott Kruger fail_targets=' '.join(list(set(fail_targets.split()))) 713054ff8cSScott Kruger 723054ff8cSScott Kruger #Make the message nice 733054ff8cSScott Kruger makefile="gmakefile.test" if inInstallDir() else "gmakefile" 743054ff8cSScott Kruger 7591bc3e46SScott Kruger print("#\n# To rerun failed tests: ") 763054ff8cSScott Kruger print("# "+make+" -f "+makefile+" test search='" + fail_targets.strip()+"'") 77bbf1c217SScott Kruger 78bbf1c217SScott Kruger if ntime>0: 79bbf1c217SScott Kruger print("# Timing summary: ") 80bbf1c217SScott Kruger timelist=list(set(timelist)) 81bbf1c217SScott Kruger timelist.sort(reverse=True) 82bbf1c217SScott Kruger nlim=(ntime if ntime<len(timelist) else len(timelist)) 83bbf1c217SScott Kruger # Do a double loop to sort in order 84bbf1c217SScott Kruger for timelimit in timelist[0:nlim]: 85bbf1c217SScott Kruger for cf in timesummary: 86bbf1c217SScott Kruger if timesummary[cf] == timelimit: 87bbf1c217SScott Kruger print("# %s: %d sec" % (re.sub('.counts','',cf), timesummary[cf])) 88bbf1c217SScott Kruger 898ccd5183SScott Kruger return 908ccd5183SScott Kruger 918ccd5183SScott Krugerdef main(): 928ccd5183SScott Kruger parser = optparse.OptionParser(usage="%prog [options]") 938ccd5183SScott Kruger parser.add_option('-d', '--directory', dest='directory', 948ccd5183SScott Kruger help='Directory containing results of petsc test system', 95e57812dcSJed Brown default=os.path.join(os.environ.get('PETSC_ARCH',''), 96bbf1c217SScott Kruger 'tests','counts')) 973054ff8cSScott Kruger parser.add_option('-m', '--make', dest='make', 983054ff8cSScott Kruger help='make executable to report in summary', 993054ff8cSScott Kruger default='make') 100bbf1c217SScott Kruger parser.add_option('-t', '--time', dest='time', 101bbf1c217SScott Kruger help='-t n: Report on the n number expensive jobs', 102bbf1c217SScott Kruger default=0) 1038ccd5183SScott Kruger options, args = parser.parse_args() 1048ccd5183SScott Kruger 1058ccd5183SScott Kruger # Process arguments 1068ccd5183SScott Kruger if len(args) > 0: 1078ccd5183SScott Kruger parser.print_usage() 1088ccd5183SScott Kruger return 1098ccd5183SScott Kruger 110bbf1c217SScott Kruger summarize_results(options.directory,options.make,int(options.time)) 1118ccd5183SScott Kruger 1128ccd5183SScott Krugerif __name__ == "__main__": 1138ccd5183SScott Kruger main() 114