Gaudi Framework, version v23r0

Home   Generated: Mon Jan 30 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 979 of file GaudiTest.py.


Member Function Documentation

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

Definition at line 1566 of file GaudiTest.py.

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

Definition at line 1132 of file GaudiTest.py.

01133                                                :
01134         # if no file is passed, do nothing
01135         if not reffile:
01136             return ""
01137 
01138         # function to split an extension in constituents parts
01139         platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
01140 
01141         reference = os.path.normpath(os.path.expandvars(reffile))
01142         # old-style platform-specific reference name
01143         spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
01144         if os.path.isfile(spec_ref):
01145             reference = spec_ref
01146         else: # look for new-style platform specific reference files:
01147             # get all the files whose name start with the reference filename
01148             dirname, basename = os.path.split(reference)
01149             if not dirname: dirname = '.'
01150             head = basename + "."
01151             head_len = len(head)
01152             platform = platformSplit(self.GetPlatform())
01153             candidates = []
01154             for f in os.listdir(dirname):
01155                 if f.startswith(head):
01156                     req_plat = platformSplit(f[head_len:])
01157                     if platform.issuperset(req_plat):
01158                         candidates.append( (len(req_plat), f) )
01159             if candidates: # take the one with highest matching
01160                 # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
01161                 #        has to use ref.x86_64-gcc43 or ref.slc5-dbg
01162                 candidates.sort()
01163                 reference = os.path.join(dirname, candidates[-1][1])
01164         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 1199 of file GaudiTest.py.

01202                                            :
01203         """
01204         Compare the TTree summaries in stdout with the ones in trees_dict or in
01205         the reference file. By default ignore the size, compression and basket
01206         fields.
01207         The presence of TTree summaries when none is expected is not a failure.
01208         """
01209         if dict is None:
01210             reference = self._expandReferenceFileName(self.reference)
01211             # call the validator if the file exists
01212             if reference and os.path.isfile(reference):
01213                 dict = findHistosSummaries(open(reference).read())
01214             else:
01215                 dict = {}
01216 
01217         from pprint import PrettyPrinter
01218         pp = PrettyPrinter()
01219         if dict:
01220             result["GaudiTest.Histos.expected"] = result.Quote(pp.pformat(dict))
01221             if ignore:
01222                 result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
01223 
01224         histos = findHistosSummaries(stdout)
01225         failed = cmpTreesDicts(dict, histos, ignore)
01226         if failed:
01227             causes.append("histos summaries")
01228             msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
01229             result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
01230             result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
01231 
01232         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 1165 of file GaudiTest.py.

01168                                                                    :
01169         """
01170         Compare the TTree summaries in stdout with the ones in trees_dict or in
01171         the reference file. By default ignore the size, compression and basket
01172         fields.
01173         The presence of TTree summaries when none is expected is not a failure.
01174         """
01175         if trees_dict is None:
01176             reference = self._expandReferenceFileName(self.reference)
01177             # call the validator if the file exists
01178             if reference and os.path.isfile(reference):
01179                 trees_dict = findTTreeSummaries(open(reference).read())
01180             else:
01181                 trees_dict = {}
01182 
01183         from pprint import PrettyPrinter
01184         pp = PrettyPrinter()
01185         if trees_dict:
01186             result["GaudiTest.TTrees.expected"] = result.Quote(pp.pformat(trees_dict))
01187             if ignore:
01188                 result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
01189 
01190         trees = findTTreeSummaries(stdout)
01191         failed = cmpTreesDicts(trees_dict, trees, ignore)
01192         if failed:
01193             causes.append("trees summaries")
01194             msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees, failed)
01195             result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
01196             result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
01197 
01198         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 1355 of file GaudiTest.py.

01356                                      :
01357         """
01358         Add the content of the environment to the result object.
01359 
01360         Copied from the QMTest class of COOL.
01361         """
01362         vars = os.environ.keys()
01363         vars.sort()
01364         result['GaudiTest.environment'] = \
01365             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 1110 of file GaudiTest.py.

01111                          :
01112         """
01113         Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
01114         """
01115         arch = "None"
01116         # check architecture name
01117         if "CMTCONFIG" in os.environ:
01118             arch = os.environ["CMTCONFIG"]
01119         elif "SCRAM_ARCH" in os.environ:
01120             arch = os.environ["SCRAM_ARCH"]
01121         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 1122 of file GaudiTest.py.

01123                            :
01124         """
01125         Return True if the current platform is Windows.
01126 
01127         This function was needed because of the change in the CMTCONFIG format,
01128         from win32_vc71_dbg to i686-winxp-vc9-dbg.
01129         """
01130         platform = self.GetPlatform()
01131         return "winxp" in platform or platform.startswith("win")

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

Definition at line 1096 of file GaudiTest.py.

01097                                                      :
01098         platform = self.GetPlatform()
01099         unsupported = [ re.compile(x)
01100                         for x in [ str(y).strip()
01101                                    for y in self.unsupported_platforms ]
01102                         if x
01103                        ]
01104         for p_re in unsupported:
01105             if p_re.search(platform):
01106                 result.SetOutcome(result.UNTESTED)
01107                 result[result.CAUSE] = 'Platform not supported.'
01108                 return True
01109         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 1366 of file GaudiTest.py.

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

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

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

Definition at line 1290 of file GaudiTest.py.

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

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


Member Data Documentation

Definition at line 1293 of file GaudiTest.py.

Definition at line 982 of file GaudiTest.py.

Definition at line 1293 of file GaudiTest.py.

Definition at line 1374 of file GaudiTest.py.

Definition at line 1293 of file GaudiTest.py.

Definition at line 1374 of file GaudiTest.py.

Definition at line 1374 of file GaudiTest.py.

Definition at line 1374 of file GaudiTest.py.

Definition at line 1374 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 Jan 30 2012 13:53:34 for Gaudi Framework, version v23r0 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004