The Gaudi Framework  v30r3 (a5ef0a68)
GaudiTest.GaudiExeTest Class Reference
Inheritance diagram for GaudiTest.GaudiExeTest:
Collaboration diagram for GaudiTest.GaudiExeTest:

Public Member Functions

def PlatformIsNotSupported (self, context, result)
 
def GetPlatform (self)
 
def isWinPlatform (self)
 
def CheckTTreesSummaries (self, stdout, result, causes, trees_dict=None, ignore=r"Basket|.*size|Compression")
 
def CheckHistosSummaries (self, stdout, result, causes, dict=None, ignore=None)
 
def ValidateWithReference (self, stdout, stderr, result, causes, preproc=None)
 
def ValidateOutput (self, stdout, stderr, result)
 
def DumpEnvironment (self, result)
 
def Run (self, context, result)
 
def RunProgram (self, program, arguments, context, result)
 

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 (self, reffile)
 
def _CreateEclipseLaunch (self, prog, args, destdir=None)
 

Detailed Description

Standard Gaudi test.

Definition at line 1151 of file GaudiTest.py.

Member Function Documentation

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

Definition at line 1764 of file GaudiTest.py.

1764  def _CreateEclipseLaunch(self, prog, args, destdir=None):
1765  if 'NO_ECLIPSE_LAUNCHERS' in os.environ:
1766  # do not generate eclipse launchers if the user asks so
1767  return
1768  # Find the project name used in ecplise.
1769  # The name is in a file called ".project" in one of the parent directories
1770  projbasedir = os.path.normpath(destdir)
1771  while not os.path.exists(os.path.join(projbasedir, ".project")):
1772  oldprojdir = projbasedir
1773  projbasedir = os.path.normpath(
1774  os.path.join(projbasedir, os.pardir))
1775  # FIXME: the root level is invariant when trying to go up one level,
1776  # but it must be cheched on windows
1777  if oldprojdir == projbasedir:
1778  # If we cannot find a .project, so no point in creating a .launch file
1779  return
1780  # Ensure that we have a place where to write.
1781  if not os.path.exists(destdir):
1782  os.makedirs(destdir)
1783  # Use ElementTree to parse the XML file
1784  from xml.etree import ElementTree as ET
1785  t = ET.parse(os.path.join(projbasedir, ".project"))
1786  projectName = t.find("name").text
1787 
1788  # prepare the name/path of the generated file
1789  destfile = "%s.launch" % self._Runnable__id
1790  if destdir:
1791  destfile = os.path.join(destdir, destfile)
1792 
1793  if self.options.strip():
1794  # this means we have some custom options in the qmt file, so we have
1795  # to copy them from the temporary file at the end of the arguments
1796  # in another file
1797  tempfile = args.pop()
1798  optsfile = destfile + os.path.splitext(tempfile)[1]
1799  shutil.copyfile(tempfile, optsfile)
1800  args.append(optsfile)
1801 
1802  # prepare the data to insert in the XML file
1803  from xml.sax.saxutils import quoteattr # useful to quote XML special chars
1804  data = {}
1805  # Note: the "quoteattr(k)" is not needed because special chars cannot be part of a variable name,
1806  # but it doesn't harm.
1807  data["environment"] = "\n".join(['<mapEntry key=%s value=%s/>' % (quoteattr(k), quoteattr(v))
1808  for k, v in os.environ.iteritems()
1809  if k not in ('MAKEOVERRIDES', 'MAKEFLAGS', 'MAKELEVEL')])
1810 
1811  data["exec"] = which(prog) or prog
1812  if os.path.basename(data["exec"]).lower().startswith("python"):
1813  # do not stop at main when debugging Python scripts
1814  data["stopAtMain"] = "false"
1815  else:
1816  data["stopAtMain"] = "true"
1817 
1818  data["args"] = "&#10;".join(map(rationalizepath, args))
1819  if self.isWinPlatform():
1820  data["args"] = "&#10;".join(
1821  ["/debugexe"] + map(rationalizepath, [data["exec"]] + args))
1822  data["exec"] = which("vcexpress.exe")
1823 
1824  if not self.use_temp_dir:
1825  data["workdir"] = os.getcwd()
1826  else:
1827  # If the test is using a tmporary directory, it is better to run it
1828  # in the same directory as the .launch file when debugged in eclipse
1829  data["workdir"] = destdir
1830 
1831  data["project"] = projectName.strip()
1832 
1833  # Template for the XML file, based on eclipse 3.4
1834  xml_template = u"""<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1835 <launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
1836 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB" value="true"/>
1837 <listAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB_LIST"/>
1838 <stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="gdb"/>
1839 <stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=".gdbinit"/>
1840 <listAttribute key="org.eclipse.cdt.debug.mi.core.SOLIB_PATH"/>
1841 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.STOP_ON_SOLIB_EVENTS" value="false"/>
1842 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
1843 <stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="org.eclipse.cdt.debug.mi.core.standardCommandFactory"/>
1844 <stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
1845 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
1846 <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
1847 <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
1848 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="org.eclipse.cdt.debug.mi.core.CDebuggerNew"/>
1849 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
1850 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
1851 <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="%(stopAtMain)s"/>
1852 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
1853 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
1854 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
1855 <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;"/>
1856 <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;"/>
1857 <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;"/>
1858 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="%(args)s"/>
1859 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="%(exec)s"/>
1860 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="%(project)s"/>
1861 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
1862 <stringAttribute key="org.eclipse.cdt.launch.WORKING_DIRECTORY" value="%(workdir)s"/>
1863 <booleanAttribute key="org.eclipse.cdt.launch.ui.ApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
1864 <booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
1865 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
1866 <listEntry value="/%(project)s"/>
1867 </listAttribute>
1868 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
1869 <listEntry value="4"/>
1870 </listAttribute>
1871 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
1872 <mapAttribute key="org.eclipse.debug.core.environmentVariables">
1873 %(environment)s
1874 </mapAttribute>
1875 <mapAttribute key="org.eclipse.debug.core.preferred_launchers">
1876 <mapEntry key="[debug]" value="org.eclipse.cdt.cdi.launch.localCLaunch"/>
1877 </mapAttribute>
1878 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
1879 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
1880 </listAttribute>
1881 </launchConfiguration>
1882 """
1883  try:
1884  # ensure the correct encoding of data values
1885  for k in data:
1886  data[k] = codecs.decode(data[k], 'utf-8')
1887  xml = xml_template % data
1888 
1889  # Write the output file
1890  codecs.open(destfile, "w", encoding='utf-8').write(xml)
1891  except:
1892  print 'WARNING: problem generating Eclipse launcher'
1893 
1894 
1895 try:
def which(executable)
Definition: GaudiTest.py:302
struct GAUDI_API map
Parametrisation class for map-like implementation.
def _CreateEclipseLaunch(self, prog, args, destdir=None)
Definition: GaudiTest.py:1764
def GaudiTest.GaudiExeTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 1311 of file GaudiTest.py.

