00001
00002
00003 import optparse
00004 import os
00005 from glob import glob
00006 import re
00007 import pprint
00008 import commands
00009 countRE = re.compile (r'^count_(\w+)')
00010 avoid = ['index', 'print']
00011
00012 def summaryOK (summary):
00013 """returns a tuple. First value is true if summary hasn't found
00014 any problems, else false."""
00015 retval = True
00016 count = -1
00017 compared = summary.get('eventsCompared', -1)
00018 if len( summary.keys()) != 2:
00019 retval = False
00020 for key,value in summary.iteritems():
00021 if countRE.search(key):
00022 count = value
00023 return (retval, {'count':count, 'compared':compared})
00024
00025 if __name__ == "__main__":
00026
00027
00028 percentRE = re.compile (r'%')
00029 startOutputRE = re.compile (r'^Summary$')
00030 success1RE = re.compile (r"{'eventsCompared':\s+(\d+),\s+'count_(\S+)':\s+(\d+)\s*}")
00031 success2RE = re.compile (r"{'count_(\S+)':\s+(\d+),\s+'eventsCompared':\s+(\d+)\s*}")
00032 loadingSoRE = re.compile (r'loading (genobjectrootlibs/\w+)')
00033 creatingSoRE = re.compile (r'creating shared library (\S+)')
00034 compRootRE = re.compile (r' --compRoot=(\S+)')
00035 descriptionRE = re.compile (r'^edmOneToOneComparison.py (\w+).txt')
00036 edmCommandRE = re.compile (r'^(edmOneToOneComparison.py .+?)\s*$')
00037
00038 labelErrorRE = re.compile (r"labelDict = GenObject._ntupleDict\[tupleName\]\['_label'\]")
00039 missingLabelRE = re.compile (r'not able to get')
00040 terminatedRE = re.compile (r'Terminated\s+\$EXE\s+\$@')
00041 cppExceptionRE = re.compile (r'\(C\+\+ exception\)')
00042 missingCfgRE = re.compile (r"raise.+Can't open configuration")
00043 finishRE = re.compile (r'finish')
00044 dummyRE = re.compile (r'edm::Wrapper<dummyType>')
00045 noEdmWrapperRE = re.compile (r"'ROOT' has no attribute 'edm::Wrapper")
00046 uint32RE = re.compile (r"Config file parser error 'operatoruint32_t")
00047 nonSpacesRE = re.compile (r'\S')
00048 problemDict = { 'labelDict' : labelErrorRE,
00049 'missingLabel' : missingLabelRE,
00050 'terminate' : terminatedRE,
00051 'uint32' : uint32RE,
00052 'cppException' : cppExceptionRE,
00053 'missingCfg' : missingCfgRE,
00054 'noEdmWrapper' : noEdmWrapperRE,
00055 'dummy' : dummyRE,
00056 'operator' : re.compile (r"onfig file parser error 'operator"),
00057 'useless' : re.compile (r'no member functions that are useful'),
00058 'lazy' : re.compile (r': Assertion'),
00059 'detset' : re.compile (r"AttributeError: 'edm::DetSet"),
00060 'doubleint' : re.compile (r'AttributeError: (int|double)'),
00061 'finish' : finishRE}
00062
00063 parser = optparse.OptionParser ("Usage: %prog logfilePrefix [directory]")
00064 parser.add_option ("--counts", dest="counts",
00065 action="store_true", default=False,
00066 help="Display counts only.")
00067 parser.add_option ('--mismatch', dest='mismatch',
00068 action='store_true',
00069 help='Displays only mismatch output')
00070 parser.add_option ("--diffTree", dest="diffTree",
00071 action="store_true", default=False,
00072 help="Shows diffTree printout.")
00073 parser.add_option ('--makeCompRoot', dest='makeCompRoot',
00074 action='store_true',
00075 help='Prints commands to make compRoot files for difftree')
00076 parser.add_option ("--problem", dest="problem", type='string',
00077 help="Displays problems matching PROBLEM")
00078
00079 options, args = parser.parse_args()
00080 if not 1 <= len (args) <= 2:
00081 raise RuntimeError, "Must give directory and log file prefix"
00082 logfilePrefix = percentRE.sub ('*', args[0])
00083 if logfilePrefix[-1] != '*':
00084 logfilePrefix += '*'
00085 cwd = os.getcwd()
00086 logdir = ''
00087 if len (args) == 2:
00088 logdir = args[1]
00089 os.chdir (logdir)
00090 files = glob (logfilePrefix)
00091 if logdir:
00092 oldFiles = files
00093 files = []
00094 for filename in oldFiles:
00095 files.append (logdir + '/' + filename)
00096 os.chdir (cwd)
00097 totalFiles = len (files)
00098 problems = {}
00099 succeeded = 0
00100 weird = 0
00101 problemTypes = {}
00102 successes = {}
00103 objectName = ''
00104 compRoot = ''
00105 soName = ''
00106 command = ''
00107 diffOutput = {}
00108 goShlib = ''
00109 for log in files:
00110 problemSet = set()
00111 source = open (log, 'r')
00112 ran = False
00113 success = False
00114 reading = False
00115 summaryLines = ''
00116 for line in source:
00117 line = line.rstrip('\n')
00118 match = edmCommandRE.search (line)
00119 if match:
00120 command = match.group(1)
00121 match = loadingSoRE.search (line)
00122 if match:
00123 goShlib = match.group(1)
00124 match = creatingSoRE.search (line)
00125 if match:
00126 goShlib = match.group(1)
00127 if options.diffTree:
00128 match = descriptionRE.search (line)
00129 if match:
00130 objectName = match.group(1)
00131 match = compRootRE.search (line)
00132 if match:
00133 compRoot = match.group(1)
00134 match = loadingSoRE.search (line)
00135 if match:
00136 soName = match.group(1)
00137 if reading:
00138 if not nonSpacesRE.search(line):
00139 reading = False
00140 continue
00141 summaryLines += line
00142 if startOutputRE.search(line):
00143 ran = True
00144 reading = True
00145 continue
00146 if success1RE.search (line) or success2RE.search(line):
00147 success = True
00148 continue
00149 for key, regex in problemDict.iteritems():
00150
00151 if regex.search(line):
00152 if key in problemSet:
00153 continue
00154 problemSet.add (key)
00155 problems.setdefault(log,[]).append(key)
00156 if not problemTypes.has_key(key):
00157 problemTypes[key] = 1
00158 else:
00159 problemTypes[key] += 1
00160 key = ''
00161 source.close()
00162
00163 if summaryLines:
00164 summary = eval (summaryLines)
00165 ok = summaryOK (summary)
00166 else:
00167 ok = (False,)
00168 summary = None
00169 if ran and success:
00170 succeeded += 1
00171 if not ok[0]:
00172 weird += 1
00173 else:
00174 successes[log] = pprint.pformat (summary, indent=4)
00175 else:
00176 if ok[0]:
00177 weird += 1
00178 if not problems.has_key (log) and not ok[0]:
00179 if not ok[0] and summary:
00180 key = 'mismatch'
00181 problems[log] = pprint.pformat (summary, indent=4)
00182
00183 if objectName and compRoot and soName:
00184
00185 varNames = summary.get(objectName, {}).\
00186 get('_var', {}).keys()
00187 variables = ['eta', 'phi']
00188 for var in sorted (varNames):
00189 if var not in variables and var not in avoid:
00190 variables.append (var)
00191 diffCmd = 'diffTreeTool.py --skipUndefined %s %s %s' \
00192 % (compRoot, soName, " ".join(variables))
00193
00194 diffOutput[log] = diffCmd
00195 else:
00196 problems[log] = ['other','ran:%s' % ran,
00197 'success:%s' % success]
00198 key = 'other'
00199 if not problemTypes.has_key(key):
00200 problemTypes[key] = 1
00201 else:
00202 problemTypes[key] += 1
00203 mismatches = problemTypes.get('mismatch', 0)
00204 if problemTypes.has_key ('mismatch'):
00205 del problemTypes['mismatch']
00206 print "total: ", len (files)
00207 print "success: ", succeeded
00208 print "mismatches: ", mismatches
00209 print "weird: ", weird
00210 print "Tool issue types:"
00211 total = 0
00212 for key, value in sorted (problemTypes.iteritems()):
00213 print " %-15s: %4d" % (key, value)
00214 total += value
00215 print " ", '-'*13, " : ----"
00216 print " %-15s: %4d + %d + %d + %d = %d" \
00217 % ('total', total, succeeded, mismatches, weird,
00218 total + succeeded + mismatches + weird)
00219
00220 if not options.counts:
00221 print "\nDetailed Problems list:"
00222 for key, problemList in sorted (problems.iteritems()):
00223 if options.problem and problemList[0] != options.problem:
00224 continue
00225 if options.mismatch and not isinstance (problemList, str):
00226 continue
00227
00228 print " %s:\n %s\n" % (key, problemList)
00229 if options.mismatch and goShlib and compRoot:
00230 print "diffTree %s %s" % (goShlib, compRoot)
00231 diffCmd = diffOutput.get(key)
00232 if diffCmd:
00233 print commands.getoutput (diffCmd)
00234 if not options.problem and not options.mismatch:
00235 print "\n", '='*78, '\n'
00236 print "Success list:"
00237 for key, successesList in sorted (successes.iteritems()):
00238 print " %s:\n %s\n" % (key, successesList)