seSuiteBase.py

Go to the documentation of this file.
00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2005
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "Script engine suite base class"
00012 __author__   = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = "2005/07/15 00:08:27"
00014 __updated__  = "$Date: 2006/04/04 02:27:50 $"
00015 __version__  = "$Revision: 1.8 $"
00016 __release__  = "$Name: HEAD $"
00017 __credits__  = "SLAC"
00018 
00019 import LICOS.copyright_SLAC
00020 
00021 from threading import Event
00022 import logging as log
00023 
00024 from LICOS.scriptEngine.FSM import FSM
00025 from LICOS.scriptEngine     import rcUtil
00026 from LICOS.lib.scriptEngine.seAppBase import seAppBase
00027 
00028 class seSuiteBase(FSM):
00029   """!\brief Script engine base class for suites.
00030 
00031   """
00032 
00033   # private class level variables
00034   __suiteStack = []
00035 
00036   def __init__(self, common):
00037     """!\brief seSuiteBase constructor
00038 
00039     \param common ScriptEngineCommon instance
00040     """
00041     FSM.__init__(self, 'SUITE STOPPED', None)
00042     self.set_default_transition(                                  self.error,     None)
00043     self.add_transition        ('SETUP',     'SUITE STOPPED',     self.seSetup,   'SUITE IN PROGRESS')
00044     self.add_transition        ('RUN',       'SUITE IN PROGRESS', self.seRun,     'SUITE COMPLETE')
00045     self.add_transition        ('STOP_RUN',  'SUITE COMPLETE',    self.seStopRun, 'SUITE STOPPED')
00046     self.add_transition        ('ABORT',     'SUITE IN PROGRESS', self.seAbort,   'SUITE STOPPED')
00047     self.add_transition        ('PAUSE',     'SUITE IN PROGRESS', self.sePause,   'SUITE PAUSED')
00048     self.add_transition        ('RESUME',    'SUITE PAUSED',      self.seResume,  'SUITE IN PROGRESS')
00049 
00050     self.common = common
00051     self.prefs = self.common.preferences()
00052 
00053     self.gui = common.getGUI()
00054 
00055     self.__suiteStart  = None
00056     self.__stopRequested = False
00057     self.__parentSuite = None
00058     self.__scriptSeq   = 0
00059     # Current suite's child script (could be an app or a suite)
00060     self.__script      = None
00061     self.__resumeEvent = Event()
00062     self.__paused      = False
00063     self.__suiteID     = None
00064 
00065   def getRunSequence(self):
00066     """!\brief Return the order of transitions for this type of application.
00067 
00068     \return A list of transitions
00069     """
00070     return ['SETUP', 'RUN', 'STOP_RUN']
00071 
00072   def doAbort(self):
00073     """!\brief Request stop of execution.
00074 
00075     \return Result of the transition
00076     """
00077     if self.__paused:
00078       status = self.doResume()
00079       if status is not None: return status
00080     if self.get_transition("ABORT", self.current_state)[1] is not None:
00081       return self.process('ABORT')
00082 
00083   def doPause(self):
00084     """!\brief Request pause of execution.
00085 
00086     \return Result of the transition
00087     """
00088     if self.get_transition("PAUSE", self.current_state)[1] is not None:
00089       return self.process('PAUSE')
00090 
00091   def doResume(self):
00092     """!\brief Request resume of execution.
00093 
00094     \return Result of the transition
00095     """
00096     if self.get_transition("RESUME", self.current_state)[1] is not None:
00097       return self.process('RESUME')
00098 
00099   def error(self):
00100     """!\brief This method is called when an undefined transition is requested.
00101 
00102     """
00103     log.error(self.__class__.__name__ + " - Undefined transition: %s from state %s" % \
00104             (self.input_symbol, self.current_state))
00105 
00106   def seSetup(self):
00107     """!\brief SETUP transition method
00108 
00109     Calls self.setup()
00110 
00111     \return None for success or
00112             False if there is an exception or
00113             status returned by the suite.
00114     """
00115     self.__paused = False
00116     self.__stopRequested = False
00117     self.__scriptSeq   = 0
00118     self.__updateGUI()
00119 
00120     # define the suiteStart script.
00121     # As it's part of this module, we don't have to call scriptLoad,
00122     #   but setParentSuite must be called.
00123     self.__suiteStart = suiteStart(self.common)
00124     self.__suiteStart.setParentSuite(self)
00125 
00126     return self.setup()
00127 
00128   def seRun(self):
00129     """!\brief RUN transition method
00130 
00131     Calls self.run()
00132 
00133     \return None for success or
00134             False if there is an exception or
00135             status returned by the suite.
00136     """
00137     self.__updateGUI()
00138     # run the suiteStart script.
00139     self.scriptRun(self.__suiteStart)
00140     return self.run()
00141 
00142   def sePause(self):
00143     """!\brief PAUSE transition method
00144 
00145     Calls self.pause()
00146 
00147     \return None for success or
00148             False if there is an exception or
00149             status returned by the suite.
00150     """
00151     if self.__resumeEvent.isSet():
00152       self.__resumeEvent.clear()
00153       self.gui.execGUImethodNR(self.gui.updateState, "PAUSING SUITE")
00154       if self.__script is not None and 'doPause' in dir(self.__script):
00155         status = self.__script.doPause()
00156         if status is not None: return status
00157     return self.pause()
00158 
00159   def seResume(self):
00160     """!\brief RESUME transition method
00161 
00162     Calls self.resume()
00163 
00164     \return None for success or
00165             False if there is an exception or
00166             status returned by the suite.
00167     """
00168     if self.__paused:
00169       if self.__script is not None and 'doResume' in dir(self.__script):
00170         self.__script.doResume()
00171       self.__resumeEvent.set()
00172       return self.resume()
00173 
00174   def seStopRun(self):
00175     """!\brief STOP_RUN transition method
00176 
00177     Calls self.stopRun()
00178 
00179     \return None for success or
00180             False if there is an exception or
00181             status returned by the suite.
00182     """
00183     if self.__paused:
00184       self.process('RESUME')
00185     self.__updateGUI()
00186     status =  self.stopRun()
00187     self.__suiteID     = None
00188     return status
00189 
00190 
00191   def seAbort(self):
00192     """!\brief ABORT transition method
00193 
00194     Calls self.abort()
00195 
00196     \return None for success or
00197             False if there is an exception or
00198             status returned by the suite.
00199     """
00200     self.setStopRequested()
00201     if self.__script is not None and 'doAbort' in dir(self.__script):
00202       self.__script.doAbort()
00203     return self.abort()
00204 
00205   def __updateGUI(self):
00206     """!\brief Update the state of the run on the GUI.
00207 
00208     """
00209     if self.gui is not None:
00210       self.gui.execGUImethodNR(self.gui.updateState, self.current_state)
00211 
00212   def setup(self):
00213     """!\brief Transition method to be overridden by the suite.
00214 
00215     """
00216     pass
00217 
00218   def stopRun(self):
00219     """!\brief Transition method to be overridden by the suite.
00220 
00221     """
00222     pass
00223 
00224   def pause(self):
00225     """!\brief Transition method to be overridden by the suite.
00226 
00227     """
00228     pass
00229 
00230   def resume(self):
00231     """!\brief Transition method to be overridden by the suite.
00232 
00233     """
00234     pass
00235 
00236   def abort(self):
00237     """!\brief Transition method to be overridden by the suite.
00238 
00239     """
00240     pass
00241 
00242   def scriptLoad(self, script, *args, **kwargs):
00243     """!\brief Load and instantiate an seAppBase or seSuiteBase based script.
00244 
00245     \param script Script module name or Python source path
00246     \param args   Positional arguments passed to the script
00247     \param kwargs Keyword arguments passed to the script
00248 
00249     \return Instantiated script object
00250     """
00251     (self.__module, self.__filename,
00252         self.__script) = rcUtil.scriptLoad(script, self.common,
00253                                         0, *args, **kwargs)
00254     if self.__script is not None:
00255       self.__script.setParentSuite(self)
00256     return self.__script
00257 
00258   def scriptRun(self, script=None):
00259     """!\brief Start the run of the specified script.
00260 
00261     \param script Instantiated script object.
00262                   If None, the last instantiated script is used.
00263     """
00264     if script == None:
00265       script = self.__script
00266     else:
00267       self.__script = script
00268     self.__scriptSeq += 1
00269 
00270     log.debug("script subclass: %s" % isinstance(script, seSuiteBase))
00271     if isinstance(script, seSuiteBase):
00272       script.setSuiteID(self.getSuiteID())
00273 
00274     self.__resumeEvent.set()
00275     rcUtil.scriptRun(script)
00276     if self.isPauseRequested():
00277       self.__updateGUI()
00278       self.setPaused(True)
00279       self.__resumeEvent.wait()
00280       self.setPaused(False)
00281 
00282   def getName(self):
00283     """!\brief Retrieve the class name of the script.
00284 
00285     \return Name of the script class
00286     """
00287     return self.__class__.__name__
00288 
00289   def getScript(self):
00290     """!\brief Retrieve the script object.
00291 
00292     \return Script object instance.
00293     """
00294     return self.__script
00295 
00296   def getType(self):
00297     """!\brief Return the type of test based on this class.
00298 
00299     Used for logging purposes.
00300 
00301     \return Test type
00302     """
00303     return 'Suite'
00304 
00305   def isStopRequested(self):
00306     """!\brief Is stop requested?
00307 
00308     \return Boolean flag indicating whether a stop was requested
00309     """
00310     return self.__stopRequested
00311 
00312   def setStopRequested(self):
00313     """!\brief Set the stop requested flag.
00314 
00315     """
00316     self.__stopRequested = True
00317 
00318   def isPauseRequested(self):
00319     """!\brief Is pause requested?
00320 
00321     \return Boolean flag indicating whether a pause was requested
00322     """
00323     return not self.__resumeEvent.isSet()
00324 
00325   def isPaused(self):
00326     """!\brief Retrieve the paused status of the script.
00327 
00328     \param paused Boolean indicating whether the script is paused or not
00329     """
00330     return self.__paused
00331 
00332   def setPaused(self, paused):
00333     """!\brief Mark the script and its parent suites as paused or unpaused.
00334 
00335     \param paused Boolean indicating whether the script is paused or not
00336     """
00337     self.__paused = paused
00338     if self.__parentSuite is not None:
00339       self.__parentSuite.setPaused(paused)
00340 
00341   def setParentSuite(self, suite):
00342     """!\brief Set the parent suite instance.
00343 
00344     \param Suite instance
00345     """
00346     self.__parentSuite = suite
00347 
00348   def getParentSuite(self):
00349     """!\brief Retrieve the parent suite instance.
00350 
00351     \return Suite instance
00352     """
00353     return self.__parentSuite
00354 
00355   def getParentSuiteName(self):
00356     """!\brief Retrieve the parent suite name.
00357 
00358     \return Parent suite name.
00359     """
00360     if self.__parentSuite is not None:
00361       return self.__parentSuite.getName()
00362 
00363   def isRunFromSuite(self):
00364     """!\brief Check if the script is being run from a suite.
00365 
00366     \return True  If the script is being run from a suite,
00367             False otherwise.
00368     """
00369     return self.__parentSuite is not None
00370 
00371   def getScriptSequence(self):
00372     """!\brief Retrieve the sequence number for the running suite script.
00373 
00374     The script sequence is incremented for each scriptRun called in the suite.
00375     This method is provided so that the suite author and the script engine
00376     can keep track of which script is the first script being run (which will
00377     have a script sequence of 1).
00378 
00379     \return Suite script sequence
00380     """
00381     return self.__scriptSeq
00382 
00383   def getSuiteID(self):
00384     """!\brief Retrieve the suite identifier
00385 
00386     As an aid to linking runs in suites together, a LICOS activity has
00387     the concept of a suite identifier.  This number is identically the
00388     runID of the first run of a suite (which is implemented in
00389     seSuiteBase.py).
00390 
00391     \return Suite identifier (integer string)
00392     """
00393     return self.__suiteID
00394 
00395   def setSuiteID(self, suiteID):
00396     """!\brief Set the suite identifier
00397 
00398     \param suiteID   Suite identifier (integer or numeric string)
00399     """
00400     self.__suiteID = str(suiteID)
00401 
00402   def setSessionVar(self, key, value):
00403     """!\brief Set a session variable.
00404 
00405     Do not use variable names beginning
00406     with the underscore ('_') character since these are reserved for ScriptEngine
00407     """
00408     sessionVars = self.common.getDBN()
00409     if sessionVars is not None:
00410       sessionVars[key] = value
00411     else:
00412       raise RuntimeError, "Database node does not exist"
00413 
00414   def getSessionVar(self, key):
00415     """!\brief Retrieve the values of the session variable indicated by \a key.
00416 
00417     \return Session variable value
00418     """
00419     sessionVars = self.common.getDBN()
00420     if sessionVars is not None and sessionVars.has_key(key):
00421       return sessionVars[key]
00422     else:
00423       return None
00424 
00425 class suiteStart(seAppBase):
00426   """!\brief Dummy run to indicate that a suite has started
00427   """
00428   def __init__(self, common, fromVal=None, toVal=None):
00429     """!\brief suiteStart constructor.
00430 
00431     \param fromVal from value
00432     \param toVal   to value
00433     """
00434     seAppBase.__init__(self, common)
00435     self.__fromVal = fromVal
00436     self.__toVal = toVal
00437 
00438   def setup(self):
00439     """!\brief SETUP transition method.
00440 
00441     \return Transition result
00442     """
00443 
00444     return None
00445 
00446   def teardown(self):
00447     """!\brief START_RUN transition method
00448 
00449     Sets the suite identifier for the controlling suite
00450     """
00451     self.getParentSuite().setSuiteID(self.runId)
00452 
00453   def stopRun(self):
00454     """!\brief STOP_RUN transition method
00455 
00456     \return Transition result
00457     """
00458     self.setCompletionStatus(self.COMPL_STATUS_PASSED)
00459     return None

Generated on Thu Apr 27 20:52:43 2006 for LICOS L02-01-00 by doxygen 1.4.6-NO