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