All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GaudiTest.GaudiExeTest Class Reference
Inheritance diagram for GaudiTest.GaudiExeTest:
Collaboration diagram for GaudiTest.GaudiExeTest:

Public Member Functions

def PlatformIsNotSupported
 
def GetPlatform
 
def isWinPlatform
 
def CheckTTreesSummaries
 
def CheckHistosSummaries
 
def ValidateWithReference
 
def ValidateOutput
 
def DumpEnvironment
 
def Run
 
def RunProgram
 

Public Attributes

 callable
 
 extra_args
 
 args_order
 
 program
 
 reference
 
 error_reference
 
 use_temp_dir
 
 timeout
 
 signal
 

Static Public Attributes

list arguments
 

Private Member Functions

def _expandReferenceFileName
 
def _CreateEclipseLaunch
 

Detailed Description

Standard Gaudi test.

Definition at line 1064 of file GaudiTest.py.

Member Function Documentation

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

Definition at line 1667 of file GaudiTest.py.

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

Definition at line 1224 of file GaudiTest.py.

1225  def _expandReferenceFileName(self, reffile):
1226  # if no file is passed, do nothing
1227  if not reffile:
1228  return ""
1229 
1230  # function to split an extension in constituents parts
1231  platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
1232 
1233  reference = os.path.normpath(os.path.expandvars(reffile))
1234  # old-style platform-specific reference name
1235  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1236  if os.path.isfile(spec_ref):
1237  reference = spec_ref
1238  else: # look for new-style platform specific reference files:
1239  # get all the files whose name start with the reference filename
1240  dirname, basename = os.path.split(reference)
1241  if not dirname: dirname = '.'
1242  head = basename + "."
1243  head_len = len(head)
1244  platform = platformSplit(self.GetPlatform())
1245  candidates = []
1246  for f in os.listdir(dirname):
1247  if f.startswith(head):
1248  req_plat = platformSplit(f[head_len:])
1249  if platform.issuperset(req_plat):
1250  candidates.append( (len(req_plat), f) )
1251  if candidates: # take the one with highest matching
1252  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1253  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1254  candidates.sort()
1255  reference = os.path.join(dirname, candidates[-1][1])
1256  return reference
def GaudiTest.GaudiExeTest.CheckHistosSummaries (   self,
  stdout,
  result,
  causes,
  dict = None,
  ignore = None 
)
Compare the TTree summaries in stdout with the ones in trees_dict or in
the reference file. By default ignore the size, compression and basket
fields.
The presence of TTree summaries when none is expected is not a failure.

Definition at line 1293 of file GaudiTest.py.

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

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

1448  def DumpEnvironment(self, result):
1449  """
1450  Add the content of the environment to the result object.
1451 
1452  Copied from the QMTest class of COOL.
1453  """
1454  vars = os.environ.keys()
1455  vars.sort()
1456  result['GaudiTest.environment'] = \
1457  result.Quote('\n'.join(["%s=%s"%(v,os.environ[v]) for v in vars]))
def GaudiTest.GaudiExeTest.GetPlatform (   self)
Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1202 of file GaudiTest.py.

1203  def GetPlatform(self):
1204  """
1205  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1206  """
1207  arch = "None"
1208  # check architecture name
1209  if "CMTCONFIG" in os.environ:
1210  arch = os.environ["CMTCONFIG"]
1211  elif "SCRAM_ARCH" in os.environ:
1212  arch = os.environ["SCRAM_ARCH"]
1213  return arch
def GaudiTest.GaudiExeTest.isWinPlatform (   self)
Return True if the current platform is Windows.

This function was needed because of the change in the CMTCONFIG format,
from win32_vc71_dbg to i686-winxp-vc9-dbg.

Definition at line 1214 of file GaudiTest.py.

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

Definition at line 1188 of file GaudiTest.py.

1189  def PlatformIsNotSupported(self, context, result):
1190  platform = self.GetPlatform()
1191  unsupported = [ re.compile(x)
1192  for x in [ str(y).strip()
1193  for y in self.unsupported_platforms ]
1194  if x
1195  ]
1196  for p_re in unsupported:
1197  if p_re.search(platform):
1198  result.SetOutcome(result.UNTESTED)
1199  result[result.CAUSE] = 'Platform not supported.'
1200  return True
1201  return False
def GaudiTest.GaudiExeTest.Run (   self,
  context,
  result 
)
Run the test.

'context' -- A 'Context' giving run-time parameters to the
test.

'result' -- A 'Result' object.  The outcome will be
'Result.PASS' when this method is called.  The 'result' may be
modified by this method to indicate outcomes other than
'Result.PASS' or to add annotations.

Definition at line 1458 of file GaudiTest.py.

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

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

Definition at line 1382 of file GaudiTest.py.

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

Definition at line 1325 of file GaudiTest.py.

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

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1396 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1067 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1392 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1492 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1393 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1480 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1491 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1598 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1529 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1519 of file GaudiTest.py.


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