The Gaudi Framework  v31r0 (aeb156f0)
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 1184 of file GaudiTest.py.

Member Function Documentation

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

Definition at line 1818 of file GaudiTest.py.

1818  def _CreateEclipseLaunch(self, prog, args, destdir=None):
1819  if 'NO_ECLIPSE_LAUNCHERS' in os.environ:
1820  # do not generate eclipse launchers if the user asks so
1821  return
1822  # Find the project name used in ecplise.
1823  # The name is in a file called ".project" in one of the parent directories
1824  projbasedir = os.path.normpath(destdir)
1825  while not os.path.exists(os.path.join(projbasedir, ".project")):
1826  oldprojdir = projbasedir
1827  projbasedir = os.path.normpath(
1828  os.path.join(projbasedir, os.pardir))
1829  # FIXME: the root level is invariant when trying to go up one level,
1830  # but it must be cheched on windows
1831  if oldprojdir == projbasedir:
1832  # If we cannot find a .project, so no point in creating a .launch file
1833  return
1834  # Ensure that we have a place where to write.
1835  if not os.path.exists(destdir):
1836  os.makedirs(destdir)
1837  # Use ElementTree to parse the XML file
1838  from xml.etree import ElementTree as ET
1839  t = ET.parse(os.path.join(projbasedir, ".project"))
1840  projectName = t.find("name").text
1841 
1842  # prepare the name/path of the generated file
1843  destfile = "%s.launch" % self._Runnable__id
1844  if destdir:
1845  destfile = os.path.join(destdir, destfile)
1846 
1847  if self.options.strip():
1848  # this means we have some custom options in the qmt file, so we have
1849  # to copy them from the temporary file at the end of the arguments
1850  # in another file
1851  tempfile = args.pop()
1852  optsfile = destfile + os.path.splitext(tempfile)[1]
1853  shutil.copyfile(tempfile, optsfile)
1854  args.append(optsfile)
1855 
1856  # prepare the data to insert in the XML file
1857  from xml.sax.saxutils import quoteattr # useful to quote XML special chars
1858  data = {}
1859  # Note: the "quoteattr(k)" is not needed because special chars cannot be part of a variable name,
1860  # but it doesn't harm.
1861  data["environment"] = "\n".join([
1862  '<mapEntry key=%s value=%s/>' % (quoteattr(k), quoteattr(v))
1863  for k, v in os.environ.iteritems()
1864  if k not in ('MAKEOVERRIDES', 'MAKEFLAGS', 'MAKELEVEL')
1865  ])
1866 
1867  data["exec"] = which(prog) or prog
1868  if os.path.basename(data["exec"]).lower().startswith("python"):
1869  # do not stop at main when debugging Python scripts
1870  data["stopAtMain"] = "false"
1871  else:
1872  data["stopAtMain"] = "true"
1873 
1874  data["args"] = "&#10;".join(map(rationalizepath, args))
1875  if self.isWinPlatform():
1876  data["args"] = "&#10;".join(
1877  ["/debugexe"] + map(rationalizepath, [data["exec"]] + args))
1878  data["exec"] = which("vcexpress.exe")
1879 
1880  if not self.use_temp_dir:
1881  data["workdir"] = os.getcwd()
1882  else:
1883  # If the test is using a tmporary directory, it is better to run it
1884  # in the same directory as the .launch file when debugged in eclipse
1885  data["workdir"] = destdir
1886 
1887  data["project"] = projectName.strip()
1888 
1889  # Template for the XML file, based on eclipse 3.4
1890  xml_template = u"""<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1891 <launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
1892 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB" value="true"/>
1893 <listAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB_LIST"/>
1894 <stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="gdb"/>
1895 <stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=".gdbinit"/>
1896 <listAttribute key="org.eclipse.cdt.debug.mi.core.SOLIB_PATH"/>
1897 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.STOP_ON_SOLIB_EVENTS" value="false"/>
1898 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
1899 <stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="org.eclipse.cdt.debug.mi.core.standardCommandFactory"/>
1900 <stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
1901 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
1902 <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
1903 <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
1904 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="org.eclipse.cdt.debug.mi.core.CDebuggerNew"/>
1905 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
1906 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
1907 <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="%(stopAtMain)s"/>
1908 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
1909 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
1910 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
1911 <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;"/>
1912 <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;"/>
1913 <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;"/>
1914 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="%(args)s"/>
1915 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="%(exec)s"/>
1916 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="%(project)s"/>
1917 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
1918 <stringAttribute key="org.eclipse.cdt.launch.WORKING_DIRECTORY" value="%(workdir)s"/>
1919 <booleanAttribute key="org.eclipse.cdt.launch.ui.ApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
1920 <booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
1921 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
1922 <listEntry value="/%(project)s"/>
1923 </listAttribute>
1924 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
1925 <listEntry value="4"/>
1926 </listAttribute>
1927 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
1928 <mapAttribute key="org.eclipse.debug.core.environmentVariables">
1929 %(environment)s
1930 </mapAttribute>
1931 <mapAttribute key="org.eclipse.debug.core.preferred_launchers">
1932 <mapEntry key="[debug]" value="org.eclipse.cdt.cdi.launch.localCLaunch"/>
1933 </mapAttribute>
1934 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
1935 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
1936 </listAttribute>
1937 </launchConfiguration>
1938 """
1939  try:
1940  # ensure the correct encoding of data values
1941  for k in data:
1942  data[k] = codecs.decode(data[k], 'utf-8')
1943  xml = xml_template % data
1944 
1945  # Write the output file
1946  codecs.open(destfile, "w", encoding='utf-8').write(xml)
1947  except:
1948  print 'WARNING: problem generating Eclipse launcher'
1949 
1950 
1951 try:
def which(executable)
Definition: GaudiTest.py:309
struct GAUDI_API map
Parametrisation class for map-like implementation.
def _CreateEclipseLaunch(self, prog, args, destdir=None)
Definition: GaudiTest.py:1818
def GaudiTest.GaudiExeTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 1333 of file GaudiTest.py.

