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

Member Function Documentation

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

Definition at line 1665 of file GaudiTest.py.

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

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

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

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

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

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

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

Definition at line 1186 of file GaudiTest.py.

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

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

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

Definition at line 1380 of file GaudiTest.py.

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

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

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1394 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 1065 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1390 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1490 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1391 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1478 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1489 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1596 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1527 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1517 of file GaudiTest.py.


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