Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 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 1583 of file GaudiTest.py.

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

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