Gaudi Framework, version v25r2

Home   Generated: Wed Jun 4 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 1060 of file GaudiTest.py.

Member Function Documentation

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

Definition at line 1663 of file GaudiTest.py.

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

Definition at line 1220 of file GaudiTest.py.

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

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

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

1444  def DumpEnvironment(self, result):
1445  """
1446  Add the content of the environment to the result object.
1447 
1448  Copied from the QMTest class of COOL.
1449  """
1450  vars = os.environ.keys()
1451  vars.sort()
1452  result['GaudiTest.environment'] = \
1453  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 1198 of file GaudiTest.py.

1199  def GetPlatform(self):
1200  """
1201  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1202  """
1203  arch = "None"
1204  # check architecture name
1205  if "CMTCONFIG" in os.environ:
1206  arch = os.environ["CMTCONFIG"]
1207  elif "SCRAM_ARCH" in os.environ:
1208  arch = os.environ["SCRAM_ARCH"]
1209  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 1210 of file GaudiTest.py.

1211  def isWinPlatform(self):
1212  """
1213  Return True if the current platform is Windows.
1214 
1215  This function was needed because of the change in the CMTCONFIG format,
1216  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1217  """
1218  platform = self.GetPlatform()
1219  return "winxp" in platform or platform.startswith("win")
def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1184 of file GaudiTest.py.

1185  def PlatformIsNotSupported(self, context, result):
1186  platform = self.GetPlatform()
1187  unsupported = [ re.compile(x)
1188  for x in [ str(y).strip()
1189  for y in self.unsupported_platforms ]
1190  if x
1191  ]
1192  for p_re in unsupported:
1193  if p_re.search(platform):
1194  result.SetOutcome(result.UNTESTED)
1195  result[result.CAUSE] = 'Platform not supported.'
1196  return True
1197  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 1454 of file GaudiTest.py.

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

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

Definition at line 1378 of file GaudiTest.py.

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

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

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1392 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1063 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1388 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1488 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1389 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1476 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1487 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1594 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1525 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1515 of file GaudiTest.py.


The documentation for this class was generated from the following file:
Generated at Wed Jun 4 2014 14:49:06 for Gaudi Framework, version v25r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004