Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011
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 975 of file GaudiTest.py.


Member Function Documentation

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

Definition at line 1562 of file GaudiTest.py.

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

Definition at line 1128 of file GaudiTest.py.

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

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

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

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

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

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

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

Definition at line 1092 of file GaudiTest.py.

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

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

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

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

Definition at line 1286 of file GaudiTest.py.

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

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


Member Data Documentation

Definition at line 1289 of file GaudiTest.py.

Definition at line 978 of file GaudiTest.py.

Definition at line 1289 of file GaudiTest.py.

Definition at line 1370 of file GaudiTest.py.

Definition at line 1289 of file GaudiTest.py.

Definition at line 1370 of file GaudiTest.py.

Definition at line 1370 of file GaudiTest.py.

Definition at line 1370 of file GaudiTest.py.

Definition at line 1370 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 Fri Sep 2 2011 16:26:02 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004