All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Public Attributes | List of all members
CheckPhotonLibraryJobs.JobChecker Class Reference

Public Member Functions

def __init__
 
def setupList
 
def reset
 
def isCollectingOutput
 
def checkFromFile
 
def checkJob
 
def getJobInfo
 
def checkJobGoodness
 
def collectJobOutputFiles
 
def writeList
 
def writeSummary
 

Public Attributes

 checkBaseDir
 
 checkBaseName
 
 knownGoodJobs
 
 knownBadJobs
 
 goodList
 
 badList
 
 outputFileList
 

Detailed Description

Performs checks on job output and collects output files.

Definition at line 134 of file CheckPhotonLibraryJobs.py.

Constructor & Destructor Documentation

def CheckPhotonLibraryJobs.JobChecker.__init__ (   self,
  baseName 
)

Definition at line 140 of file CheckPhotonLibraryJobs.py.

141  baseName: "name used for the check (defaults are shaped after it)",
142  goodList: "name of good job list (None: automatic; False: no list)" = None,
143  badList: "name of bad job list (None: automatic; False: no list)" = None,
144  fileList: "name of output file list (None: automatic; False: no list)" = None,
145  skipKnownGoodJobs: "do not check the jobs already in the good list" = False,
146  skipKnownBadJobs: "do not check the jobs already in the bad list" = False,
147  ):
148 
149  self.checkBaseDir = os.path.dirname(baseName)
150  # remove suffix:
152  os.path.splitext(os.path.basename(baseName))[0], # start with basename
153  '_xml', '-xml'
154  )
155 
156  self.goodListName, self.goodList, self.knownGoodJobs \
157  = self.setupList(goodList, 'goodxml', mustExist=skipKnownGoodJobs)
158  self.badListName, self.badList, self.knownBadJobs \
159  = self.setupList(badList, 'badxml', mustExist=skipKnownBadJobs)
160  self.outputFileListName, self.outputFileList, _ \
161  = self.setupList(fileList, 'outputfile')
162 
163  if not skipKnownGoodJobs: self.knownGoodJobs = set()
164  if not skipKnownBadJobs: self.knownBadJobs = set()

Member Function Documentation

def CheckPhotonLibraryJobs.JobChecker.checkFromFile (   self,
  XMLfilePath 
)

Definition at line 209 of file CheckPhotonLibraryJobs.py.

210  XMLfilePath: "path to the file containing XML job configuration",
211  projectName: "target the specified project name in the file" = "",
212  stageName: "target the specified stage name in the file" = "",
213  maxJobs: "if not None, process at most this many jobs" = None
214  ):
215 
216  nJobs = 0
217  for lineNo, fileName in FileListIterator(listName=XMLfilePath, withLineNo=True):
218 
219  if maxJobs is not None and nJobs >= maxJobs:
220  logging.info("Maximum number of jobs checked (%d).", maxJobs)
221  break
222  # if
223  nJobs += 1
224 
225  try:
226  self.checkJob(fileName, projectName=projectName, stageName=stageName)
227  except KeyboardInterrupt: raise
228  except Exception as e:
229  logging.error("Error processing job '%s' (file list line %d): %s",
230  fileName, lineNo, e)
231  # try ... except
232 
# for file line
def CheckPhotonLibraryJobs.JobChecker.checkJob (   self,
  XMLfilePath 
)

Definition at line 237 of file CheckPhotonLibraryJobs.py.

238  XMLfilePath: "path to the file containing XML job configuration",
239  projectName: "target the specified project name in the file" = "",
240  stageName: "target the specified stage name in the file" = "",
241  ):
242 
243  if not os.path.isfile(XMLfilePath):
244  raise RuntimeError("Can't open file '{}'.".format(XMLfilePath))
245 
246  # jobInfo is a lazy callable returning the job information:
247  # information will be extracted only the first time `jobInfo()` is executed
248  jobInfo = CachedValue(lambda: self.getJobInfo \
249  (XMLfilePath, projectName=projectName, stageName=stageName))
250 
251  XMLfileDir, XMLfileName = os.path.split(XMLfilePath)
252 
253  if self.knownGoodJobs and (XMLfilePath in self.knownGoodJobs):
254  logging.info("%s: known as good, check skipped.", XMLfileName)
255  good = True
256  elif self.knownBadJobs and (XMLfilePath in self.knownBadJobs):
257  logging.info("%s: known as bad, check skipped.", XMLfileName)
258  good = False
259  else:
260  good = self.checkJobGoodness(jobInfo(), XMLfilePath)
261  #
262 
263  if good:
264  self.goodList.append(XMLfilePath)
265  if self.isCollectingOutput(): self.collectJobOutputFiles(jobInfo())
266  #
267  else:
268  self.badList.append(XMLfilePath)
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
def CheckPhotonLibraryJobs.JobChecker.checkJobGoodness (   self,
  jobInfo,
  jobName 
)

Definition at line 304 of file CheckPhotonLibraryJobs.py.

305  def checkJobGoodness(self, jobInfo, jobName):
306 
307  class JobCheckError(RuntimeError): pass
308 
309  try:
310  outputDir = jobInfo.outdir
311  logging.debug("Job '%s' output directory: '%s'", jobName, outputDir)
312 
313  if not os.path.isdir(outputDir):
314  raise JobCheckError("no output directory present ('{}')".format(outputDir))
315 
316  if not os.path.exists(os.path.join(outputDir, 'checked')):
317  raise JobCheckError("not checked (run `project.py --checkana` first)")
318 
319  for jobID in map(JobIDclass, open(os.path.join(outputDir, 'jobids.list'), 'r')):
320  logging.debug("Checking subjob '%s'", jobID)
321 
322  subjobDir = os.path.join(outputDir, jobID.subjobTag())
323  logging.debug("Subjob '%s' output directory: '%s'", jobID, subjobDir)
324  if not os.path.isdir(subjobDir):
325  raise JobCheckError("job %s missing output directory" % jobID)
326 
327  statusFile = os.path.join(subjobDir, 'larStage0.stat')
328  if not os.path.isfile(statusFile):
329  raise JobCheckError("job %s missing status file" % jobID)
330 
331  try:
332  status = int(open(statusFile, 'r').readline().strip())
333  except KeyboardInterrupt: raise
334  except Exception as e:
335  raise JobCheckError("job %s failed reading status file '%s': %s"
336  % (jobID, statusFile, e))
337  #
338 
339  if status != 0:
340  raise JobCheckError("job %s exited with error code %d" % (jobID, status))
341 
342  # for subjob
343 
344  expectedOutputFileList = os.path.join(outputDir, 'filesana.list')
345  if not os.path.exists(expectedOutputFileList):
346  raise JobCheckError("no output file list ('%s')" % expectedOutputFileList)
347 
348  expectedOutputFiles = list(FileListIterator(listName=expectedOutputFileList))
349  if len(expectedOutputFiles) == 0:
350  raise JobCheckError("job has no output file")
351 
352  foundOutputFiles = list(filter(os.path.isfile, expectedOutputFiles))
353  if len(foundOutputFiles) != len(expectedOutputFiles):
354  raise JobCheckError("only %d/%d output files still present"
355  % (len(foundOutputFiles), len(expectedOutputFiles)))
356  # if
357 
358  except JobCheckError as e:
359  logging.error("%s: %s", jobName, e)
360  return False
361  else:
362  logging.info("%s succeeded.", jobName)
363  return True
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
Framework includes.
list
Definition: file_to_url.sh:28
open(RACETRACK) or die("Could not open file $RACETRACK for writing")
def CheckPhotonLibraryJobs.JobChecker.collectJobOutputFiles (   self,
  jobInfo 
)

Definition at line 367 of file CheckPhotonLibraryJobs.py.

368  def collectJobOutputFiles(self, jobInfo):
369 
370  outputFileList = os.path.join(jobInfo.outdir, 'filesana.list')
371  self.outputFileList.extend(FileListIterator(listName=outputFileList))
def CheckPhotonLibraryJobs.JobChecker.getJobInfo (   self,
  jobConfigFile 
)

Definition at line 273 of file CheckPhotonLibraryJobs.py.

274  jobConfigFile: "path to the file containing XML job configuration",
275  projectName: "target the specified project name in the file" = "",
276  stageName: "target the specified stage name in the file" = "",
277  ):
278 
279  #
280  # get the project parsed by project.py
281  #
282  projInfo = project.get_project \
283  (jobConfigFile, projectname=projectName, stagename=stageName)
284 
285  if not projInfo: # this message should be improved...
286  raise RuntimeError("Job '{}' does not have project {} stage {}".format(
287  jobConfigFile, repr(projectName), repr(stageName)
288  ))
289  #
290 
291  stageInfo = \
292  next(filter(lambda stage: stage.name == stageName, projInfo.stages), None) \
293  if stageName else projInfo.stages[0]
294 
295  if not stageInfo:
296  raise RuntimeError("Job '{}' project {} does not have a stage {}".format(
297  jobConfigFile, repr(project.name), repr(stageName)
298  ))
299  #
300 
return stageInfo
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
Framework includes.
def CheckPhotonLibraryJobs.JobChecker.isCollectingOutput (   self,
  if,
  the,
  output,
  file,
  list,
  is,
  being,
  filled 
)

Definition at line 205 of file CheckPhotonLibraryJobs.py.

206  def isCollectingOutput(self) -> "if the output file list is being filled":
207  return self.outputFileListName is not None
def CheckPhotonLibraryJobs.JobChecker.reset (   self)
Resets all the counters and records.

Definition at line 196 of file CheckPhotonLibraryJobs.py.

197  def reset(self):
198  """Resets all the counters and records."""
199 
200  self.goodList = []
201  self.badList = []
202  self.outputFileList = []
def CheckPhotonLibraryJobs.JobChecker.setupList (   self,
  listName,
  listTag,
  mustExist = False 
)
Returns the name of the list, an empty list to be filled and the existing
content.

Definition at line 168 of file CheckPhotonLibraryJobs.py.

169  def setupList(self, listName, listTag, mustExist = False):
170  """Returns the name of the list, an empty list to be filled and the existing
171  content.
172  """
173 
174  if listName is False: # set up for no list at all
175  return None, [], set()
176 
177  if listName is None:
178  listPath = os.path.join \
179  (self.checkBaseDir, self.checkBaseName + "-" + listTag + ".list")
180  elif not os.path.dirname(listName):
181  listPath = os.path.join(self.checkBaseDir, listName)
182  else: listPath = listName
183 
184  if os.path.isfile(listPath):
185  listContent = set(FileListIterator(listName=listPath))
186  (logging.info if mustExist else logging.debug) \
187  ("File list %s contains already %d entries.", listPath, len(listContent))
188  elif mustExist:
189  raise RuntimeError("File list '{}' ({} list) is required to exist."
190  .format(listPath, listTag))
191  else: listContent = set()
192 
return listPath, [], listContent
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
def CheckPhotonLibraryJobs.JobChecker.writeList (   self,
  content,
  fileName,
  tag,
  Whether,
  the,
  file,
  list,
  was,
  written 
)

Definition at line 375 of file CheckPhotonLibraryJobs.py.

376  def writeList(self, content, fileName, tag) -> "Whether the file list was written":
377 
378  if not fileName: return False # we are not asked to write the list
379 
380  # some file systems do not support overwriting
381  if os.path.exists(fileName):
382  try: os.remove(fileName)
383  except IOError as e:
384  logging.warning("Could not delete the old %s file list '%s': %s.",
385  tag, fileName, e)
386  # try ... except
387  # if
388 
389  # we do not write the list if it would be empty
390  if not len(content): return False
391 
392  listDir = os.path.dirname(fileName)
393  os.makedirs(os.path.normpath(listDir), exist_ok=True)
394 
395  with open(fileName, 'w') as listFile:
396 
397  print("# {} file list created on {}: {:d} entries".format(
398  tag, time.ctime(), len(content)
399  ), file=listFile,
400  )
401  listFile.write("\n".join(content))
402  listFile.write("\n")
403  # with
404 
405  logging.info("File list for %s created as '%s' with %d entries.",
406  tag, fileName, len(content))
407 
return True
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
do one_file $F done echo for F in find $TOP name CMakeLists txt print
S join(S const &sep, Coll const &s)
Returns a concatenation of strings in s separated by sep.
open(RACETRACK) or die("Could not open file $RACETRACK for writing")
def CheckPhotonLibraryJobs.JobChecker.writeSummary (   self)

Definition at line 411 of file CheckPhotonLibraryJobs.py.

412  def writeSummary(self):
413 
414  nJobs = len(self.badList) + len(self.goodList)
415 
416  # save file lists
417  if len(self.badList) > 0:
418 
419  if len(self.goodList) == 0:
420  logging.info("None of the %d jobs was successful!!", nJobs)
421  else:
422  logging.info("%d/%d jobs were not successful.", len(self.badList), nJobs)
423 
424  elif nJobs > 0:
425 
426  logging.info("All %d jobs were successful.", nJobs)
427 
428  else:
429  logging.error("No jobs checked.")
430 
431  try:
432  self.writeList(self.goodList, self.goodListName, "successful jobs")
433  except IOError as e:
434  logging.critical("Could not write good job file list '%s': %s",
435  self.goodListName, e)
436  # try
437 
438  try:
439  self.writeList(self.badList, self.badListName, "non-successful jobs")
440  except IOError as e:
441  logging.critical("Could not write bad job file list '%s': %s",
442  self.badListName, e)
443  # try
444 
445  try:
446  self.writeList(self.outputFileList, self.outputFileListName, "output files")
447  except IOError as e:
448  logging.critical("Could not write output file list '%s': %s",
449  self.outputFileListName, e)
450  # try
451 

Member Data Documentation

CheckPhotonLibraryJobs.JobChecker.badList

Definition at line 200 of file CheckPhotonLibraryJobs.py.

CheckPhotonLibraryJobs.JobChecker.checkBaseDir

Definition at line 148 of file CheckPhotonLibraryJobs.py.

CheckPhotonLibraryJobs.JobChecker.checkBaseName

Definition at line 150 of file CheckPhotonLibraryJobs.py.

CheckPhotonLibraryJobs.JobChecker.goodList

Definition at line 199 of file CheckPhotonLibraryJobs.py.

CheckPhotonLibraryJobs.JobChecker.knownBadJobs

Definition at line 163 of file CheckPhotonLibraryJobs.py.

CheckPhotonLibraryJobs.JobChecker.knownGoodJobs

Definition at line 162 of file CheckPhotonLibraryJobs.py.

CheckPhotonLibraryJobs.JobChecker.outputFileList

Definition at line 201 of file CheckPhotonLibraryJobs.py.


The documentation for this class was generated from the following file: