The Gaudi Framework  v33r1 (b1225454)
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 1195 of file GaudiTest.py.

Member Function Documentation

◆ _CreateEclipseLaunch()

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

Definition at line 1829 of file GaudiTest.py.

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

◆ _expandReferenceFileName()

def GaudiTest.GaudiExeTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 1344 of file GaudiTest.py.

1344  def _expandReferenceFileName(self, reffile):
1345  # if no file is passed, do nothing
1346  if not reffile:
1347  return ""
1348 
1349  # function to split an extension in constituents parts
1350  def platformSplit(p):
1351  return set(p.split('-' in p and '-' or '_'))
1352 
1353  reference = os.path.normpath(os.path.expandvars(reffile))
1354  # old-style platform-specific reference name
1355  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1356  if os.path.isfile(spec_ref):
1357  reference = spec_ref
1358  else: # look for new-style platform specific reference files:
1359  # get all the files whose name start with the reference filename
1360  dirname, basename = os.path.split(reference)
1361  if not dirname:
1362  dirname = '.'
1363  head = basename + "."
1364  head_len = len(head)
1365  platform = platformSplit(self.GetPlatform())
1366  if 'do0' in platform:
1367  platform.add('dbg')
1368  candidates = []
1369  for f in os.listdir(dirname):
1370  if f.startswith(head):
1371  req_plat = platformSplit(f[head_len:])
1372  if platform.issuperset(req_plat):
1373  candidates.append((len(req_plat), f))
1374  if candidates: # take the one with highest matching
1375  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1376  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1377  candidates.sort()
1378  reference = os.path.join(dirname, candidates[-1][1])
1379  return reference
1380 

◆ CheckHistosSummaries()

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 1420 of file GaudiTest.py.

1420  def CheckHistosSummaries(self,
1421  stdout,
1422  result,
1423  causes,
1424  dict=None,
1425  ignore=None):
1426  """
1427  Compare the TTree summaries in stdout with the ones in trees_dict or in
1428  the reference file. By default ignore the size, compression and basket
1429  fields.
1430  The presence of TTree summaries when none is expected is not a failure.
1431  """
1432  if dict is None:
1433  reference = self._expandReferenceFileName(self.reference)
1434  # call the validator if the file exists
1435  if reference and os.path.isfile(reference):
1436  dict = findHistosSummaries(open(reference).read())
1437  else:
1438  dict = {}
1439 
1440  from pprint import PrettyPrinter
1441  pp = PrettyPrinter()
1442  if dict:
1443  result["GaudiTest.Histos.expected"] = result.Quote(
1444  pp.pformat(dict))
1445  if ignore:
1446  result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1447 
1448  histos = findHistosSummaries(stdout)
1449  failed = cmpTreesDicts(dict, histos, ignore)
1450  if failed:
1451  causes.append("histos summaries")
1452  msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1453  result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1454  result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1455 
1456  return causes
1457 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:33
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: GaudiTest.py:886
def getCmpFailingValues(reference, to_check, fail_path)
Definition: GaudiTest.py:919
def findHistosSummaries(stdout)
Definition: GaudiTest.py:1004

◆ CheckTTreesSummaries()

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 1381 of file GaudiTest.py.

1381  def CheckTTreesSummaries(self,
1382  stdout,
1383  result,
1384  causes,
1385  trees_dict=None,
1386  ignore=r"Basket|.*size|Compression"):
1387  """
1388  Compare the TTree summaries in stdout with the ones in trees_dict or in
1389  the reference file. By default ignore the size, compression and basket
1390  fields.
1391  The presence of TTree summaries when none is expected is not a failure.
1392  """
1393  if trees_dict is None:
1394  reference = self._expandReferenceFileName(self.reference)
1395  # call the validator if the file exists
1396  if reference and os.path.isfile(reference):
1397  trees_dict = findTTreeSummaries(open(reference).read())
1398  else:
1399  trees_dict = {}
1400 
1401  from pprint import PrettyPrinter
1402  pp = PrettyPrinter()
1403  if trees_dict:
1404  result["GaudiTest.TTrees.expected"] = result.Quote(
1405  pp.pformat(trees_dict))
1406  if ignore:
1407  result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1408 
1409  trees = findTTreeSummaries(stdout)
1410  failed = cmpTreesDicts(trees_dict, trees, ignore)
1411  if failed:
1412  causes.append("trees summaries")
1413  msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees,
1414  failed)
1415  result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1416  result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1417 
1418  return causes
1419 
def read(f, regex='.*', skipevents=0)
Definition: hivetimeline.py:33
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: GaudiTest.py:886
def getCmpFailingValues(reference, to_check, fail_path)
Definition: GaudiTest.py:919
def findTTreeSummaries(stdout)
Definition: GaudiTest.py:864

◆ DumpEnvironment()

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 1607 of file GaudiTest.py.

1607  def DumpEnvironment(self, result):
1608  """
1609  Add the content of the environment to the result object.
1610 
1611  Copied from the QMTest class of COOL.
1612  """
1613  vars = os.environ.keys()
1614  vars.sort()
1615  result['GaudiTest.environment'] = \
1616  result.Quote(
1617  '\n'.join(["%s=%s" % (v, os.environ[v]) for v in vars]))
1618 

◆ GetPlatform()

def GaudiTest.GaudiExeTest.GetPlatform (   self)
Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1322 of file GaudiTest.py.