1333  def _expandReferenceFileName(self, reffile):
1334  # if no file is passed, do nothing
1335  if not reffile:
1336  return ""
1337 
1338  # function to split an extension in constituents parts
1339  def platformSplit(p):
1340  return set(p.split('-' in p and '-' or '_'))
1341 
1342  reference = os.path.normpath(os.path.expandvars(reffile))
1343  # old-style platform-specific reference name
1344  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1345  if os.path.isfile(spec_ref):
1346  reference = spec_ref
1347  else: # look for new-style platform specific reference files:
1348  # get all the files whose name start with the reference filename
1349  dirname, basename = os.path.split(reference)
1350  if not dirname:
1351  dirname = '.'
1352  head = basename + "."
1353  head_len = len(head)
1354  platform = platformSplit(self.GetPlatform())
1355  if 'do0' in platform:
1356  platform.add('dbg')
1357  candidates = []
1358  for f in os.listdir(dirname):
1359  if f.startswith(head):
1360  req_plat = platformSplit(f[head_len:])
1361  if platform.issuperset(req_plat):
1362  candidates.append((len(req_plat), f))
1363  if candidates: # take the one with highest matching
1364  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1365  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1366  candidates.sort()
1367  reference = os.path.join(dirname, candidates[-1][1])
1368  return reference
1369 
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1333
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 1414 of file GaudiTest.py.

1414  ignore=None):
1415  """
1416  Compare the TTree summaries in stdout with the ones in trees_dict or in
1417  the reference file. By default ignore the size, compression and basket
1418  fields.
1419  The presence of TTree summaries when none is expected is not a failure.
1420  """
1421  if dict is None:
1422  reference = self._expandReferenceFileName(self.reference)
1423  # call the validator if the file exists
1424  if reference and os.path.isfile(reference):
1425  dict = findHistosSummaries(open(reference).read())
1426  else:
1427  dict = {}
1428 
1429  from pprint import PrettyPrinter
1430  pp = PrettyPrinter()
1431  if dict:
1432  result["GaudiTest.Histos.expected"] = result.Quote(
1433  pp.pformat(dict))
1434  if ignore:
1435  result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1436 
1437  histos = findHistosSummaries(stdout)
1438  failed = cmpTreesDicts(dict, histos, ignore)
1439  if failed:
1440  causes.append("histos summaries")
1441  msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1442  result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1443  result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1444 
1445  return causes
1446 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1333
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: GaudiTest.py:875
def getCmpFailingValues(reference, to_check, fail_path)
Definition: GaudiTest.py:908
def findHistosSummaries(stdout)
Definition: GaudiTest.py:993
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 1375 of file GaudiTest.py.

1375  ignore=r"Basket|.*size|Compression"):
1376  """
1377  Compare the TTree summaries in stdout with the ones in trees_dict or in
1378  the reference file. By default ignore the size, compression and basket
1379  fields.
1380  The presence of TTree summaries when none is expected is not a failure.
1381  """
1382  if trees_dict is None:
1383  reference = self._expandReferenceFileName(self.reference)
1384  # call the validator if the file exists
1385  if reference and os.path.isfile(reference):
1386  trees_dict = findTTreeSummaries(open(reference).read())
1387  else:
1388  trees_dict = {}
1389 
1390  from pprint import PrettyPrinter
1391  pp = PrettyPrinter()
1392  if trees_dict:
1393  result["GaudiTest.TTrees.expected"] = result.Quote(
1394  pp.pformat(trees_dict))
1395  if ignore:
1396  result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1397 
1398  trees = findTTreeSummaries(stdout)
1399  failed = cmpTreesDicts(trees_dict, trees, ignore)
1400  if failed:
1401  causes.append("trees summaries")
1402  msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees,
1403  failed)
1404  result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1405  result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1406 
1407  return causes
1408 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1333
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: GaudiTest.py:875
def getCmpFailingValues(reference, to_check, fail_path)
Definition: GaudiTest.py:908
def findTTreeSummaries(stdout)
Definition: GaudiTest.py:853
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 1596 of file GaudiTest.py.

1596  def DumpEnvironment(self, result):
1597  """
1598  Add the content of the environment to the result object.
1599 
1600  Copied from the QMTest class of COOL.
1601  """
1602  vars = os.environ.keys()
1603  vars.sort()
1604  result['GaudiTest.environment'] = \
1605  result.Quote(
1606  '\n'.join(["%s=%s" % (v, os.environ[v]) for v in vars]))
1607 
def DumpEnvironment(self, result)
Definition: GaudiTest.py:1596
def GaudiTest.GaudiExeTest.GetPlatform (   self)
Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1311 of file GaudiTest.py.

1311  def GetPlatform(self):
1312  """
1313  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1314  """
1315  arch = "None"
1316  # check architecture name
1317  if "CMTCONFIG" in os.environ:
1318  arch = os.environ["CMTCONFIG"]
1319  elif "SCRAM_ARCH" in os.environ:
1320  arch = os.environ["SCRAM_ARCH"]
1321  return arch
1322 
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 1323 of file GaudiTest.py.

1323  def isWinPlatform(self):
1324  """
1325  Return True if the current platform is Windows.
1326 
1327  This function was needed because of the change in the CMTCONFIG format,
1328  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1329  """
1330  platform = self.GetPlatform()
1331  return "winxp" in platform or platform.startswith("win")
1332 
def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1298 of file GaudiTest.py.

1298  def PlatformIsNotSupported(self, context, result):
1299  platform = self.GetPlatform()
1300  unsupported = [
1301  re.compile(x)
1302  for x in [str(y).strip() for y in self.unsupported_platforms] if x
1303  ]
1304  for p_re in unsupported:
1305  if p_re.search(platform):
1306  result.SetOutcome(result.UNTESTED)
1307  result[result.CAUSE] = 'Platform not supported.'
1308  return True
1309  return False
1310 
def PlatformIsNotSupported(self, context, result)
Definition: GaudiTest.py:1298
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 1608 of file GaudiTest.py.

1608  def Run(self, context, result):
1609  """Run the test.
1610 
1611  'context' -- A 'Context' giving run-time parameters to the
1612  test.
1613 
1614  'result' -- A 'Result' object. The outcome will be
1615  'Result.PASS' when this method is called. The 'result' may be
1616  modified by this method to indicate outcomes other than
1617  'Result.PASS' or to add annotations."""
1618 
1619  # Check if the platform is supported
1620  if self.PlatformIsNotSupported(context, result):
1621  return
1622 
1623  # Prepare program name and arguments (expanding variables, and converting to absolute)
1624  if self.program:
1625  prog = rationalizepath(self.program)
1626  elif "GAUDIEXE" in os.environ:
1627  prog = os.environ["GAUDIEXE"]
1628  else:
1629  prog = "Gaudi.exe"
1630  self.program = prog
1631 
1632  dummy, prog_ext = os.path.splitext(prog)
1633  if prog_ext not in [".exe", ".py", ".bat"] and self.isWinPlatform():
1634  prog += ".exe"
1635  prog_ext = ".exe"
1636 
1637  prog = which(prog) or prog
1638 
1639  # Convert paths to absolute paths in arguments and reference files
1640  args = map(rationalizepath, self.args)
1643 
1644  # check if the user provided inline options
1645  tmpfile = None
1646  if self.options.strip():
1647  ext = ".opts"
1648  if re.search(
1649  r"from\s+Gaudi.Configuration\s+import\s+\*|from\s+Configurables\s+import",
1650  self.options):
1651  ext = ".py"
1652  tmpfile = TempFile(ext)
1653  tmpfile.writelines("\n".join(self.options.splitlines()))
1654  tmpfile.flush()
1655  args.append(tmpfile.name)
1656  result["GaudiTest.options"] = result.Quote(self.options)
1657 
1658  # if the program is a python file, execute it through python
1659  if prog_ext == ".py":
1660  args.insert(0, prog)
1661  if self.isWinPlatform():
1662  prog = which("python.exe") or "python.exe"
1663  else:
1664  prog = which("python") or "python"
1665 
1666  # Change to the working directory if specified or to the default temporary
1667  origdir = os.getcwd()
1668  if self.workdir:
1669  os.chdir(str(os.path.normpath(os.path.expandvars(self.workdir))))
1670  elif self.use_temp_dir == "true":
1671  if "QMTEST_TMPDIR" in os.environ:
1672  qmtest_tmpdir = os.environ["QMTEST_TMPDIR"]
1673  if not os.path.exists(qmtest_tmpdir):
1674  os.makedirs(qmtest_tmpdir)
1675  os.chdir(qmtest_tmpdir)
1676  elif "qmtest.tmpdir" in context:
1677  os.chdir(context["qmtest.tmpdir"])
1678 
1679  if "QMTEST_IGNORE_TIMEOUT" not in os.environ:
1680  self.timeout = max(self.timeout, 600)
1681  else:
1682  self.timeout = -1
1683 
1684  try:
1685  # Generate eclipse.org debug launcher for the test
1686  self._CreateEclipseLaunch(
1687  prog, args, destdir=os.path.join(origdir, '.eclipse'))
1688  # Run the test
1689  self.RunProgram(prog, [prog] + args, context, result)
1690  # Record the content of the enfironment for failing tests
1691  if result.GetOutcome() not in [result.PASS]:
1692  self.DumpEnvironment(result)
1693  finally:
1694  # revert to the original directory
1695  os.chdir(origdir)
1696 
def PlatformIsNotSupported(self, context, result)
Definition: GaudiTest.py:1298
def DumpEnvironment(self, result)
Definition: GaudiTest.py:1596
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:215
def which(executable)
Definition: GaudiTest.py:309
def RunProgram(self, program, arguments, context, result)
Definition: GaudiTest.py:1697
struct GAUDI_API map
Parametrisation class for map-like implementation.
def Run(self, context, result)
Definition: GaudiTest.py:1608
def _CreateEclipseLaunch(self, prog, args, destdir=None)
Definition: GaudiTest.py:1818
def rationalizepath(p)
Definition: GaudiTest.py:330
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 1697 of file GaudiTest.py.

1697  def RunProgram(self, program, arguments, context, result):
1698  """Run the 'program'.
1699 
1700  'program' -- The path to the program to run.
1701 
1702  'arguments' -- A list of the arguments to the program. This
1703  list must contain a first argument corresponding to 'argv[0]'.
1704 
1705  'context' -- A 'Context' giving run-time parameters to the
1706  test.
1707 
1708  'result' -- A 'Result' object. The outcome will be
1709  'Result.PASS' when this method is called. The 'result' may be
1710  modified by this method to indicate outcomes other than
1711  'Result.PASS' or to add annotations.
1712 
1713  @attention: This method has been copied from command.ExecTestBase
1714  (QMTest 2.3.0) and modified to keep stdout and stderr
1715  for tests that have been terminated by a signal.
1716  (Fundamental for debugging in the Application Area)
1717  """
1718 
1719  # Construct the environment.
1720  environment = self.MakeEnvironment(context)
1721  # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
1722  if "slc6" in environment.get('CMTCONFIG', ''):
1723  environment['TERM'] = 'dumb'
1724  # Create the executable.
1725  if self.timeout >= 0:
1726  timeout = self.timeout
1727  else:
1728  # If no timeout was specified, we sill run this process in a
1729  # separate process group and kill the entire process group
1730  # when the child is done executing. That means that
1731  # orphaned child processes created by the test will be
1732  # cleaned up.
1733  timeout = -2
1734  e = GaudiFilterExecutable(self.stdin, timeout)
1735  # Run it.
1736  exit_status = e.Run(arguments, environment, path=program)
1737  # Get the stack trace from the temporary file (if present)
1738  if e.stack_trace_file and os.path.exists(e.stack_trace_file):
1739  stack_trace = open(e.stack_trace_file).read()
1740  os.remove(e.stack_trace_file)
1741  else:
1742  stack_trace = None
1743  if stack_trace:
1744  result["ExecTest.stack_trace"] = result.Quote(stack_trace)
1745 
1746  # If the process terminated normally, check the outputs.
1747  if (sys.platform == "win32" or os.WIFEXITED(exit_status)
1748  or self.signal == os.WTERMSIG(exit_status)):
1749  # There are no causes of failure yet.
1750  causes = []
1751  # The target program terminated normally. Extract the
1752  # exit code, if this test checks it.
1753  if self.exit_code is None:
1754  exit_code = None
1755  elif sys.platform == "win32":
1756  exit_code = exit_status
1757  else:
1758  exit_code = os.WEXITSTATUS(exit_status)
1759  # Get the output generated by the program.
1760  stdout = e.stdout
1761  stderr = e.stderr
1762  # Record the results.
1763  result["ExecTest.exit_code"] = str(exit_code)
1764  result["ExecTest.stdout"] = result.Quote(stdout)
1765  result["ExecTest.stderr"] = result.Quote(stderr)
1766  # Check to see if the exit code matches.
1767  if exit_code != self.exit_code:
1768  causes.append("exit_code")
1769  result["ExecTest.expected_exit_code"] \
1770  = str(self.exit_code)
1771  # Validate the output.
1772  causes += self.ValidateOutput(stdout, stderr, result)
1773  # If anything went wrong, the test failed.
1774  if causes:
1775  result.Fail("Unexpected %s." % string.join(causes, ", "))
1776  elif os.WIFSIGNALED(exit_status):
1777  # The target program terminated with a signal. Construe
1778  # that as a test failure.
1779  signal_number = str(os.WTERMSIG(exit_status))
1780  if not stack_trace:
1781  result.Fail("Program terminated by signal.")
1782  else:
1783  # The presence of stack_trace means tha we stopped the job because
1784  # of a time-out
1785  result.Fail("Exceeded time limit (%ds), terminated." % timeout)
1786  result["ExecTest.signal_number"] = signal_number
1787  result["ExecTest.stdout"] = result.Quote(e.stdout)
1788  result["ExecTest.stderr"] = result.Quote(e.stderr)
1789  if self.signal:
1790  result["ExecTest.expected_signal_number"] = str(self.signal)
1791  elif os.WIFSTOPPED(exit_status):
1792  # The target program was stopped. Construe that as a
1793  # test failure.
1794  signal_number = str(os.WSTOPSIG(exit_status))
1795  if not stack_trace:
1796  result.Fail("Program stopped by signal.")
1797  else:
1798  # The presence of stack_trace means tha we stopped the job because
1799  # of a time-out
1800  result.Fail("Exceeded time limit (%ds), stopped." % timeout)
1801  result["ExecTest.signal_number"] = signal_number
1802  result["ExecTest.stdout"] = result.Quote(e.stdout)
1803  result["ExecTest.stderr"] = result.Quote(e.stderr)
1804  else:
1805  # The target program terminated abnormally in some other
1806  # manner. (This shouldn't normally happen...)
1807  result.Fail("Program did not terminate normally.")
1808 
1809  # Marco Cl.: This is a special trick to fix a "problem" with the output
1810  # of gaudi jobs when they use colors
1811  esc = '\x1b'
1812  repr_esc = '\\x1b'
1813  result["ExecTest.stdout"] = result["ExecTest.stdout"].replace(
1814  esc, repr_esc)
1815  # TODO: (MCl) improve the hack for colors in standard output
1816  # may be converting them to HTML tags
1817 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:22
def RunProgram(self, program, arguments, context, result)
Definition: GaudiTest.py:1697
def ValidateOutput(self, stdout, stderr, result)
Definition: GaudiTest.py:1511
def GaudiTest.GaudiExeTest.ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1511 of file GaudiTest.py.

1511  def ValidateOutput(self, stdout, stderr, result):
1512  causes = []
1513  # if the test definition contains a custom validator, use it
1514  if self.validator.strip() != "":
1515 
1516  class CallWrapper(object):
1517  """
1518  Small wrapper class to dynamically bind some default arguments
1519  to a callable.
1520  """
1521 
1522  def __init__(self, callable, extra_args={}):
1523  self.callable = callable
1524  self.extra_args = extra_args
1525  # get the list of names of positional arguments
1526  from inspect import getargspec
1527  self.args_order = getargspec(callable)[0]
1528  # Remove "self" from the list of positional arguments
1529  # since it is added automatically
1530  if self.args_order[0] == "self":
1531  del self.args_order[0]
1532 
1533  def __call__(self, *args, **kwargs):
1534  # Check which positional arguments are used
1535  positional = self.args_order[:len(args)]
1536 
1537  kwargs = dict(kwargs) # copy the arguments dictionary
1538  for a in self.extra_args:
1539  # use "extra_args" for the arguments not specified as
1540  # positional or keyword
1541  if a not in positional and a not in kwargs:
1542  kwargs[a] = self.extra_args[a]
1543  return apply(self.callable, args, kwargs)
1544 
1545  # local names to be exposed in the script
1546  exported_symbols = {
1547  "self":
1548  self,
1549  "stdout":
1550  stdout,
1551  "stderr":
1552  stderr,
1553  "result":
1554  result,
1555  "causes":
1556  causes,
1557  "findReferenceBlock":
1558  CallWrapper(findReferenceBlock, {
1559  "stdout": stdout,
1560  "result": result,
1561  "causes": causes
1562  }),
1563  "validateWithReference":
1564  CallWrapper(
1565  self.ValidateWithReference, {
1566  "stdout": stdout,
1567  "stderr": stderr,
1568  "result": result,
1569  "causes": causes
1570  }),
1571  "countErrorLines":
1572  CallWrapper(countErrorLines, {
1573  "stdout": stdout,
1574  "result": result,
1575  "causes": causes
1576  }),
1577  "checkTTreesSummaries":
1578  CallWrapper(self.CheckTTreesSummaries, {
1579  "stdout": stdout,
1580  "result": result,
1581  "causes": causes
1582  }),
1583  "checkHistosSummaries":
1584  CallWrapper(self.CheckHistosSummaries, {
1585  "stdout": stdout,
1586  "result": result,
1587  "causes": causes
1588  }),
1589  }
1590  exec self.validator in globals(), exported_symbols
1591  else:
1592  self.ValidateWithReference(stdout, stderr, result, causes)
1593 
1594  return causes
1595 
def CheckHistosSummaries(self, stdout, result, causes, dict=None, ignore=None)
Definition: GaudiTest.py:1414
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:27
def CheckTTreesSummaries(self, stdout, result, causes, trees_dict=None, ignore=r"Basket|.*size|Compression")
Definition: GaudiTest.py:1375
def ValidateOutput(self, stdout, stderr, result)
Definition: GaudiTest.py:1511
def ValidateWithReference(self, stdout, stderr, result, causes, preproc=None)
Definition: GaudiTest.py:1452
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 1452 of file GaudiTest.py.

1452  preproc=None):
1453  """
1454  Default validation action: compare standard output and error to the
1455  reference files.
1456  """
1457  # set the default output preprocessor
1458  if preproc is None:
1459  preproc = normalizeExamples
1460  # check standard output
1461  reference = self._expandReferenceFileName(self.reference)
1462  # call the validator if the file exists
1463  if reference and os.path.isfile(reference):
1464  result["GaudiTest.output_reference"] = reference
1465  causes += ReferenceFileValidator(
1466  reference,
1467  "standard output",
1468  "GaudiTest.output_diff",
1469  preproc=preproc)(stdout, result)
1470 
1471  # Compare TTree summaries
1472  causes = self.CheckTTreesSummaries(stdout, result, causes)
1473  causes = self.CheckHistosSummaries(stdout, result, causes)
1474 
1475  if causes: # Write a new reference file for stdout
1476  try:
1477  newref = open(reference + ".new", "w")
1478  # sanitize newlines
1479  for l in stdout.splitlines():
1480  newref.write(l.rstrip() + '\n')
1481  del newref # flush and close
1482  except IOError:
1483  # Ignore IO errors when trying to update reference files
1484  # because we may be in a read-only filesystem
1485  pass
1486 
1487  # check standard error
1488  reference = self._expandReferenceFileName(self.error_reference)
1489  # call the validator if we have a file to use
1490  if reference and os.path.isfile(reference):
1491  result["GaudiTest.error_reference"] = reference
1492  newcauses = ReferenceFileValidator(
1493  reference,
1494  "standard error",
1495  "GaudiTest.error_diff",
1496  preproc=preproc)(stderr, result)
1497  causes += newcauses
1498  if newcauses: # Write a new reference file for stdedd
1499  newref = open(reference + ".new", "w")
1500  # sanitize newlines
1501  for l in stderr.splitlines():
1502  newref.write(l.rstrip() + '\n')
1503  del newref # flush and close
1504  else:
1505  causes += BasicOutputValidator(self.stderr, "standard error",
1506  "ExecTest.expected_stderr")(stderr,
1507  result)
1508 
1509  return causes
1510 
def CheckHistosSummaries(self, stdout, result, causes, dict=None, ignore=None)
Definition: GaudiTest.py:1414
def _expandReferenceFileName(self, reffile)
Definition: GaudiTest.py:1333
def CheckTTreesSummaries(self, stdout, result, causes, trees_dict=None, ignore=r"Basket|.*size|Compression")
Definition: GaudiTest.py:1375
Output Validation Classes.
Definition: GaudiTest.py:382

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1527 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1187 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1523 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1642 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1524 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1630 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1641 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1748 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1680 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1670 of file GaudiTest.py.


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