1311  def _expandReferenceFileName(self, reffile):
1312  # if no file is passed, do nothing
1313  if not reffile:
1314  return ""
1315 
1316  # function to split an extension in constituents parts
1317  def platformSplit(p): return set(p.split('-' in p and '-' or '_'))
1318 
1319  reference = os.path.normpath(os.path.expandvars(reffile))
1320  # old-style platform-specific reference name
1321  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1322  if os.path.isfile(spec_ref):
1323  reference = spec_ref
1324  else: # look for new-style platform specific reference files:
1325  # get all the files whose name start with the reference filename
1326  dirname, basename = os.path.split(reference)
1327  if not dirname:
1328  dirname = '.'
1329  head = basename + "."
1330  head_len = len(head)
1331  platform = platformSplit(self.GetPlatform())
1332  if 'do0' in platform:
1333  platform.add('dbg')
1334  candidates = []
1335  for f in os.listdir(dirname):
1336  if f.startswith(head):
1337  req_plat = platformSplit(f[head_len:])
1338  if platform.issuperset(req_plat):
1339  candidates.append((len(req_plat), f))
1340  if candidates: # take the one with highest matching
1341  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1342  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1343  candidates.sort()
1344  reference = os.path.join(dirname, candidates[-1][1])
1345  return reference
1346 
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1311
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 1385 of file GaudiTest.py.

