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