1322  def GetPlatform(self):
1323  """
1324  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1325  """
1326  arch = "None"
1327  # check architecture name
1328  if "CMTCONFIG" in os.environ:
1329  arch = os.environ["CMTCONFIG"]
1330  elif "SCRAM_ARCH" in os.environ:
1331  arch = os.environ["SCRAM_ARCH"]
1332  return arch
1333 
def GetPlatform(self)
Definition: BaseTest.py:1334

◆ isWinPlatform()

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 1334 of file GaudiTest.py.

1334  def isWinPlatform(self):
1335  """
1336  Return True if the current platform is Windows.
1337 
1338  This function was needed because of the change in the CMTCONFIG format,
1339  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1340  """
1341  platform = self.GetPlatform()
1342  return "winxp" in platform or platform.startswith("win")
1343 
def isWinPlatform(self)
Definition: BaseTest.py:1349

◆ PlatformIsNotSupported()

def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1309 of file GaudiTest.py.

1309  def PlatformIsNotSupported(self, context, result):
1310  platform = self.GetPlatform()
1311  unsupported = [
1312  re.compile(x)
1313  for x in [str(y).strip() for y in self.unsupported_platforms] if x
1314  ]
1315  for p_re in unsupported:
1316  if p_re.search(platform):
1317  result.SetOutcome(result.UNTESTED)
1318  result[result.CAUSE] = 'Platform not supported.'
1319  return True
1320  return False
1321 
def PlatformIsNotSupported(self, context, result)
Definition: BaseTest.py:1320

◆ Run()

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 1619 of file GaudiTest.py.

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

◆ RunProgram()

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 1708 of file GaudiTest.py.

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

◆ ValidateOutput()

def GaudiTest.GaudiExeTest.ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1522 of file GaudiTest.py.

1522  def ValidateOutput(self, stdout, stderr, result):
1523  causes = []
1524  # if the test definition contains a custom validator, use it
1525  if self.validator.strip() != "":
1526 
1527  class CallWrapper(object):
1528  """
1529  Small wrapper class to dynamically bind some default arguments
1530  to a callable.
1531  """
1532 
1533  def __init__(self, callable, extra_args={}):
1534  self.callable = callable
1535  self.extra_args = extra_args
1536  # get the list of names of positional arguments
1537  from inspect import getargspec
1538  self.args_order = getargspec(callable)[0]
1539  # Remove "self" from the list of positional arguments
1540  # since it is added automatically
1541  if self.args_order[0] == "self":
1542  del self.args_order[0]
1543 
1544  def __call__(self, *args, **kwargs):
1545  # Check which positional arguments are used
1546  positional = self.args_order[:len(args)]
1547 
1548  kwargs = dict(kwargs) # copy the arguments dictionary
1549  for a in self.extra_args:
1550  # use "extra_args" for the arguments not specified as
1551  # positional or keyword
1552  if a not in positional and a not in kwargs:
1553  kwargs[a] = self.extra_args[a]
1554  return self.callable(*args, **kwargs)
1555 
1556  # local names to be exposed in the script
1557  exported_symbols = {
1558  "self":
1559  self,
1560  "stdout":
1561  stdout,
1562  "stderr":
1563  stderr,
1564  "result":
1565  result,
1566  "causes":
1567  causes,
1568  "findReferenceBlock":
1569  CallWrapper(findReferenceBlock, {
1570  "stdout": stdout,
1571  "result": result,
1572  "causes": causes
1573  }),
1574  "validateWithReference":
1575  CallWrapper(
1576  self.ValidateWithReference, {
1577  "stdout": stdout,
1578  "stderr": stderr,
1579  "result": result,
1580  "causes": causes
1581  }),
1582  "countErrorLines":
1583  CallWrapper(countErrorLines, {
1584  "stdout": stdout,
1585  "result": result,
1586  "causes": causes
1587  }),
1588  "checkTTreesSummaries":
1589  CallWrapper(self.CheckTTreesSummaries, {
1590  "stdout": stdout,
1591  "result": result,
1592  "causes": causes
1593  }),
1594  "checkHistosSummaries":
1595  CallWrapper(self.CheckHistosSummaries, {
1596  "stdout": stdout,
1597  "result": result,
1598  "causes": causes
1599  }),
1600  }
1601  exec (self.validator, globals(), exported_symbols)
1602  else:
1603  self.ValidateWithReference(stdout, stderr, result, causes)
1604 
1605  return causes
1606 

◆ ValidateWithReference()

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 1458 of file GaudiTest.py.

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

Member Data Documentation

◆ args_order

GaudiTest.GaudiExeTest.args_order

Definition at line 1538 of file GaudiTest.py.

◆ arguments

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1198 of file GaudiTest.py.

◆ callable

GaudiTest.GaudiExeTest.callable

Definition at line 1534 of file GaudiTest.py.

◆ error_reference

GaudiTest.GaudiExeTest.error_reference

Definition at line 1653 of file GaudiTest.py.

◆ extra_args

GaudiTest.GaudiExeTest.extra_args

Definition at line 1535 of file GaudiTest.py.

◆ program

GaudiTest.GaudiExeTest.program

Definition at line 1641 of file GaudiTest.py.

◆ reference

GaudiTest.GaudiExeTest.reference

Definition at line 1652 of file GaudiTest.py.

◆ signal

GaudiTest.GaudiExeTest.signal

Definition at line 1759 of file GaudiTest.py.

◆ timeout

GaudiTest.GaudiExeTest.timeout

Definition at line 1691 of file GaudiTest.py.

◆ use_temp_dir

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1681 of file GaudiTest.py.


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