1385  ignore=None):
1386  """
1387  Compare the TTree summaries in stdout with the ones in trees_dict or in
1388  the reference file. By default ignore the size, compression and basket
1389  fields.
1390  The presence of TTree summaries when none is expected is not a failure.
1391  """
1392  if dict is None:
1393  reference = self._expandReferenceFileName(self.reference)
1394  # call the validator if the file exists
1395  if reference and os.path.isfile(reference):
1396  dict = findHistosSummaries(open(reference).read())
1397  else:
1398  dict = {}
1399 
1400  from pprint import PrettyPrinter
1401  pp = PrettyPrinter()
1402  if dict:
1403  result["GaudiTest.Histos.expected"] = result.Quote(
1404  pp.pformat(dict))
1405  if ignore:
1406  result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1407 
1408  histos = findHistosSummaries(stdout)
1409  failed = cmpTreesDicts(dict, histos, ignore)
1410  if failed:
1411  causes.append("histos summaries")
1412  msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1413  result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1414  result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1415 
1416  return causes
1417 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1311
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: GaudiTest.py:849
def getCmpFailingValues(reference, to_check, fail_path)
Definition: GaudiTest.py:882
def findHistosSummaries(stdout)
Definition: GaudiTest.py:964
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 1349 of file GaudiTest.py.

1349  ignore=r"Basket|.*size|Compression"):
1350  """
1351  Compare the TTree summaries in stdout with the ones in trees_dict or in
1352  the reference file. By default ignore the size, compression and basket
1353  fields.
1354  The presence of TTree summaries when none is expected is not a failure.
1355  """
1356  if trees_dict is None:
1357  reference = self._expandReferenceFileName(self.reference)
1358  # call the validator if the file exists
1359  if reference and os.path.isfile(reference):
1360  trees_dict = findTTreeSummaries(open(reference).read())
1361  else:
1362  trees_dict = {}
1363 
1364  from pprint import PrettyPrinter
1365  pp = PrettyPrinter()
1366  if trees_dict:
1367  result["GaudiTest.TTrees.expected"] = result.Quote(
1368  pp.pformat(trees_dict))
1369  if ignore:
1370  result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1371 
1372  trees = findTTreeSummaries(stdout)
1373  failed = cmpTreesDicts(trees_dict, trees, ignore)
1374  if failed:
1375  causes.append("trees summaries")
1376  msg = "%s: %s != %s" % getCmpFailingValues(
1377  trees_dict, trees, failed)
1378  result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1379  result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1380 
1381  return causes
1382 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1311
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: GaudiTest.py:849
def getCmpFailingValues(reference, to_check, fail_path)
Definition: GaudiTest.py:882
def findTTreeSummaries(stdout)
Definition: GaudiTest.py:827
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 1542 of file GaudiTest.py.

1542  def DumpEnvironment(self, result):
1543  """
1544  Add the content of the environment to the result object.
1545 
1546  Copied from the QMTest class of COOL.
1547  """
1548  vars = os.environ.keys()
1549  vars.sort()
1550  result['GaudiTest.environment'] = \
1551  result.Quote(
1552  '\n'.join(["%s=%s" % (v, os.environ[v]) for v in vars]))
1553 
def DumpEnvironment(self, result)
Definition: GaudiTest.py:1542
def GaudiTest.GaudiExeTest.GetPlatform (   self)
Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1289 of file GaudiTest.py.

1289  def GetPlatform(self):
1290  """
1291  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1292  """
1293  arch = "None"
1294  # check architecture name
1295  if "CMTCONFIG" in os.environ:
1296  arch = os.environ["CMTCONFIG"]
1297  elif "SCRAM_ARCH" in os.environ:
1298  arch = os.environ["SCRAM_ARCH"]
1299  return arch
1300 
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 1301 of file GaudiTest.py.

1301  def isWinPlatform(self):
1302  """
1303  Return True if the current platform is Windows.
1304 
1305  This function was needed because of the change in the CMTCONFIG format,
1306  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1307  """
1308  platform = self.GetPlatform()
1309  return "winxp" in platform or platform.startswith("win")
1310 
def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1275 of file GaudiTest.py.

1275  def PlatformIsNotSupported(self, context, result):
1276  platform = self.GetPlatform()
1277  unsupported = [re.compile(x)
1278  for x in [str(y).strip()
1279  for y in self.unsupported_platforms]
1280  if x
1281  ]
1282  for p_re in unsupported:
1283  if p_re.search(platform):
1284  result.SetOutcome(result.UNTESTED)
1285  result[result.CAUSE] = 'Platform not supported.'
1286  return True
1287  return False
1288 
def PlatformIsNotSupported(self, context, result)
Definition: GaudiTest.py:1275
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 1554 of file GaudiTest.py.

1554  def Run(self, context, result):
1555  """Run the test.
1556 
1557  'context' -- A 'Context' giving run-time parameters to the
1558  test.
1559 
1560  'result' -- A 'Result' object. The outcome will be
1561  'Result.PASS' when this method is called. The 'result' may be
1562  modified by this method to indicate outcomes other than
1563  'Result.PASS' or to add annotations."""
1564 
1565  # Check if the platform is supported
1566  if self.PlatformIsNotSupported(context, result):
1567  return
1568 
1569  # Prepare program name and arguments (expanding variables, and converting to absolute)
1570  if self.program:
1571  prog = rationalizepath(self.program)
1572  elif "GAUDIEXE" in os.environ:
1573  prog = os.environ["GAUDIEXE"]
1574  else:
1575  prog = "Gaudi.exe"
1576  self.program = prog
1577 
1578  dummy, prog_ext = os.path.splitext(prog)
1579  if prog_ext not in [".exe", ".py", ".bat"] and self.isWinPlatform():
1580  prog += ".exe"
1581  prog_ext = ".exe"
1582 
1583  prog = which(prog) or prog
1584 
1585  # Convert paths to absolute paths in arguments and reference files
1586  args = map(rationalizepath, self.args)
1589 
1590  # check if the user provided inline options
1591  tmpfile = None
1592  if self.options.strip():
1593  ext = ".opts"
1594  if re.search(r"from\s+Gaudi.Configuration\s+import\s+\*|from\s+Configurables\s+import", self.options):
1595  ext = ".py"
1596  tmpfile = TempFile(ext)
1597  tmpfile.writelines("\n".join(self.options.splitlines()))
1598  tmpfile.flush()
1599  args.append(tmpfile.name)
1600  result["GaudiTest.options"] = result.Quote(self.options)
1601 
1602  # if the program is a python file, execute it through python
1603  if prog_ext == ".py":
1604  args.insert(0, prog)
1605  if self.isWinPlatform():
1606  prog = which("python.exe") or "python.exe"
1607  else:
1608  prog = which("python") or "python"
1609 
1610  # Change to the working directory if specified or to the default temporary
1611  origdir = os.getcwd()
1612  if self.workdir:
1613  os.chdir(str(os.path.normpath(os.path.expandvars(self.workdir))))
1614  elif self.use_temp_dir == "true":
1615  if "QMTEST_TMPDIR" in os.environ:
1616  qmtest_tmpdir = os.environ["QMTEST_TMPDIR"]
1617  if not os.path.exists(qmtest_tmpdir):
1618  os.makedirs(qmtest_tmpdir)
1619  os.chdir(qmtest_tmpdir)
1620  elif "qmtest.tmpdir" in context:
1621  os.chdir(context["qmtest.tmpdir"])
1622 
1623  if "QMTEST_IGNORE_TIMEOUT" not in os.environ:
1624  self.timeout = max(self.timeout, 600)
1625  else:
1626  self.timeout = -1
1627 
1628  try:
1629  # Generate eclipse.org debug launcher for the test
1630  self._CreateEclipseLaunch(
1631  prog, args, destdir=os.path.join(origdir, '.eclipse'))
1632  # Run the test
1633  self.RunProgram(prog,
1634  [prog] + args,
1635  context, result)
1636  # Record the content of the enfironment for failing tests
1637  if result.GetOutcome() not in [result.PASS]:
1638  self.DumpEnvironment(result)
1639  finally:
1640  # revert to the original directory
1641  os.chdir(origdir)
1642 
def PlatformIsNotSupported(self, context, result)
Definition: GaudiTest.py:1275
def DumpEnvironment(self, result)
Definition: GaudiTest.py:1542
def which(executable)
Definition: GaudiTest.py:302
def RunProgram(self, program, arguments, context, result)
Definition: GaudiTest.py:1643
struct GAUDI_API map
Parametrisation class for map-like implementation.
def Run(self, context, result)
Definition: GaudiTest.py:1554
def _CreateEclipseLaunch(self, prog, args, destdir=None)
Definition: GaudiTest.py:1764
def rationalizepath(p)
Definition: GaudiTest.py:323
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 1643 of file GaudiTest.py.

1643  def RunProgram(self, program, arguments, context, result):
1644  """Run the 'program'.
1645 
1646  'program' -- The path to the program to run.
1647 
1648  'arguments' -- A list of the arguments to the program. This
1649  list must contain a first argument corresponding to 'argv[0]'.
1650 
1651  'context' -- A 'Context' giving run-time parameters to the
1652  test.
1653 
1654  'result' -- A 'Result' object. The outcome will be
1655  'Result.PASS' when this method is called. The 'result' may be
1656  modified by this method to indicate outcomes other than
1657  'Result.PASS' or to add annotations.
1658 
1659  @attention: This method has been copied from command.ExecTestBase
1660  (QMTest 2.3.0) and modified to keep stdout and stderr
1661  for tests that have been terminated by a signal.
1662  (Fundamental for debugging in the Application Area)
1663  """
1664 
1665  # Construct the environment.
1666  environment = self.MakeEnvironment(context)
1667  # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
1668  if "slc6" in environment.get('CMTCONFIG', ''):
1669  environment['TERM'] = 'dumb'
1670  # Create the executable.
1671  if self.timeout >= 0:
1672  timeout = self.timeout
1673  else:
1674  # If no timeout was specified, we sill run this process in a
1675  # separate process group and kill the entire process group
1676  # when the child is done executing. That means that
1677  # orphaned child processes created by the test will be
1678  # cleaned up.
1679  timeout = -2
1680  e = GaudiFilterExecutable(self.stdin, timeout)
1681  # Run it.
1682  exit_status = e.Run(arguments, environment, path=program)
1683  # Get the stack trace from the temporary file (if present)
1684  if e.stack_trace_file and os.path.exists(e.stack_trace_file):
1685  stack_trace = open(e.stack_trace_file).read()
1686  os.remove(e.stack_trace_file)
1687  else:
1688  stack_trace = None
1689  if stack_trace:
1690  result["ExecTest.stack_trace"] = result.Quote(stack_trace)
1691 
1692  # If the process terminated normally, check the outputs.
1693  if (sys.platform == "win32" or os.WIFEXITED(exit_status)
1694  or self.signal == os.WTERMSIG(exit_status)):
1695  # There are no causes of failure yet.
1696  causes = []
1697  # The target program terminated normally. Extract the
1698  # exit code, if this test checks it.
1699  if self.exit_code is None:
1700  exit_code = None
1701  elif sys.platform == "win32":
1702  exit_code = exit_status
1703  else:
1704  exit_code = os.WEXITSTATUS(exit_status)
1705  # Get the output generated by the program.
1706  stdout = e.stdout
1707  stderr = e.stderr
1708  # Record the results.
1709  result["ExecTest.exit_code"] = str(exit_code)
1710  result["ExecTest.stdout"] = result.Quote(stdout)
1711  result["ExecTest.stderr"] = result.Quote(stderr)
1712  # Check to see if the exit code matches.
1713  if exit_code != self.exit_code:
1714  causes.append("exit_code")
1715  result["ExecTest.expected_exit_code"] \
1716  = str(self.exit_code)
1717  # Validate the output.
1718  causes += self.ValidateOutput(stdout, stderr, result)
1719  # If anything went wrong, the test failed.
1720  if causes:
1721  result.Fail("Unexpected %s." % string.join(causes, ", "))
1722  elif os.WIFSIGNALED(exit_status):
1723  # The target program terminated with a signal. Construe
1724  # that as a test failure.
1725  signal_number = str(os.WTERMSIG(exit_status))
1726  if not stack_trace:
1727  result.Fail("Program terminated by signal.")
1728  else:
1729  # The presence of stack_trace means tha we stopped the job because
1730  # of a time-out
1731  result.Fail("Exceeded time limit (%ds), terminated." % timeout)
1732  result["ExecTest.signal_number"] = signal_number
1733  result["ExecTest.stdout"] = result.Quote(e.stdout)
1734  result["ExecTest.stderr"] = result.Quote(e.stderr)
1735  if self.signal:
1736  result["ExecTest.expected_signal_number"] = str(self.signal)
1737  elif os.WIFSTOPPED(exit_status):
1738  # The target program was stopped. Construe that as a
1739  # test failure.
1740  signal_number = str(os.WSTOPSIG(exit_status))
1741  if not stack_trace:
1742  result.Fail("Program stopped by signal.")
1743  else:
1744  # The presence of stack_trace means tha we stopped the job because
1745  # of a time-out
1746  result.Fail("Exceeded time limit (%ds), stopped." % timeout)
1747  result["ExecTest.signal_number"] = signal_number
1748  result["ExecTest.stdout"] = result.Quote(e.stdout)
1749  result["ExecTest.stderr"] = result.Quote(e.stderr)
1750  else:
1751  # The target program terminated abnormally in some other
1752  # manner. (This shouldn't normally happen...)
1753  result.Fail("Program did not terminate normally.")
1754 
1755  # Marco Cl.: This is a special trick to fix a "problem" with the output
1756  # of gaudi jobs when they use colors
1757  esc = '\x1b'
1758  repr_esc = '\\x1b'
1759  result["ExecTest.stdout"] = result["ExecTest.stdout"].replace(
1760  esc, repr_esc)
1761  # TODO: (MCl) improve the hack for colors in standard output
1762  # may be converting them to HTML tags
1763 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
def RunProgram(self, program, arguments, context, result)
Definition: GaudiTest.py:1643
def ValidateOutput(self, stdout, stderr, result)
Definition: GaudiTest.py:1475
def GaudiTest.GaudiExeTest.ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1475 of file GaudiTest.py.

1475  def ValidateOutput(self, stdout, stderr, result):
1476  causes = []
1477  # if the test definition contains a custom validator, use it
1478  if self.validator.strip() != "":
1479  class CallWrapper(object):
1480  """
1481  Small wrapper class to dynamically bind some default arguments
1482  to a callable.
1483  """
1484 
1485  def __init__(self, callable, extra_args={}):
1486  self.callable = callable
1487  self.extra_args = extra_args
1488  # get the list of names of positional arguments
1489  from inspect import getargspec
1490  self.args_order = getargspec(callable)[0]
1491  # Remove "self" from the list of positional arguments
1492  # since it is added automatically
1493  if self.args_order[0] == "self":
1494  del self.args_order[0]
1495 
1496  def __call__(self, *args, **kwargs):
1497  # Check which positional arguments are used
1498  positional = self.args_order[:len(args)]
1499 
1500  kwargs = dict(kwargs) # copy the arguments dictionary
1501  for a in self.extra_args:
1502  # use "extra_args" for the arguments not specified as
1503  # positional or keyword
1504  if a not in positional and a not in kwargs:
1505  kwargs[a] = self.extra_args[a]
1506  return apply(self.callable, args, kwargs)
1507  # local names to be exposed in the script
1508  exported_symbols = {"self": self,
1509  "stdout": stdout,
1510  "stderr": stderr,
1511  "result": result,
1512  "causes": causes,
1513  "findReferenceBlock":
1514  CallWrapper(findReferenceBlock, {"stdout": stdout,
1515  "result": result,
1516  "causes": causes}),
1517  "validateWithReference":
1518  CallWrapper(self.ValidateWithReference, {"stdout": stdout,
1519  "stderr": stderr,
1520  "result": result,
1521  "causes": causes}),
1522  "countErrorLines":
1523  CallWrapper(countErrorLines, {"stdout": stdout,
1524  "result": result,
1525  "causes": causes}),
1526  "checkTTreesSummaries":
1527  CallWrapper(self.CheckTTreesSummaries, {"stdout": stdout,
1528  "result": result,
1529  "causes": causes}),
1530  "checkHistosSummaries":
1531  CallWrapper(self.CheckHistosSummaries, {"stdout": stdout,
1532  "result": result,
1533  "causes": causes}),
1534 
1535  }
1536  exec self.validator in globals(), exported_symbols
1537  else:
1538  self.ValidateWithReference(stdout, stderr, result, causes)
1539 
1540  return causes
1541 
def CheckHistosSummaries(self, stdout, result, causes, dict=None, ignore=None)
Definition: GaudiTest.py:1385
decltype(auto) constexpr apply(F &&f, Tuple &&t) noexcept(noexcept( detail::apply_impl(std::forward< F >(f), std::forward< Tuple >(t), std::make_index_sequence< std::tuple_size< std::remove_reference_t< Tuple >>::value >{})))
Definition: apply.h:31
def CheckTTreesSummaries(self, stdout, result, causes, trees_dict=None, ignore=r"Basket|.*size|Compression")
Definition: GaudiTest.py:1349
def ValidateOutput(self, stdout, stderr, result)
Definition: GaudiTest.py:1475
def ValidateWithReference(self, stdout, stderr, result, causes, preproc=None)
Definition: GaudiTest.py:1418
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 1418 of file GaudiTest.py.

