Gaudi Framework, version v25r1

Home   Generated: Mon Mar 24 2014
 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 1049 of file GaudiTest.py.

Member Function Documentation

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

Definition at line 1652 of file GaudiTest.py.

1653  def _CreateEclipseLaunch(self, prog, args, destdir = None):
1654  # Find the project name used in ecplise.
1655  # The name is in a file called ".project" in one of the parent directories
1656  projbasedir = os.path.normpath(destdir)
1657  while not os.path.exists(os.path.join(projbasedir, ".project")):
1658  oldprojdir = projbasedir
1659  projbasedir = os.path.normpath(os.path.join(projbasedir, os.pardir))
1660  # FIXME: the root level is invariant when trying to go up one level,
1661  # but it must be cheched on windows
1662  if oldprojdir == projbasedir:
1663  # If we cannot find a .project, so no point in creating a .launch file
1664  return
1665  # Ensure that we have a place where to write.
1666  if not os.path.exists(destdir):
1667  os.makedirs(destdir)
1668  # Use ElementTree to parse the XML file
1669  from xml.etree import ElementTree as ET
1670  t = ET.parse(os.path.join(projbasedir, ".project"))
1671  projectName = t.find("name").text
1672 
1673  # prepare the name/path of the generated file
1674  destfile = "%s.launch" % self._Runnable__id
1675  if destdir:
1676  destfile = os.path.join(destdir, destfile)
1677 
1678  if self.options.strip():
1679  # this means we have some custom options in the qmt file, so we have
1680  # to copy them from the temporary file at the end of the arguments
1681  # in another file
1682  tempfile = args.pop()
1683  optsfile = destfile + os.path.splitext(tempfile)[1]
1684  shutil.copyfile(tempfile, optsfile)
1685  args.append(optsfile)
1686 
1687  # prepare the data to insert in the XML file
1688  from xml.sax.saxutils import quoteattr # useful to quote XML special chars
1689  data = {}
1690  # Note: the "quoteattr(k)" is not needed because special chars cannot be part of a variable name,
1691  # but it doesn't harm.
1692  data["environment"] = "\n".join(['<mapEntry key=%s value=%s/>' % (quoteattr(k), quoteattr(v))
1693  for k, v in os.environ.iteritems()
1694  if k not in ('MAKEOVERRIDES', 'MAKEFLAGS', 'MAKELEVEL')])
1695 
1696  data["exec"] = which(prog) or prog
1697  if os.path.basename(data["exec"]).lower().startswith("python"):
1698  data["stopAtMain"] = "false" # do not stop at main when debugging Python scripts
1699  else:
1700  data["stopAtMain"] = "true"
1701 
1702  data["args"] = "&#10;".join(map(rationalizepath, args))
1703  if self.isWinPlatform():
1704  data["args"] = "&#10;".join(["/debugexe"] + map(rationalizepath, [data["exec"]] + args))
1705  data["exec"] = which("vcexpress.exe")
1706 
1707  if not self.use_temp_dir:
1708  data["workdir"] = os.getcwd()
1709  else:
1710  # If the test is using a tmporary directory, it is better to run it
1711  # in the same directory as the .launch file when debugged in eclipse
1712  data["workdir"] = destdir
1713 
1714  data["project"] = projectName.strip()
1715 
1716  # Template for the XML file, based on eclipse 3.4
1717  xml = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1718 <launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
1719 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB" value="true"/>
1720 <listAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB_LIST"/>
1721 <stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="gdb"/>
1722 <stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=".gdbinit"/>
1723 <listAttribute key="org.eclipse.cdt.debug.mi.core.SOLIB_PATH"/>
1724 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.STOP_ON_SOLIB_EVENTS" value="false"/>
1725 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
1726 <stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="org.eclipse.cdt.debug.mi.core.standardCommandFactory"/>
1727 <stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
1728 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
1729 <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
1730 <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
1731 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="org.eclipse.cdt.debug.mi.core.CDebuggerNew"/>
1732 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
1733 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
1734 <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="%(stopAtMain)s"/>
1735 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
1736 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
1737 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
1738 <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;"/>
1739 <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;"/>
1740 <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;"/>
1741 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="%(args)s"/>
1742 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="%(exec)s"/>
1743 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="%(project)s"/>
1744 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
1745 <stringAttribute key="org.eclipse.cdt.launch.WORKING_DIRECTORY" value="%(workdir)s"/>
1746 <booleanAttribute key="org.eclipse.cdt.launch.ui.ApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
1747 <booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
1748 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
1749 <listEntry value="/%(project)s"/>
1750 </listAttribute>
1751 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
1752 <listEntry value="4"/>
1753 </listAttribute>
1754 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
1755 <mapAttribute key="org.eclipse.debug.core.environmentVariables">
1756 %(environment)s
1757 </mapAttribute>
1758 <mapAttribute key="org.eclipse.debug.core.preferred_launchers">
1759 <mapEntry key="[debug]" value="org.eclipse.cdt.cdi.launch.localCLaunch"/>
1760 </mapAttribute>
1761 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
1762 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
1763 </listAttribute>
1764 </launchConfiguration>
1765 """ % data
1766 
1767  # Write the output file
1768  open(destfile, "w").write(xml)
1769  #open(destfile + "_copy.xml", "w").write(xml)
1770 
1771 
try:
def GaudiTest.GaudiExeTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 1209 of file GaudiTest.py.

1210  def _expandReferenceFileName(self, reffile):
1211  # if no file is passed, do nothing
1212  if not reffile:
1213  return ""
1214 
1215  # function to split an extension in constituents parts
1216  platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
1217 
1218  reference = os.path.normpath(os.path.expandvars(reffile))
1219  # old-style platform-specific reference name
1220  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1221  if os.path.isfile(spec_ref):
1222  reference = spec_ref
1223  else: # look for new-style platform specific reference files:
1224  # get all the files whose name start with the reference filename
1225  dirname, basename = os.path.split(reference)
1226  if not dirname: dirname = '.'
1227  head = basename + "."
1228  head_len = len(head)
1229  platform = platformSplit(self.GetPlatform())
1230  candidates = []
1231  for f in os.listdir(dirname):
1232  if f.startswith(head):
1233  req_plat = platformSplit(f[head_len:])
1234  if platform.issuperset(req_plat):
1235  candidates.append( (len(req_plat), f) )
1236  if candidates: # take the one with highest matching
1237  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1238  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1239  candidates.sort()
1240  reference = os.path.join(dirname, candidates[-1][1])
1241  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 1278 of file GaudiTest.py.

1279  ignore = None):
1280  """
1281  Compare the TTree summaries in stdout with the ones in trees_dict or in
1282  the reference file. By default ignore the size, compression and basket
1283  fields.
1284  The presence of TTree summaries when none is expected is not a failure.
1285  """
1286  if dict is None:
1287  reference = self._expandReferenceFileName(self.reference)
1288  # call the validator if the file exists
1289  if reference and os.path.isfile(reference):
1290  dict = findHistosSummaries(open(reference).read())
1291  else:
1292  dict = {}
1293 
1294  from pprint import PrettyPrinter
1295  pp = PrettyPrinter()
1296  if dict:
1297  result["GaudiTest.Histos.expected"] = result.Quote(pp.pformat(dict))
1298  if ignore:
1299  result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1300 
1301  histos = findHistosSummaries(stdout)
1302  failed = cmpTreesDicts(dict, histos, ignore)
1303  if failed:
1304  causes.append("histos summaries")
1305  msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1306  result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1307  result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1308 
1309  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 1244 of file GaudiTest.py.

1245  ignore = r"Basket|.*size|Compression"):
1246  """
1247  Compare the TTree summaries in stdout with the ones in trees_dict or in
1248  the reference file. By default ignore the size, compression and basket
1249  fields.
1250  The presence of TTree summaries when none is expected is not a failure.
1251  """
1252  if trees_dict is None:
1253  reference = self._expandReferenceFileName(self.reference)
1254  # call the validator if the file exists
1255  if reference and os.path.isfile(reference):
1256  trees_dict = findTTreeSummaries(open(reference).read())
1257  else:
1258  trees_dict = {}
1259 
1260  from pprint import PrettyPrinter
1261  pp = PrettyPrinter()
1262  if trees_dict:
1263  result["GaudiTest.TTrees.expected"] = result.Quote(pp.pformat(trees_dict))
1264  if ignore:
1265  result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1266 
1267  trees = findTTreeSummaries(stdout)
1268  failed = cmpTreesDicts(trees_dict, trees, ignore)
1269  if failed:
1270  causes.append("trees summaries")
1271  msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees, failed)
1272  result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1273  result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1274 
1275  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 1432 of file GaudiTest.py.

1433  def DumpEnvironment(self, result):
1434  """
1435  Add the content of the environment to the result object.
1436 
1437  Copied from the QMTest class of COOL.
1438  """
1439  vars = os.environ.keys()
1440  vars.sort()
1441  result['GaudiTest.environment'] = \
1442  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 1187 of file GaudiTest.py.

1188  def GetPlatform(self):
1189  """
1190  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1191  """
1192  arch = "None"
1193  # check architecture name
1194  if "CMTCONFIG" in os.environ:
1195  arch = os.environ["CMTCONFIG"]
1196  elif "SCRAM_ARCH" in os.environ:
1197  arch = os.environ["SCRAM_ARCH"]
1198  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 1199 of file GaudiTest.py.

1200  def isWinPlatform(self):
1201  """
1202  Return True if the current platform is Windows.
1203 
1204  This function was needed because of the change in the CMTCONFIG format,
1205  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1206  """
1207  platform = self.GetPlatform()
1208  return "winxp" in platform or platform.startswith("win")
def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1173 of file GaudiTest.py.

1174  def PlatformIsNotSupported(self, context, result):
1175  platform = self.GetPlatform()
1176  unsupported = [ re.compile(x)
1177  for x in [ str(y).strip()
1178  for y in self.unsupported_platforms ]
1179  if x
1180  ]
1181  for p_re in unsupported:
1182  if p_re.search(platform):
1183  result.SetOutcome(result.UNTESTED)
1184  result[result.CAUSE] = 'Platform not supported.'
1185  return True
1186  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 1443 of file GaudiTest.py.

1444  def Run(self, context, result):
1445  """Run the test.
1446 
1447  'context' -- A 'Context' giving run-time parameters to the
1448  test.
1449 
1450  'result' -- A 'Result' object. The outcome will be
1451  'Result.PASS' when this method is called. The 'result' may be
1452  modified by this method to indicate outcomes other than
1453  'Result.PASS' or to add annotations."""
1454 
1455  # Check if the platform is supported
1456  if self.PlatformIsNotSupported(context, result):
1457  return
1458 
1459  # Prepare program name and arguments (expanding variables, and converting to absolute)
1460  if self.program:
1461  prog = rationalizepath(self.program)
1462  elif "GAUDIEXE" in os.environ:
1463  prog = os.environ["GAUDIEXE"]
1464  else:
1465  prog = "Gaudi.exe"
1466  self.program = prog
1467 
1468  dummy, prog_ext = os.path.splitext(prog)
1469  if prog_ext not in [ ".exe", ".py", ".bat" ] and self.isWinPlatform():
1470  prog += ".exe"
1471  prog_ext = ".exe"
1472 
1473  prog = which(prog) or prog
1474 
1475  # Convert paths to absolute paths in arguments and reference files
1476  args = map(rationalizepath, self.args)
1479 
1480 
1481  # check if the user provided inline options
1482  tmpfile = None
1483  if self.options.strip():
1484  ext = ".opts"
1485  if re.search(r"from\s+Gaudi.Configuration\s+import\s+\*|from\s+Configurables\s+import", self.options):
1486  ext = ".py"
1487  tmpfile = TempFile(ext)
1488  tmpfile.writelines("\n".join(self.options.splitlines()))
1489  tmpfile.flush()
1490  args.append(tmpfile.name)
1491  result["GaudiTest.options"] = result.Quote(self.options)
1492 
1493  # if the program is a python file, execute it through python
1494  if prog_ext == ".py":
1495  args.insert(0,prog)
1496  if self.isWinPlatform():
1497  prog = which("python.exe") or "python.exe"
1498  else:
1499  prog = which("python") or "python"
1500 
1501  # Change to the working directory if specified or to the default temporary
1502  origdir = os.getcwd()
1503  if self.workdir:
1504  os.chdir(str(os.path.normpath(os.path.expandvars(self.workdir))))
1505  elif self.use_temp_dir == "true":
1506  if "QMTEST_TMPDIR" in os.environ:
1507  qmtest_tmpdir = os.environ["QMTEST_TMPDIR"]
1508  if not os.path.exists(qmtest_tmpdir):
1509  os.makedirs(qmtest_tmpdir)
1510  os.chdir(qmtest_tmpdir)
1511  elif "qmtest.tmpdir" in context:
1512  os.chdir(context["qmtest.tmpdir"])
1513 
1514  if "QMTEST_IGNORE_TIMEOUT" not in os.environ:
1515  self.timeout = max(self.timeout,600)
1516  else:
1517  self.timeout = -1
1518 
1519  try:
1520  # Generate eclipse.org debug launcher for the test
1521  self._CreateEclipseLaunch(prog, args, destdir = os.path.join(origdir, '.eclipse'))
1522  # Run the test
1523  self.RunProgram(prog,
1524  [ prog ] + args,
1525  context, result)
1526  # Record the content of the enfironment for failing tests
1527  if result.GetOutcome() not in [ result.PASS ]:
1528  self.DumpEnvironment(result)
1529  finally:
1530  # revert to the original directory
1531  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 1532 of file GaudiTest.py.

1533  def RunProgram(self, program, arguments, context, result):
1534  """Run the 'program'.
1535 
1536  'program' -- The path to the program to run.
1537 
1538  'arguments' -- A list of the arguments to the program. This
1539  list must contain a first argument corresponding to 'argv[0]'.
1540 
1541  'context' -- A 'Context' giving run-time parameters to the
1542  test.
1543 
1544  'result' -- A 'Result' object. The outcome will be
1545  'Result.PASS' when this method is called. The 'result' may be
1546  modified by this method to indicate outcomes other than
1547  'Result.PASS' or to add annotations.
1548 
1549  @attention: This method has been copied from command.ExecTestBase
1550  (QMTest 2.3.0) and modified to keep stdout and stderr
1551  for tests that have been terminated by a signal.
1552  (Fundamental for debugging in the Application Area)
1553  """
1554 
1555  # Construct the environment.
1556  environment = self.MakeEnvironment(context)
1557  # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
1558  if "slc6" in environment.get('CMTCONFIG', ''):
1559  environment['TERM'] = 'dumb'
1560  # Create the executable.
1561  if self.timeout >= 0:
1562  timeout = self.timeout
1563  else:
1564  # If no timeout was specified, we sill run this process in a
1565  # separate process group and kill the entire process group
1566  # when the child is done executing. That means that
1567  # orphaned child processes created by the test will be
1568  # cleaned up.
1569  timeout = -2
1570  e = GaudiFilterExecutable(self.stdin, timeout)
1571  # Run it.
1572  exit_status = e.Run(arguments, environment, path = program)
1573  # Get the stack trace from the temporary file (if present)
1574  if e.stack_trace_file and os.path.exists(e.stack_trace_file):
1575  stack_trace = open(e.stack_trace_file).read()
1576  os.remove(e.stack_trace_file)
1577  else:
1578  stack_trace = None
1579  if stack_trace:
1580  result["ExecTest.stack_trace"] = result.Quote(stack_trace)
1581 
1582  # If the process terminated normally, check the outputs.
1583  if (sys.platform == "win32" or os.WIFEXITED(exit_status)
1584  or self.signal == os.WTERMSIG(exit_status)):
1585  # There are no causes of failure yet.
1586  causes = []
1587  # The target program terminated normally. Extract the
1588  # exit code, if this test checks it.
1589  if self.exit_code is None:
1590  exit_code = None
1591  elif sys.platform == "win32":
1592  exit_code = exit_status
1593  else:
1594  exit_code = os.WEXITSTATUS(exit_status)
1595  # Get the output generated by the program.
1596  stdout = e.stdout
1597  stderr = e.stderr
1598  # Record the results.
1599  result["ExecTest.exit_code"] = str(exit_code)
1600  result["ExecTest.stdout"] = result.Quote(stdout)
1601  result["ExecTest.stderr"] = result.Quote(stderr)
1602  # Check to see if the exit code matches.
1603  if exit_code != self.exit_code:
1604  causes.append("exit_code")
1605  result["ExecTest.expected_exit_code"] \
1606  = str(self.exit_code)
1607  # Validate the output.
1608  causes += self.ValidateOutput(stdout, stderr, result)
1609  # If anything went wrong, the test failed.
1610  if causes:
1611  result.Fail("Unexpected %s." % string.join(causes, ", "))
1612  elif os.WIFSIGNALED(exit_status):
1613  # The target program terminated with a signal. Construe
1614  # that as a test failure.
1615  signal_number = str(os.WTERMSIG(exit_status))
1616  if not stack_trace:
1617  result.Fail("Program terminated by signal.")
1618  else:
1619  # The presence of stack_trace means tha we stopped the job because
1620  # of a time-out
1621  result.Fail("Exceeded time limit (%ds), terminated." % timeout)
1622  result["ExecTest.signal_number"] = signal_number
1623  result["ExecTest.stdout"] = result.Quote(e.stdout)
1624  result["ExecTest.stderr"] = result.Quote(e.stderr)
1625  if self.signal:
1626  result["ExecTest.expected_signal_number"] = str(self.signal)
1627  elif os.WIFSTOPPED(exit_status):
1628  # The target program was stopped. Construe that as a
1629  # test failure.
1630  signal_number = str(os.WSTOPSIG(exit_status))
1631  if not stack_trace:
1632  result.Fail("Program stopped by signal.")
1633  else:
1634  # The presence of stack_trace means tha we stopped the job because
1635  # of a time-out
1636  result.Fail("Exceeded time limit (%ds), stopped." % timeout)
1637  result["ExecTest.signal_number"] = signal_number
1638  result["ExecTest.stdout"] = result.Quote(e.stdout)
1639  result["ExecTest.stderr"] = result.Quote(e.stderr)
1640  else:
1641  # The target program terminated abnormally in some other
1642  # manner. (This shouldn't normally happen...)
1643  result.Fail("Program did not terminate normally.")
1644 
1645  # Marco Cl.: This is a special trick to fix a "problem" with the output
1646  # of gaudi jobs when they use colors
1647  esc = '\x1b'
1648  repr_esc = '\\x1b'
1649  result["ExecTest.stdout"] = result["ExecTest.stdout"].replace(esc,repr_esc)
1650  # TODO: (MCl) improve the hack for colors in standard output
1651  # may be converting them to HTML tags
def GaudiTest.GaudiExeTest.ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1367 of file GaudiTest.py.

1368  def ValidateOutput(self, stdout, stderr, result):
1369  causes = []
1370  # if the test definition contains a custom validator, use it
1371  if self.validator.strip() != "":
1372  class CallWrapper(object):
1373  """
1374  Small wrapper class to dynamically bind some default arguments
1375  to a callable.
1376  """
1377  def __init__(self, callable, extra_args = {}):
1378  self.callable = callable
1379  self.extra_args = extra_args
1380  # get the list of names of positional arguments
1381  from inspect import getargspec
1382  self.args_order = getargspec(callable)[0]
1383  # Remove "self" from the list of positional arguments
1384  # since it is added automatically
1385  if self.args_order[0] == "self":
1386  del self.args_order[0]
1387  def __call__(self, *args, **kwargs):
1388  # Check which positional arguments are used
1389  positional = self.args_order[:len(args)]
1390 
1391  kwargs = dict(kwargs) # copy the arguments dictionary
1392  for a in self.extra_args:
1393  # use "extra_args" for the arguments not specified as
1394  # positional or keyword
1395  if a not in positional and a not in kwargs:
1396  kwargs[a] = self.extra_args[a]
1397  return apply(self.callable, args, kwargs)
1398  # local names to be exposed in the script
1399  exported_symbols = {"self":self,
1400  "stdout":stdout,
1401  "stderr":stderr,
1402  "result":result,
1403  "causes":causes,
1404  "findReferenceBlock":
1405  CallWrapper(findReferenceBlock, {"stdout":stdout,
1406  "result":result,
1407  "causes":causes}),
1408  "validateWithReference":
1409  CallWrapper(self.ValidateWithReference, {"stdout":stdout,
1410  "stderr":stderr,
1411  "result":result,
1412  "causes":causes}),
1413  "countErrorLines":
1414  CallWrapper(countErrorLines, {"stdout":stdout,
1415  "result":result,
1416  "causes":causes}),
1417  "checkTTreesSummaries":
1418  CallWrapper(self.CheckTTreesSummaries, {"stdout":stdout,
1419  "result":result,
1420  "causes":causes}),
1421  "checkHistosSummaries":
1422  CallWrapper(self.CheckHistosSummaries, {"stdout":stdout,
1423  "result":result,
1424  "causes":causes}),
1425 
1426  }
1427  exec self.validator in globals(), exported_symbols
1428  else:
1429  self.ValidateWithReference(stdout, stderr, result, causes)
1430 
1431  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 1310 of file GaudiTest.py.

1311  def ValidateWithReference(self, stdout, stderr, result, causes, preproc = None):
1312  """
1313  Default validation action: compare standard output and error to the
1314  reference files.
1315  """
1316  # set the default output preprocessor
1317  if preproc is None:
1318  preproc = normalizeExamples
1319  # check standard output
1320  reference = self._expandReferenceFileName(self.reference)
1321  # call the validator if the file exists
1322  if reference and os.path.isfile(reference):
1323  result["GaudiTest.output_reference"] = reference
1324  causes += ReferenceFileValidator(reference,
1325  "standard output",
1326  "GaudiTest.output_diff",
1327  preproc = preproc)(stdout, result)
1328 
1329  # Compare TTree summaries
1330  causes = self.CheckTTreesSummaries(stdout, result, causes)
1331  causes = self.CheckHistosSummaries(stdout, result, causes)
1332 
1333  if causes: # Write a new reference file for stdout
1334  try:
1335  newref = open(reference + ".new","w")
1336  # sanitize newlines
1337  for l in stdout.splitlines():
1338  newref.write(l.rstrip() + '\n')
1339  del newref # flush and close
1340  except IOError:
1341  # Ignore IO errors when trying to update reference files
1342  # because we may be in a read-only filesystem
1343  pass
1344 
1345  # check standard error
1346  reference = self._expandReferenceFileName(self.error_reference)
1347  # call the validator if we have a file to use
1348  if reference and os.path.isfile(reference):
1349  result["GaudiTest.error_reference"] = reference
1350  newcauses = ReferenceFileValidator(reference,
1351  "standard error",
1352  "GaudiTest.error_diff",
1353  preproc = preproc)(stderr, result)
1354  causes += newcauses
1355  if newcauses: # Write a new reference file for stdedd
1356  newref = open(reference + ".new","w")
1357  # sanitize newlines
1358  for l in stderr.splitlines():
1359  newref.write(l.rstrip() + '\n')
1360  del newref # flush and close
1361  else:
1362  causes += BasicOutputValidator(self.stderr,
1363  "standard error",
1364  "ExecTest.expected_stderr")(stderr, result)
1365 
1366  return causes

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1381 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1052 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1377 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1477 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1378 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1465 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1476 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1583 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1514 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1504 of file GaudiTest.py.


The documentation for this class was generated from the following file:
Generated at Mon Mar 24 2014 18:27:53 for Gaudi Framework, version v25r1 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004