Gaudi Framework, version v23r3

Home   Generated: Thu Jun 28 2012
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions

GaudiTest::GaudiExeTest Class Reference

Inheritance diagram for GaudiTest::GaudiExeTest:
Inheritance graph
[legend]
Collaboration diagram for GaudiTest::GaudiExeTest:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def PlatformIsNotSupported
def GetPlatform
def isWinPlatform
def CheckTTreesSummaries
def CheckHistosSummaries
def ValidateWithReference
def ValidateOutput
def DumpEnvironment
def Run
def RunProgram

Public Attributes

 callable
 extra_args
 args_order
 program
 reference
 error_reference
 use_temp_dir
 timeout

Static Public Attributes

list arguments

Private Member Functions

def _expandReferenceFileName
def _CreateEclipseLaunch

Detailed Description

Standard Gaudi test.

Definition at line 990 of file GaudiTest.py.


Member Function Documentation

def GaudiTest::GaudiExeTest::_CreateEclipseLaunch (   self,
  prog,
  args,
  destdir = None 
) [private]

Definition at line 1580 of file GaudiTest.py.

01581                                                               :
01582         # Find the project name used in ecplise.
01583         # The name is in a file called ".project" in one of the parent directories
01584         projbasedir = os.path.normpath(destdir)
01585         while not os.path.exists(os.path.join(projbasedir, ".project")):
01586             oldprojdir = projbasedir
01587             projbasedir = os.path.normpath(os.path.join(projbasedir, os.pardir))
01588             # FIXME: the root level is invariant when trying to go up one level,
01589             #        but it must be cheched on windows
01590             if oldprojdir == projbasedir:
01591                 # If we cannot find a .project, so no point in creating a .launch file
01592                 return
01593         # Use ElementTree to parse the XML file
01594         from xml.etree import ElementTree as ET
01595         t = ET.parse(os.path.join(projbasedir, ".project"))
01596         projectName = t.find("name").text
01597 
01598         # prepare the name/path of the generated file
01599         destfile = "%s.launch" % self._Runnable__id
01600         if destdir:
01601             destfile = os.path.join(destdir, destfile)
01602 
01603         if self.options.strip():
01604             # this means we have some custom options in the qmt file, so we have
01605             # to copy them from the temporary file at the end of the arguments
01606             # in another file
01607             tempfile = args.pop()
01608             optsfile = destfile + os.path.splitext(tempfile)[1]
01609             shutil.copyfile(tempfile, optsfile)
01610             args.append(optsfile)
01611 
01612         # prepare the data to insert in the XML file
01613         from xml.sax.saxutils import quoteattr # useful to quote XML special chars
01614         data = {}
01615         # Note: the "quoteattr(k)" is not needed because special chars cannot be part of a variable name,
01616         # but it doesn't harm.
01617         data["environment"] = "\n".join(['<mapEntry key=%s value=%s/>' % (quoteattr(k), quoteattr(v))
01618                                          for k, v in os.environ.iteritems()])
01619 
01620         data["exec"] = which(prog) or prog
01621         if os.path.basename(data["exec"]).lower().startswith("python"):
01622             data["stopAtMain"] = "false" # do not stop at main when debugging Python scripts
01623         else:
01624             data["stopAtMain"] = "true"
01625 
01626         data["args"] = "&#10;".join(map(rationalizepath, args))
01627         if self.isWinPlatform():
01628             data["args"] = "&#10;".join(["/debugexe"] + map(rationalizepath, [data["exec"]] + args))
01629             data["exec"] = which("vcexpress.exe")
01630 
01631         if not self.use_temp_dir:
01632             data["workdir"] = os.getcwd()
01633         else:
01634             # If the test is using a tmporary directory, it is better to run it
01635             # in the same directory as the .launch file when debugged in eclipse
01636             data["workdir"] = destdir
01637 
01638         data["project"] = projectName.strip()
01639 
01640         # Template for the XML file, based on eclipse 3.4
01641         xml = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
01642 <launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
01643 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB" value="true"/>
01644 <listAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB_LIST"/>
01645 <stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="gdb"/>
01646 <stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=".gdbinit"/>
01647 <listAttribute key="org.eclipse.cdt.debug.mi.core.SOLIB_PATH"/>
01648 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.STOP_ON_SOLIB_EVENTS" value="false"/>
01649 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
01650 <stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="org.eclipse.cdt.debug.mi.core.standardCommandFactory"/>
01651 <stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
01652 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
01653 <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
01654 <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
01655 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="org.eclipse.cdt.debug.mi.core.CDebuggerNew"/>
01656 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
01657 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
01658 <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="%(stopAtMain)s"/>
01659 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
01660 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
01661 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
01662 <stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList/&gt;"/>
01663 <stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;globalVariableList/&gt;&#10;"/>
01664 <stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList/&gt;&#10;"/>
01665 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="%(args)s"/>
01666 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="%(exec)s"/>
01667 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="%(project)s"/>
01668 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
01669 <stringAttribute key="org.eclipse.cdt.launch.WORKING_DIRECTORY" value="%(workdir)s"/>
01670 <booleanAttribute key="org.eclipse.cdt.launch.ui.ApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
01671 <booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
01672 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
01673 <listEntry value="/%(project)s"/>
01674 </listAttribute>
01675 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
01676 <listEntry value="4"/>
01677 </listAttribute>
01678 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
01679 <mapAttribute key="org.eclipse.debug.core.environmentVariables">
01680 %(environment)s
01681 </mapAttribute>
01682 <mapAttribute key="org.eclipse.debug.core.preferred_launchers">
01683 <mapEntry key="[debug]" value="org.eclipse.cdt.cdi.launch.localCLaunch"/>
01684 </mapAttribute>
01685 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
01686 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
01687 </listAttribute>
01688 </launchConfiguration>
01689 """ % data
01690 
01691         # Write the output file
01692         open(destfile, "w").write(xml)
01693         #open(destfile + "_copy.xml", "w").write(xml)
01694 
01695 
try:
def GaudiTest::GaudiExeTest::_expandReferenceFileName (   self,
  reffile 
) [private]

Definition at line 1143 of file GaudiTest.py.

01144                                                :
01145         # if no file is passed, do nothing
01146         if not reffile:
01147             return ""
01148 
01149         # function to split an extension in constituents parts
01150         platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
01151 
01152         reference = os.path.normpath(os.path.expandvars(reffile))
01153         # old-style platform-specific reference name
01154         spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
01155         if os.path.isfile(spec_ref):
01156             reference = spec_ref
01157         else: # look for new-style platform specific reference files:
01158             # get all the files whose name start with the reference filename
01159             dirname, basename = os.path.split(reference)
01160             if not dirname: dirname = '.'
01161             head = basename + "."
01162             head_len = len(head)
01163             platform = platformSplit(self.GetPlatform())
01164             candidates = []
01165             for f in os.listdir(dirname):
01166                 if f.startswith(head):
01167                     req_plat = platformSplit(f[head_len:])
01168                     if platform.issuperset(req_plat):
01169                         candidates.append( (len(req_plat), f) )
01170             if candidates: # take the one with highest matching
01171                 # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
01172                 #        has to use ref.x86_64-gcc43 or ref.slc5-dbg
01173                 candidates.sort()
01174                 reference = os.path.join(dirname, candidates[-1][1])
01175         return reference

def GaudiTest::GaudiExeTest::CheckHistosSummaries (   self,
  stdout,
  result,
  causes,
  dict = None,
  ignore = None 
)
Compare the TTree summaries in stdout with the ones in trees_dict or in
the reference file. By default ignore the size, compression and basket
fields.
The presence of TTree summaries when none is expected is not a failure.

Definition at line 1210 of file GaudiTest.py.

01213                                            :
01214         """
01215         Compare the TTree summaries in stdout with the ones in trees_dict or in
01216         the reference file. By default ignore the size, compression and basket
01217         fields.
01218         The presence of TTree summaries when none is expected is not a failure.
01219         """
01220         if dict is None:
01221             reference = self._expandReferenceFileName(self.reference)
01222             # call the validator if the file exists
01223             if reference and os.path.isfile(reference):
01224                 dict = findHistosSummaries(open(reference).read())
01225             else:
01226                 dict = {}
01227 
01228         from pprint import PrettyPrinter
01229         pp = PrettyPrinter()
01230         if dict:
01231             result["GaudiTest.Histos.expected"] = result.Quote(pp.pformat(dict))
01232             if ignore:
01233                 result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
01234 
01235         histos = findHistosSummaries(stdout)
01236         failed = cmpTreesDicts(dict, histos, ignore)
01237         if failed:
01238             causes.append("histos summaries")
01239             msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
01240             result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
01241             result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
01242 
01243         return causes

def GaudiTest::GaudiExeTest::CheckTTreesSummaries (   self,
  stdout,
  result,
  causes,
  trees_dict = None,
  ignore = r"Basket|.*size|Compression" 
)
Compare the TTree summaries in stdout with the ones in trees_dict or in
the reference file. By default ignore the size, compression and basket
fields.
The presence of TTree summaries when none is expected is not a failure.

Definition at line 1176 of file GaudiTest.py.

01179                                                                    :
01180         """
01181         Compare the TTree summaries in stdout with the ones in trees_dict or in
01182         the reference file. By default ignore the size, compression and basket
01183         fields.
01184         The presence of TTree summaries when none is expected is not a failure.
01185         """
01186         if trees_dict is None:
01187             reference = self._expandReferenceFileName(self.reference)
01188             # call the validator if the file exists
01189             if reference and os.path.isfile(reference):
01190                 trees_dict = findTTreeSummaries(open(reference).read())
01191             else:
01192                 trees_dict = {}
01193 
01194         from pprint import PrettyPrinter
01195         pp = PrettyPrinter()
01196         if trees_dict:
01197             result["GaudiTest.TTrees.expected"] = result.Quote(pp.pformat(trees_dict))
01198             if ignore:
01199                 result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
01200 
01201         trees = findTTreeSummaries(stdout)
01202         failed = cmpTreesDicts(trees_dict, trees, ignore)
01203         if failed:
01204             causes.append("trees summaries")
01205             msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees, failed)
01206             result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
01207             result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
01208 
01209         return causes

def GaudiTest::GaudiExeTest::DumpEnvironment (   self,
  result 
)
Add the content of the environment to the result object.

Copied from the QMTest class of COOL.

Definition at line 1366 of file GaudiTest.py.

01367                                      :
01368         """
01369         Add the content of the environment to the result object.
01370 
01371         Copied from the QMTest class of COOL.
01372         """
01373         vars = os.environ.keys()
01374         vars.sort()
01375         result['GaudiTest.environment'] = \
01376             result.Quote('\n'.join(["%s=%s"%(v,os.environ[v]) for v in vars]))

def GaudiTest::GaudiExeTest::GetPlatform (   self )
Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1121 of file GaudiTest.py.

01122                          :
01123         """
01124         Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
01125         """
01126         arch = "None"
01127         # check architecture name
01128         if "CMTCONFIG" in os.environ:
01129             arch = os.environ["CMTCONFIG"]
01130         elif "SCRAM_ARCH" in os.environ:
01131             arch = os.environ["SCRAM_ARCH"]
01132         return arch

def GaudiTest::GaudiExeTest::isWinPlatform (   self )
Return True if the current platform is Windows.

This function was needed because of the change in the CMTCONFIG format,
from win32_vc71_dbg to i686-winxp-vc9-dbg.

Definition at line 1133 of file GaudiTest.py.

01134                            :
01135         """
01136         Return True if the current platform is Windows.
01137 
01138         This function was needed because of the change in the CMTCONFIG format,
01139         from win32_vc71_dbg to i686-winxp-vc9-dbg.
01140         """
01141         platform = self.GetPlatform()
01142         return "winxp" in platform or platform.startswith("win")

def GaudiTest::GaudiExeTest::PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1107 of file GaudiTest.py.

01108                                                      :
01109         platform = self.GetPlatform()
01110         unsupported = [ re.compile(x)
01111                         for x in [ str(y).strip()
01112                                    for y in self.unsupported_platforms ]
01113                         if x
01114                        ]
01115         for p_re in unsupported:
01116             if p_re.search(platform):
01117                 result.SetOutcome(result.UNTESTED)
01118                 result[result.CAUSE] = 'Platform not supported.'
01119                 return True
01120         return False

def GaudiTest::GaudiExeTest::Run (   self,
  context,
  result 
)
Run the test.

'context' -- A 'Context' giving run-time parameters to the
test.

'result' -- A 'Result' object.  The outcome will be
'Result.PASS' when this method is called.  The 'result' may be
modified by this method to indicate outcomes other than
'Result.PASS' or to add annotations.

Definition at line 1377 of file GaudiTest.py.

01378                                   :
01379         """Run the test.
01380 
01381         'context' -- A 'Context' giving run-time parameters to the
01382         test.
01383 
01384         'result' -- A 'Result' object.  The outcome will be
01385         'Result.PASS' when this method is called.  The 'result' may be
01386         modified by this method to indicate outcomes other than
01387         'Result.PASS' or to add annotations."""
01388 
01389         # Check if the platform is supported
01390         if self.PlatformIsNotSupported(context, result):
01391             return
01392 
01393         # Prepare program name and arguments (expanding variables, and converting to absolute)
01394         if self.program:
01395             prog = rationalizepath(self.program)
01396         elif "GAUDIEXE" in os.environ:
01397             prog = os.environ["GAUDIEXE"]
01398         else:
01399             prog = "Gaudi.exe"
01400         self.program = prog
01401 
01402         dummy, prog_ext = os.path.splitext(prog)
01403         if prog_ext not in [ ".exe", ".py", ".bat" ] and self.isWinPlatform():
01404             prog += ".exe"
01405             prog_ext = ".exe"
01406 
01407         prog = which(prog) or prog
01408 
01409         # Convert paths to absolute paths in arguments and reference files
01410         args = map(rationalizepath, self.args)
01411         self.reference = rationalizepath(self.reference)
01412         self.error_reference = rationalizepath(self.error_reference)
01413 
01414 
01415         # check if the user provided inline options
01416         tmpfile = None
01417         if self.options.strip():
01418             ext = ".opts"
01419             if re.search(r"from\s*Gaudi.Configuration\s*import\s*\*", self.options):
01420                 ext = ".py"
01421             tmpfile = TempFile(ext)
01422             tmpfile.writelines("\n".join(self.options.splitlines()))
01423             tmpfile.flush()
01424             args.append(tmpfile.name)
01425             result["GaudiTest.options"] = result.Quote(self.options)
01426 
01427         # if the program is a python file, execute it through python
01428         if prog_ext == ".py":
01429             args.insert(0,prog)
01430             if self.isWinPlatform():
01431                 prog = which("python.exe") or "python.exe"
01432             else:
01433                 prog = which("python") or "python"
01434 
01435         # Change to the working directory if specified or to the default temporary
01436         origdir = os.getcwd()
01437         if self.workdir:
01438             os.chdir(str(os.path.normpath(os.path.expandvars(self.workdir))))
01439         elif self.use_temp_dir == "true":
01440             if "QMTEST_TMPDIR" in os.environ:
01441                 os.chdir(os.environ["QMTEST_TMPDIR"])
01442             elif "qmtest.tmpdir" in context:
01443                 os.chdir(context["qmtest.tmpdir"])
01444 
01445         if "QMTEST_IGNORE_TIMEOUT" not in os.environ:
01446             self.timeout = max(self.timeout,600)
01447         else:
01448             self.timeout = -1
01449 
01450         try:
01451             # Generate eclipse.org debug launcher for the test
01452             self._CreateEclipseLaunch(prog, args, destdir = origdir)
01453             # Run the test
01454             self.RunProgram(prog,
01455                             [ prog ] + args,
01456                             context, result)
01457             # Record the content of the enfironment for failing tests
01458             if result.GetOutcome() not in [ result.PASS ]:
01459                 self.DumpEnvironment(result)
01460         finally:
01461             # revert to the original directory
01462             os.chdir(origdir)

def GaudiTest::GaudiExeTest::RunProgram (   self,
  program,
  arguments,
  context,
  result 
)
Run the 'program'.

'program' -- The path to the program to run.

'arguments' -- A list of the arguments to the program.  This
list must contain a first argument corresponding to 'argv[0]'.

'context' -- A 'Context' giving run-time parameters to the
test.

'result' -- A 'Result' object.  The outcome will be
'Result.PASS' when this method is called.  The 'result' may be
modified by this method to indicate outcomes other than
'Result.PASS' or to add annotations.

@attention: This method has been copied from command.ExecTestBase
    (QMTest 2.3.0) and modified to keep stdout and stderr
    for tests that have been terminated by a signal.
    (Fundamental for debugging in the Application Area)

Definition at line 1463 of file GaudiTest.py.

01464                                                              :
01465         """Run the 'program'.
01466 
01467         'program' -- The path to the program to run.
01468 
01469         'arguments' -- A list of the arguments to the program.  This
01470         list must contain a first argument corresponding to 'argv[0]'.
01471 
01472         'context' -- A 'Context' giving run-time parameters to the
01473         test.
01474 
01475         'result' -- A 'Result' object.  The outcome will be
01476         'Result.PASS' when this method is called.  The 'result' may be
01477         modified by this method to indicate outcomes other than
01478         'Result.PASS' or to add annotations.
01479 
01480         @attention: This method has been copied from command.ExecTestBase
01481                     (QMTest 2.3.0) and modified to keep stdout and stderr
01482                     for tests that have been terminated by a signal.
01483                     (Fundamental for debugging in the Application Area)
01484         """
01485 
01486         # Construct the environment.
01487         environment = self.MakeEnvironment(context)
01488         # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
01489         if "slc6" in environment.get('CMTCONFIG', ''):
01490             environment['TERM'] = 'dumb'
01491         # Create the executable.
01492         if self.timeout >= 0:
01493             timeout = self.timeout
01494         else:
01495             # If no timeout was specified, we sill run this process in a
01496             # separate process group and kill the entire process group
01497             # when the child is done executing.  That means that
01498             # orphaned child processes created by the test will be
01499             # cleaned up.
01500             timeout = -2
01501         e = GaudiFilterExecutable(self.stdin, timeout)
01502         # Run it.
01503         exit_status = e.Run(arguments, environment, path = program)
01504         # Get the stack trace from the temporary file (if present)
01505         if e.stack_trace_file and os.path.exists(e.stack_trace_file):
01506             stack_trace = open(e.stack_trace_file).read()
01507             os.remove(e.stack_trace_file)
01508         else:
01509             stack_trace = None
01510         if stack_trace:
01511             result["ExecTest.stack_trace"] = result.Quote(stack_trace)
01512 
01513         # If the process terminated normally, check the outputs.
01514         if sys.platform == "win32" or os.WIFEXITED(exit_status):
01515             # There are no causes of failure yet.
01516             causes = []
01517             # The target program terminated normally.  Extract the
01518             # exit code, if this test checks it.
01519             if self.exit_code is None:
01520                 exit_code = None
01521             elif sys.platform == "win32":
01522                 exit_code = exit_status
01523             else:
01524                 exit_code = os.WEXITSTATUS(exit_status)
01525             # Get the output generated by the program.
01526             stdout = e.stdout
01527             stderr = e.stderr
01528             # Record the results.
01529             result["ExecTest.exit_code"] = str(exit_code)
01530             result["ExecTest.stdout"] = result.Quote(stdout)
01531             result["ExecTest.stderr"] = result.Quote(stderr)
01532             # Check to see if the exit code matches.
01533             if exit_code != self.exit_code:
01534                 causes.append("exit_code")
01535                 result["ExecTest.expected_exit_code"] \
01536                     = str(self.exit_code)
01537             # Validate the output.
01538             causes += self.ValidateOutput(stdout, stderr, result)
01539             # If anything went wrong, the test failed.
01540             if causes:
01541                 result.Fail("Unexpected %s." % string.join(causes, ", "))
01542         elif os.WIFSIGNALED(exit_status):
01543             # The target program terminated with a signal.  Construe
01544             # that as a test failure.
01545             signal_number = str(os.WTERMSIG(exit_status))
01546             if not stack_trace:
01547                 result.Fail("Program terminated by signal.")
01548             else:
01549                 # The presence of stack_trace means tha we stopped the job because
01550                 # of a time-out
01551                 result.Fail("Exceeded time limit (%ds), terminated." % timeout)
01552             result["ExecTest.signal_number"] = signal_number
01553             result["ExecTest.stdout"] = result.Quote(e.stdout)
01554             result["ExecTest.stderr"] = result.Quote(e.stderr)
01555         elif os.WIFSTOPPED(exit_status):
01556             # The target program was stopped.  Construe that as a
01557             # test failure.
01558             signal_number = str(os.WSTOPSIG(exit_status))
01559             if not stack_trace:
01560                 result.Fail("Program stopped by signal.")
01561             else:
01562                 # The presence of stack_trace means tha we stopped the job because
01563                 # of a time-out
01564                 result.Fail("Exceeded time limit (%ds), stopped." % timeout)
01565             result["ExecTest.signal_number"] = signal_number
01566             result["ExecTest.stdout"] = result.Quote(e.stdout)
01567             result["ExecTest.stderr"] = result.Quote(e.stderr)
01568         else:
01569             # The target program terminated abnormally in some other
01570             # manner.  (This shouldn't normally happen...)
01571             result.Fail("Program did not terminate normally.")
01572 
01573         # Marco Cl.: This is a special trick to fix a "problem" with the output
01574         # of gaudi jobs when they use colors
01575         esc = '\x1b'
01576         repr_esc = '\\x1b'
01577         result["ExecTest.stdout"] = result["ExecTest.stdout"].replace(esc,repr_esc)
01578         # TODO: (MCl) improve the hack for colors in standard output
01579         #             may be converting them to HTML tags

def GaudiTest::GaudiExeTest::ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1301 of file GaudiTest.py.

01302                                                     :
01303         causes = []
01304         # if the test definition contains a custom validator, use it
01305         if self.validator.strip() != "":
01306             class CallWrapper(object):
01307                 """
01308                 Small wrapper class to dynamically bind some default arguments
01309                 to a callable.
01310                 """
01311                 def __init__(self, callable, extra_args = {}):
01312                     self.callable = callable
01313                     self.extra_args = extra_args
01314                     # get the list of names of positional arguments
01315                     from inspect import getargspec
01316                     self.args_order = getargspec(callable)[0]
01317                     # Remove "self" from the list of positional arguments
01318                     # since it is added automatically
01319                     if self.args_order[0] == "self":
01320                         del self.args_order[0]
01321                 def __call__(self, *args, **kwargs):
01322                     # Check which positional arguments are used
01323                     positional = self.args_order[:len(args)]
01324 
01325                     kwargs = dict(kwargs) # copy the arguments dictionary
01326                     for a in self.extra_args:
01327                         # use "extra_args" for the arguments not specified as
01328                         # positional or keyword
01329                         if a not in positional and a not in kwargs:
01330                             kwargs[a] = self.extra_args[a]
01331                     return apply(self.callable, args, kwargs)
01332             # local names to be exposed in the script
01333             exported_symbols = {"self":self,
01334                                 "stdout":stdout,
01335                                 "stderr":stderr,
01336                                 "result":result,
01337                                 "causes":causes,
01338                                 "findReferenceBlock":
01339                                     CallWrapper(findReferenceBlock, {"stdout":stdout,
01340                                                                      "result":result,
01341                                                                      "causes":causes}),
01342                                 "validateWithReference":
01343                                     CallWrapper(self.ValidateWithReference, {"stdout":stdout,
01344                                                                              "stderr":stderr,
01345                                                                              "result":result,
01346                                                                              "causes":causes}),
01347                                 "countErrorLines":
01348                                     CallWrapper(countErrorLines, {"stdout":stdout,
01349                                                                   "result":result,
01350                                                                   "causes":causes}),
01351                                 "checkTTreesSummaries":
01352                                     CallWrapper(self.CheckTTreesSummaries, {"stdout":stdout,
01353                                                                             "result":result,
01354                                                                             "causes":causes}),
01355                                 "checkHistosSummaries":
01356                                     CallWrapper(self.CheckHistosSummaries, {"stdout":stdout,
01357                                                                             "result":result,
01358                                                                             "causes":causes}),
01359 
01360                                 }
01361             exec self.validator in globals(), exported_symbols
01362         else:
01363             self.ValidateWithReference(stdout, stderr, result, causes)
01364 
01365         return causes

def GaudiTest::GaudiExeTest::ValidateWithReference (   self,
  stdout,
  stderr,
  result,
  causes,
  preproc = None 
)
Default validation action: compare standard output and error to the
reference files.

Definition at line 1244 of file GaudiTest.py.

01245                                                                                    :
01246         """
01247         Default validation action: compare standard output and error to the
01248         reference files.
01249         """
01250         # set the default output preprocessor
01251         if preproc is None:
01252             preproc = normalizeExamples
01253         # check standard output
01254         reference = self._expandReferenceFileName(self.reference)
01255         # call the validator if the file exists
01256         if reference and os.path.isfile(reference):
01257             result["GaudiTest.output_reference"] = reference
01258             causes += ReferenceFileValidator(reference,
01259                                              "standard output",
01260                                              "GaudiTest.output_diff",
01261                                              preproc = preproc)(stdout, result)
01262 
01263         # Compare TTree summaries
01264         causes = self.CheckTTreesSummaries(stdout, result, causes)
01265         causes = self.CheckHistosSummaries(stdout, result, causes)
01266 
01267         if causes: # Write a new reference file for stdout
01268             try:
01269                 newref = open(reference + ".new","w")
01270                 # sanitize newlines
01271                 for l in stdout.splitlines():
01272                     newref.write(l.rstrip() + '\n')
01273                 del newref # flush and close
01274             except IOError:
01275                 # Ignore IO errors when trying to update reference files
01276                 # because we may be in a read-only filesystem
01277                 pass
01278 
01279         # check standard error
01280         reference = self._expandReferenceFileName(self.error_reference)
01281         # call the validator if we have a file to use
01282         if reference and os.path.isfile(reference):
01283             result["GaudiTest.error_reference"] = reference
01284             newcauses = ReferenceFileValidator(reference,
01285                                                "standard error",
01286                                                "GaudiTest.error_diff",
01287                                                preproc = preproc)(stderr, result)
01288             causes += newcauses
01289             if newcauses: # Write a new reference file for stdedd
01290                 newref = open(reference + ".new","w")
01291                 # sanitize newlines
01292                 for l in stderr.splitlines():
01293                     newref.write(l.rstrip() + '\n')
01294                 del newref # flush and close
01295         else:
01296             causes += BasicOutputValidator(self.stderr,
01297                                            "standard error",
01298                                            "ExecTest.expected_stderr")(stderr, result)
01299 
01300         return causes


Member Data Documentation

Definition at line 1304 of file GaudiTest.py.

Definition at line 993 of file GaudiTest.py.

Definition at line 1304 of file GaudiTest.py.

Definition at line 1385 of file GaudiTest.py.

Definition at line 1304 of file GaudiTest.py.

Definition at line 1385 of file GaudiTest.py.

Definition at line 1385 of file GaudiTest.py.

Definition at line 1385 of file GaudiTest.py.

Definition at line 1385 of file GaudiTest.py.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Thu Jun 28 2012 12:30:23 for Gaudi Framework, version v23r3 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004