Gaudi Framework, version v23r10

Home   Generated: Mon Sep 30 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | List of all members
GaudiTest.GaudiExeTest Class Reference
Inheritance diagram for GaudiTest.GaudiExeTest:
Inheritance graph
[legend]
Collaboration diagram for GaudiTest.GaudiExeTest:
Collaboration graph
[legend]

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
 
 signal
 

Static Public Attributes

list arguments
 

Private Member Functions

def _expandReferenceFileName
 
def _CreateEclipseLaunch
 

Detailed Description

Standard Gaudi test.

Definition at line 993 of file GaudiTest.py.

Member Function Documentation

def GaudiTest.GaudiExeTest._CreateEclipseLaunch (   self,
  prog,
  args,
  destdir = None 
)
private

Definition at line 1596 of file GaudiTest.py.

1597  def _CreateEclipseLaunch(self, prog, args, destdir = None):
1598  # Find the project name used in ecplise.
1599  # The name is in a file called ".project" in one of the parent directories
1600  projbasedir = os.path.normpath(destdir)
1601  while not os.path.exists(os.path.join(projbasedir, ".project")):
1602  oldprojdir = projbasedir
1603  projbasedir = os.path.normpath(os.path.join(projbasedir, os.pardir))
1604  # FIXME: the root level is invariant when trying to go up one level,
1605  # but it must be cheched on windows
1606  if oldprojdir == projbasedir:
1607  # If we cannot find a .project, so no point in creating a .launch file
1608  return
1609  # Ensure that we have a place where to write.
1610  if not os.path.exists(destdir):
1611  os.makedirs(destdir)
1612  # Use ElementTree to parse the XML file
1613  from xml.etree import ElementTree as ET
1614  t = ET.parse(os.path.join(projbasedir, ".project"))
1615  projectName = t.find("name").text
1616 
1617  # prepare the name/path of the generated file
1618  destfile = "%s.launch" % self._Runnable__id
1619  if destdir:
1620  destfile = os.path.join(destdir, destfile)
1621 
1622  if self.options.strip():
1623  # this means we have some custom options in the qmt file, so we have
1624  # to copy them from the temporary file at the end of the arguments
1625  # in another file
1626  tempfile = args.pop()
1627  optsfile = destfile + os.path.splitext(tempfile)[1]
1628  shutil.copyfile(tempfile, optsfile)
1629  args.append(optsfile)
1630 
1631  # prepare the data to insert in the XML file
1632  from xml.sax.saxutils import quoteattr # useful to quote XML special chars
1633  data = {}
1634  # Note: the "quoteattr(k)" is not needed because special chars cannot be part of a variable name,
1635  # but it doesn't harm.
1636  data["environment"] = "\n".join(['<mapEntry key=%s value=%s/>' % (quoteattr(k), quoteattr(v))
1637  for k, v in os.environ.iteritems()
1638  if k not in ('MAKEOVERRIDES', 'MAKEFLAGS', 'MAKELEVEL')])
1639 
1640  data["exec"] = which(prog) or prog
1641  if os.path.basename(data["exec"]).lower().startswith("python"):
1642  data["stopAtMain"] = "false" # do not stop at main when debugging Python scripts
1643  else:
1644  data["stopAtMain"] = "true"
1645 
1646  data["args"] = "&#10;".join(map(rationalizepath, args))
1647  if self.isWinPlatform():
1648  data["args"] = "&#10;".join(["/debugexe"] + map(rationalizepath, [data["exec"]] + args))
1649  data["exec"] = which("vcexpress.exe")
1650 
1651  if not self.use_temp_dir:
1652  data["workdir"] = os.getcwd()
1653  else:
1654  # If the test is using a tmporary directory, it is better to run it
1655  # in the same directory as the .launch file when debugged in eclipse
1656  data["workdir"] = destdir
1657 
1658  data["project"] = projectName.strip()
1659 
1660  # Template for the XML file, based on eclipse 3.4
1661  xml = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1662 <launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
1663 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB" value="true"/>
1664 <listAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB_LIST"/>
1665 <stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="gdb"/>
1666 <stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=".gdbinit"/>
1667 <listAttribute key="org.eclipse.cdt.debug.mi.core.SOLIB_PATH"/>
1668 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.STOP_ON_SOLIB_EVENTS" value="false"/>
1669 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
1670 <stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="org.eclipse.cdt.debug.mi.core.standardCommandFactory"/>
1671 <stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
1672 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
1673 <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
1674 <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
1675 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="org.eclipse.cdt.debug.mi.core.CDebuggerNew"/>
1676 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
1677 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
1678 <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="%(stopAtMain)s"/>
1679 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
1680 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
1681 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
1682 <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;"/>
1683 <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;"/>
1684 <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;"/>
1685 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="%(args)s"/>
1686 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="%(exec)s"/>
1687 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="%(project)s"/>
1688 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
1689 <stringAttribute key="org.eclipse.cdt.launch.WORKING_DIRECTORY" value="%(workdir)s"/>
1690 <booleanAttribute key="org.eclipse.cdt.launch.ui.ApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
1691 <booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
1692 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
1693 <listEntry value="/%(project)s"/>
1694 </listAttribute>
1695 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
1696 <listEntry value="4"/>
1697 </listAttribute>
1698 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
1699 <mapAttribute key="org.eclipse.debug.core.environmentVariables">
1700 %(environment)s
1701 </mapAttribute>
1702 <mapAttribute key="org.eclipse.debug.core.preferred_launchers">
1703 <mapEntry key="[debug]" value="org.eclipse.cdt.cdi.launch.localCLaunch"/>
1704 </mapAttribute>
1705 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
1706 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
1707 </listAttribute>
1708 </launchConfiguration>
1709 """ % data
1710 
1711  # Write the output file
1712  open(destfile, "w").write(xml)
1713  #open(destfile + "_copy.xml", "w").write(xml)
1714 
1715 
try:
def GaudiTest.GaudiExeTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 1153 of file GaudiTest.py.

1154  def _expandReferenceFileName(self, reffile):
1155  # if no file is passed, do nothing
1156  if not reffile:
1157  return ""
1158 
1159  # function to split an extension in constituents parts
1160  platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
1161 
1162  reference = os.path.normpath(os.path.expandvars(reffile))
1163  # old-style platform-specific reference name
1164  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1165  if os.path.isfile(spec_ref):
1166  reference = spec_ref
1167  else: # look for new-style platform specific reference files:
1168  # get all the files whose name start with the reference filename
1169  dirname, basename = os.path.split(reference)
1170  if not dirname: dirname = '.'
1171  head = basename + "."
1172  head_len = len(head)
1173  platform = platformSplit(self.GetPlatform())
1174  candidates = []
1175  for f in os.listdir(dirname):
1176  if f.startswith(head):
1177  req_plat = platformSplit(f[head_len:])
1178  if platform.issuperset(req_plat):
1179  candidates.append( (len(req_plat), f) )
1180  if candidates: # take the one with highest matching
1181  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1182  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1183  candidates.sort()
1184  reference = os.path.join(dirname, candidates[-1][1])
1185  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 1222 of file GaudiTest.py.

1223  ignore = None):
1224  """
1225  Compare the TTree summaries in stdout with the ones in trees_dict or in
1226  the reference file. By default ignore the size, compression and basket
1227  fields.
1228  The presence of TTree summaries when none is expected is not a failure.
1229  """
1230  if dict is None:
1231  reference = self._expandReferenceFileName(self.reference)
1232  # call the validator if the file exists
1233  if reference and os.path.isfile(reference):
1234  dict = findHistosSummaries(open(reference).read())
1235  else:
1236  dict = {}
1237 
1238  from pprint import PrettyPrinter
1239  pp = PrettyPrinter()
1240  if dict:
1241  result["GaudiTest.Histos.expected"] = result.Quote(pp.pformat(dict))
1242  if ignore:
1243  result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1244 
1245  histos = findHistosSummaries(stdout)
1246  failed = cmpTreesDicts(dict, histos, ignore)
1247  if failed:
1248  causes.append("histos summaries")
1249  msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1250  result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1251  result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1252 
1253  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 1188 of file GaudiTest.py.

1189  ignore = r"Basket|.*size|Compression"):
1190  """
1191  Compare the TTree summaries in stdout with the ones in trees_dict or in
1192  the reference file. By default ignore the size, compression and basket
1193  fields.
1194  The presence of TTree summaries when none is expected is not a failure.
1195  """
1196  if trees_dict is None:
1197  reference = self._expandReferenceFileName(self.reference)
1198  # call the validator if the file exists
1199  if reference and os.path.isfile(reference):
1200  trees_dict = findTTreeSummaries(open(reference).read())
1201  else:
1202  trees_dict = {}
1203 
1204  from pprint import PrettyPrinter
1205  pp = PrettyPrinter()
1206  if trees_dict:
1207  result["GaudiTest.TTrees.expected"] = result.Quote(pp.pformat(trees_dict))
1208  if ignore:
1209  result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1210 
1211  trees = findTTreeSummaries(stdout)
1212  failed = cmpTreesDicts(trees_dict, trees, ignore)
1213  if failed:
1214  causes.append("trees summaries")
1215  msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees, failed)
1216  result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1217  result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1218 
1219  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 1376 of file GaudiTest.py.

1377  def DumpEnvironment(self, result):
1378  """
1379  Add the content of the environment to the result object.
1380 
1381  Copied from the QMTest class of COOL.
1382  """
1383  vars = os.environ.keys()
1384  vars.sort()
1385  result['GaudiTest.environment'] = \
1386  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 1131 of file GaudiTest.py.

1132  def GetPlatform(self):
1133  """
1134  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1135  """
1136  arch = "None"
1137  # check architecture name
1138  if "CMTCONFIG" in os.environ:
1139  arch = os.environ["CMTCONFIG"]
1140  elif "SCRAM_ARCH" in os.environ:
1141  arch = os.environ["SCRAM_ARCH"]
1142  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 1143 of file GaudiTest.py.

1144  def isWinPlatform(self):
1145  """
1146  Return True if the current platform is Windows.
1147 
1148  This function was needed because of the change in the CMTCONFIG format,
1149  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1150  """
1151  platform = self.GetPlatform()
1152  return "winxp" in platform or platform.startswith("win")
def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1117 of file GaudiTest.py.

1118  def PlatformIsNotSupported(self, context, result):
1119  platform = self.GetPlatform()
1120  unsupported = [ re.compile(x)
1121  for x in [ str(y).strip()
1122  for y in self.unsupported_platforms ]
1123  if x
1124  ]
1125  for p_re in unsupported:
1126  if p_re.search(platform):
1127  result.SetOutcome(result.UNTESTED)
1128  result[result.CAUSE] = 'Platform not supported.'
1129  return True
1130  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 1387 of file GaudiTest.py.

1388  def Run(self, context, result):
1389  """Run the test.
1390 
1391  'context' -- A 'Context' giving run-time parameters to the
1392  test.
1393 
1394  'result' -- A 'Result' object. The outcome will be
1395  'Result.PASS' when this method is called. The 'result' may be
1396  modified by this method to indicate outcomes other than
1397  'Result.PASS' or to add annotations."""
1398 
1399  # Check if the platform is supported
1400  if self.PlatformIsNotSupported(context, result):
1401  return
1402 
1403  # Prepare program name and arguments (expanding variables, and converting to absolute)
1404  if self.program:
1405  prog = rationalizepath(self.program)
1406  elif "GAUDIEXE" in os.environ:
1407  prog = os.environ["GAUDIEXE"]
1408  else:
1409  prog = "Gaudi.exe"
1410  self.program = prog
1411 
1412  dummy, prog_ext = os.path.splitext(prog)
1413  if prog_ext not in [ ".exe", ".py", ".bat" ] and self.isWinPlatform():
1414  prog += ".exe"
1415  prog_ext = ".exe"
1416 
1417  prog = which(prog) or prog
1418 
1419  # Convert paths to absolute paths in arguments and reference files
1420  args = map(rationalizepath, self.args)
1423 
1424 
1425  # check if the user provided inline options
1426  tmpfile = None
1427  if self.options.strip():
1428  ext = ".opts"
1429  if re.search(r"from\s+Gaudi.Configuration\s+import\s+\*|from\s+Configurables\s+import", self.options):
1430  ext = ".py"
1431  tmpfile = TempFile(ext)
1432  tmpfile.writelines("\n".join(self.options.splitlines()))
1433  tmpfile.flush()
1434  args.append(tmpfile.name)
1435  result["GaudiTest.options"] = result.Quote(self.options)
1436 
1437  # if the program is a python file, execute it through python
1438  if prog_ext == ".py":
1439  args.insert(0,prog)
1440  if self.isWinPlatform():
1441  prog = which("python.exe") or "python.exe"
1442  else:
1443  prog = which("python") or "python"
1444 
1445  # Change to the working directory if specified or to the default temporary
1446  origdir = os.getcwd()
1447  if self.workdir:
1448  os.chdir(str(os.path.normpath(os.path.expandvars(self.workdir))))
1449  elif self.use_temp_dir == "true":
1450  if "QMTEST_TMPDIR" in os.environ:
1451  qmtest_tmpdir = os.environ["QMTEST_TMPDIR"]
1452  if not os.path.exists(qmtest_tmpdir):
1453  os.makedirs(qmtest_tmpdir)
1454  os.chdir(qmtest_tmpdir)
1455  elif "qmtest.tmpdir" in context:
1456  os.chdir(context["qmtest.tmpdir"])
1457 
1458  if "QMTEST_IGNORE_TIMEOUT" not in os.environ:
1459  self.timeout = max(self.timeout,600)
1460  else:
1461  self.timeout = -1
1462 
1463  try:
1464  # Generate eclipse.org debug launcher for the test
1465  self._CreateEclipseLaunch(prog, args, destdir = os.path.join(origdir, '.eclipse'))
1466  # Run the test
1467  self.RunProgram(prog,
1468  [ prog ] + args,
1469  context, result)
1470  # Record the content of the enfironment for failing tests
1471  if result.GetOutcome() not in [ result.PASS ]:
1472  self.DumpEnvironment(result)
1473  finally:
1474  # revert to the original directory
1475  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 1476 of file GaudiTest.py.

1477  def RunProgram(self, program, arguments, context, result):
1478  """Run the 'program'.
1479 
1480  'program' -- The path to the program to run.
1481 
1482  'arguments' -- A list of the arguments to the program. This
1483  list must contain a first argument corresponding to 'argv[0]'.
1484 
1485  'context' -- A 'Context' giving run-time parameters to the
1486  test.
1487 
1488  'result' -- A 'Result' object. The outcome will be
1489  'Result.PASS' when this method is called. The 'result' may be
1490  modified by this method to indicate outcomes other than
1491  'Result.PASS' or to add annotations.
1492 
1493  @attention: This method has been copied from command.ExecTestBase
1494  (QMTest 2.3.0) and modified to keep stdout and stderr
1495  for tests that have been terminated by a signal.
1496  (Fundamental for debugging in the Application Area)
1497  """
1498 
1499  # Construct the environment.
1500  environment = self.MakeEnvironment(context)
1501  # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
1502  if "slc6" in environment.get('CMTCONFIG', ''):
1503  environment['TERM'] = 'dumb'
1504  # Create the executable.
1505  if self.timeout >= 0:
1506  timeout = self.timeout
1507  else:
1508  # If no timeout was specified, we sill run this process in a
1509  # separate process group and kill the entire process group
1510  # when the child is done executing. That means that
1511  # orphaned child processes created by the test will be
1512  # cleaned up.
1513  timeout = -2
1514  e = GaudiFilterExecutable(self.stdin, timeout)
1515  # Run it.
1516  exit_status = e.Run(arguments, environment, path = program)
1517  # Get the stack trace from the temporary file (if present)
1518  if e.stack_trace_file and os.path.exists(e.stack_trace_file):
1519  stack_trace = open(e.stack_trace_file).read()
1520  os.remove(e.stack_trace_file)
1521  else:
1522  stack_trace = None
1523  if stack_trace:
1524  result["ExecTest.stack_trace"] = result.Quote(stack_trace)
1525 
1526  # If the process terminated normally, check the outputs.
1527  if (sys.platform == "win32" or os.WIFEXITED(exit_status)
1528  or self.signal == os.WTERMSIG(exit_status)):
1529  # There are no causes of failure yet.
1530  causes = []
1531  # The target program terminated normally. Extract the
1532  # exit code, if this test checks it.
1533  if self.exit_code is None:
1534  exit_code = None
1535  elif sys.platform == "win32":
1536  exit_code = exit_status
1537  else:
1538  exit_code = os.WEXITSTATUS(exit_status)
1539  # Get the output generated by the program.
1540  stdout = e.stdout
1541  stderr = e.stderr
1542  # Record the results.
1543  result["ExecTest.exit_code"] = str(exit_code)
1544  result["ExecTest.stdout"] = result.Quote(stdout)
1545  result["ExecTest.stderr"] = result.Quote(stderr)
1546  # Check to see if the exit code matches.
1547  if exit_code != self.exit_code:
1548  causes.append("exit_code")
1549  result["ExecTest.expected_exit_code"] \
1550  = str(self.exit_code)
1551  # Validate the output.
1552  causes += self.ValidateOutput(stdout, stderr, result)
1553  # If anything went wrong, the test failed.
1554  if causes:
1555  result.Fail("Unexpected %s." % string.join(causes, ", "))
1556  elif os.WIFSIGNALED(exit_status):
1557  # The target program terminated with a signal. Construe
1558  # that as a test failure.
1559  signal_number = str(os.WTERMSIG(exit_status))
1560  if not stack_trace:
1561  result.Fail("Program terminated by signal.")
1562  else:
1563  # The presence of stack_trace means tha we stopped the job because
1564  # of a time-out
1565  result.Fail("Exceeded time limit (%ds), terminated." % timeout)
1566  result["ExecTest.signal_number"] = signal_number
1567  result["ExecTest.stdout"] = result.Quote(e.stdout)
1568  result["ExecTest.stderr"] = result.Quote(e.stderr)
1569  if self.signal:
1570  result["ExecTest.expected_signal_number"] = str(self.signal)
1571  elif os.WIFSTOPPED(exit_status):
1572  # The target program was stopped. Construe that as a
1573  # test failure.
1574  signal_number = str(os.WSTOPSIG(exit_status))
1575  if not stack_trace:
1576  result.Fail("Program stopped by signal.")
1577  else:
1578  # The presence of stack_trace means tha we stopped the job because
1579  # of a time-out
1580  result.Fail("Exceeded time limit (%ds), stopped." % timeout)
1581  result["ExecTest.signal_number"] = signal_number
1582  result["ExecTest.stdout"] = result.Quote(e.stdout)
1583  result["ExecTest.stderr"] = result.Quote(e.stderr)
1584  else:
1585  # The target program terminated abnormally in some other
1586  # manner. (This shouldn't normally happen...)
1587  result.Fail("Program did not terminate normally.")
1588 
1589  # Marco Cl.: This is a special trick to fix a "problem" with the output
1590  # of gaudi jobs when they use colors
1591  esc = '\x1b'
1592  repr_esc = '\\x1b'
1593  result["ExecTest.stdout"] = result["ExecTest.stdout"].replace(esc,repr_esc)
1594  # TODO: (MCl) improve the hack for colors in standard output
1595  # may be converting them to HTML tags
def GaudiTest.GaudiExeTest.ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1311 of file GaudiTest.py.

1312  def ValidateOutput(self, stdout, stderr, result):
1313  causes = []
1314  # if the test definition contains a custom validator, use it
1315  if self.validator.strip() != "":
1316  class CallWrapper(object):
1317  """
1318  Small wrapper class to dynamically bind some default arguments
1319  to a callable.
1320  """
1321  def __init__(self, callable, extra_args = {}):
1322  self.callable = callable
1323  self.extra_args = extra_args
1324  # get the list of names of positional arguments
1325  from inspect import getargspec
1326  self.args_order = getargspec(callable)[0]
1327  # Remove "self" from the list of positional arguments
1328  # since it is added automatically
1329  if self.args_order[0] == "self":
1330  del self.args_order[0]
1331  def __call__(self, *args, **kwargs):
1332  # Check which positional arguments are used
1333  positional = self.args_order[:len(args)]
1334 
1335  kwargs = dict(kwargs) # copy the arguments dictionary
1336  for a in self.extra_args:
1337  # use "extra_args" for the arguments not specified as
1338  # positional or keyword
1339  if a not in positional and a not in kwargs:
1340  kwargs[a] = self.extra_args[a]
1341  return apply(self.callable, args, kwargs)
1342  # local names to be exposed in the script
1343  exported_symbols = {"self":self,
1344  "stdout":stdout,
1345  "stderr":stderr,
1346  "result":result,
1347  "causes":causes,
1348  "findReferenceBlock":
1349  CallWrapper(findReferenceBlock, {"stdout":stdout,
1350  "result":result,
1351  "causes":causes}),
1352  "validateWithReference":
1353  CallWrapper(self.ValidateWithReference, {"stdout":stdout,
1354  "stderr":stderr,
1355  "result":result,
1356  "causes":causes}),
1357  "countErrorLines":
1358  CallWrapper(countErrorLines, {"stdout":stdout,
1359  "result":result,
1360  "causes":causes}),
1361  "checkTTreesSummaries":
1362  CallWrapper(self.CheckTTreesSummaries, {"stdout":stdout,
1363  "result":result,
1364  "causes":causes}),
1365  "checkHistosSummaries":
1366  CallWrapper(self.CheckHistosSummaries, {"stdout":stdout,
1367  "result":result,
1368  "causes":causes}),
1369 
1370  }
1371  exec self.validator in globals(), exported_symbols
1372  else:
1373  self.ValidateWithReference(stdout, stderr, result, causes)
1374 
1375  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 1254 of file GaudiTest.py.

1255  def ValidateWithReference(self, stdout, stderr, result, causes, preproc = None):
1256  """
1257  Default validation action: compare standard output and error to the
1258  reference files.
1259  """
1260  # set the default output preprocessor
1261  if preproc is None:
1262  preproc = normalizeExamples
1263  # check standard output
1264  reference = self._expandReferenceFileName(self.reference)
1265  # call the validator if the file exists
1266  if reference and os.path.isfile(reference):
1267  result["GaudiTest.output_reference"] = reference
1268  causes += ReferenceFileValidator(reference,
1269  "standard output",
1270  "GaudiTest.output_diff",
1271  preproc = preproc)(stdout, result)
1272 
1273  # Compare TTree summaries
1274  causes = self.CheckTTreesSummaries(stdout, result, causes)
1275  causes = self.CheckHistosSummaries(stdout, result, causes)
1276 
1277  if causes: # Write a new reference file for stdout
1278  try:
1279  newref = open(reference + ".new","w")
1280  # sanitize newlines
1281  for l in stdout.splitlines():
1282  newref.write(l.rstrip() + '\n')
1283  del newref # flush and close
1284  except IOError:
1285  # Ignore IO errors when trying to update reference files
1286  # because we may be in a read-only filesystem
1287  pass
1288 
1289  # check standard error
1290  reference = self._expandReferenceFileName(self.error_reference)
1291  # call the validator if we have a file to use
1292  if reference and os.path.isfile(reference):
1293  result["GaudiTest.error_reference"] = reference
1294  newcauses = ReferenceFileValidator(reference,
1295  "standard error",
1296  "GaudiTest.error_diff",
1297  preproc = preproc)(stderr, result)
1298  causes += newcauses
1299  if newcauses: # Write a new reference file for stdedd
1300  newref = open(reference + ".new","w")
1301  # sanitize newlines
1302  for l in stderr.splitlines():
1303  newref.write(l.rstrip() + '\n')
1304  del newref # flush and close
1305  else:
1306  causes += BasicOutputValidator(self.stderr,
1307  "standard error",
1308  "ExecTest.expected_stderr")(stderr, result)
1309 
1310  return causes

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1325 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 996 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1321 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1421 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1322 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1409 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1420 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1527 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1458 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1448 of file GaudiTest.py.


The documentation for this class was generated from the following file:
Generated at Mon Sep 30 2013 14:52:08 for Gaudi Framework, version v23r10 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004