1418  def ValidateWithReference(self, stdout, stderr, result, causes, preproc=None):
1419  """
1420  Default validation action: compare standard output and error to the
1421  reference files.
1422  """
1423  # set the default output preprocessor
1424  if preproc is None:
1425  preproc = normalizeExamples
1426  # check standard output
1427  reference = self._expandReferenceFileName(self.reference)
1428  # call the validator if the file exists
1429  if reference and os.path.isfile(reference):
1430  result["GaudiTest.output_reference"] = reference
1431  causes += ReferenceFileValidator(reference,
1432  "standard output",
1433  "GaudiTest.output_diff",
1434  preproc=preproc)(stdout, result)
1435 
1436  # Compare TTree summaries
1437  causes = self.CheckTTreesSummaries(stdout, result, causes)
1438  causes = self.CheckHistosSummaries(stdout, result, causes)
1439 
1440  if causes: # Write a new reference file for stdout
1441  try:
1442  newref = open(reference + ".new", "w")
1443  # sanitize newlines
1444  for l in stdout.splitlines():
1445  newref.write(l.rstrip() + '\n')
1446  del newref # flush and close
1447  except IOError:
1448  # Ignore IO errors when trying to update reference files
1449  # because we may be in a read-only filesystem
1450  pass
1451 
1452  # check standard error
1453  reference = self._expandReferenceFileName(self.error_reference)
1454  # call the validator if we have a file to use
1455  if reference and os.path.isfile(reference):
1456  result["GaudiTest.error_reference"] = reference
1457  newcauses = ReferenceFileValidator(reference,
1458  "standard error",
1459  "GaudiTest.error_diff",
1460  preproc=preproc)(stderr, result)
1461  causes += newcauses
1462  if newcauses: # Write a new reference file for stdedd
1463  newref = open(reference + ".new", "w")
1464  # sanitize newlines
1465  for l in stderr.splitlines():
1466  newref.write(l.rstrip() + '\n')
1467  del newref # flush and close
1468  else:
1469  causes += BasicOutputValidator(self.stderr,
1470  "standard error",
1471  "ExecTest.expected_stderr")(stderr, result)
1472 
1473  return causes
1474 
def CheckHistosSummaries(self, stdout, result, causes, dict=None, ignore=None)
Definition: GaudiTest.py:1385
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1311
def CheckTTreesSummaries(self, stdout, result, causes, trees_dict=None, ignore=r"Basket|.*size|Compression")
Definition: GaudiTest.py:1349
Output Validation Classes.
Definition: GaudiTest.py:374
def ValidateWithReference(self, stdout, stderr, result, causes, preproc=None)
Definition: GaudiTest.py:1418

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1490 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1154 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1486 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1588 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1487 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1576 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1587 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1694 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1624 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1614 of file GaudiTest.py.


The documentation for this class was generated from the following file: