xref: /petsc/config/report_tests.py (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
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