Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | List of all members
GaudiTest.GaudiExeTest Class Reference
Inheritance diagram for GaudiTest.GaudiExeTest:
Inheritance graph
[legend]
Collaboration diagram for GaudiTest.GaudiExeTest:
Collaboration graph
[legend]

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

Member Function Documentation

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

Definition at line 1598 of file GaudiTest.py.

1599  def _CreateEclipseLaunch(self, prog, args, destdir = None):
1600  # Find the project name used in ecplise.
1601  # The name is in a file called ".project" in one of the parent directories
1602  projbasedir = os.path.normpath(destdir)
1603  while not os.path.exists(os.path.join(projbasedir, ".project")):
1604  oldprojdir = projbasedir
1605  projbasedir = os.path.normpath(os.path.join(projbasedir, os.pardir))
1606  # FIXME: the root level is invariant when trying to go up one level,
1607  # but it must be cheched on windows
1608  if oldprojdir == projbasedir:
1609  # If we cannot find a .project, so no point in creating a .launch file
1610  return
1611  # Ensure that we have a place where to write.
1612  if not os.path.exists(destdir):
1613  os.makedirs(destdir)
1614  # Use ElementTree to parse the XML file
1615  from xml.etree import ElementTree as ET
1616  t = ET.parse(os.path.join(projbasedir, ".project"))
1617  projectName = t.find("name").text
1618 
1619  # prepare the name/path of the generated file
1620  destfile = "%s.launch" % self._Runnable__id
1621  if destdir:
1622  destfile = os.path.join(destdir, destfile)
1623 
1624  if self.options.strip():
1625  # this means we have some custom options in the qmt file, so we have
1626  # to copy them from the temporary file at the end of the arguments
1627  # in another file
1628  tempfile = args.pop()
1629  optsfile = destfile + os.path.splitext(tempfile)[1]
1630  shutil.copyfile(tempfile, optsfile)
1631  args.append(optsfile)
1632 
1633  # prepare the data to insert in the XML file
1634  from xml.sax.saxutils import quoteattr # useful to quote XML special chars
1635  data = {}
1636  # Note: the "quoteattr(k)" is not needed because special chars cannot be part of a variable name,
1637  # but it doesn't harm.
1638  data["environment"] = "\n".join(['<mapEntry key=%s value=%s/>' % (quoteattr(k), quoteattr(v))
1639  for k, v in os.environ.iteritems()
1640  if k not in ('MAKEOVERRIDES', 'MAKEFLAGS', 'MAKELEVEL')])
1641 
1642  data["exec"] = which(prog) or prog
1643  if os.path.basename(data["exec"]).lower().startswith("python"):
1644  data["stopAtMain"] = "false" # do not stop at main when debugging Python scripts
1645  else:
1646  data["stopAtMain"] = "true"
1647 
1648  data["args"] = "&#10;".join(map(rationalizepath, args))
1649  if self.isWinPlatform():
1650  data["args"] = "&#10;".join(["/debugexe"] + map(rationalizepath, [data["exec"]] + args))
1651  data["exec"] = which("vcexpress.exe")
1652 
1653  if not self.use_temp_dir:
1654  data["workdir"] = os.getcwd()
1655  else:
1656  # If the test is using a tmporary directory, it is better to run it
1657  # in the same directory as the .launch file when debugged in eclipse
1658  data["workdir"] = destdir
1659 
1660  data["project"] = projectName.strip()
1661 
1662  # Template for the XML file, based on eclipse 3.4
1663  xml = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1664 <launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
1665 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB" value="true"/>
1666 <listAttribute key="org.eclipse.cdt.debug.mi.core.AUTO_SOLIB_LIST"/>
1667 <stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="gdb"/>
1668 <stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=".gdbinit"/>
1669 <listAttribute key="org.eclipse.cdt.debug.mi.core.SOLIB_PATH"/>
1670 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.STOP_ON_SOLIB_EVENTS" value="false"/>
1671 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
1672 <stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="org.eclipse.cdt.debug.mi.core.standardCommandFactory"/>
1673 <stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
1674 <booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
1675 <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
1676 <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
1677 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="org.eclipse.cdt.debug.mi.core.CDebuggerNew"/>
1678 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
1679 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
1680 <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="%(stopAtMain)s"/>
1681 <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
1682 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
1683 <booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
1684 <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;"/>
1685 <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;"/>
1686 <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;"/>
1687 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="%(args)s"/>
1688 <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="%(exec)s"/>
1689 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="%(project)s"/>
1690 <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
1691 <stringAttribute key="org.eclipse.cdt.launch.WORKING_DIRECTORY" value="%(workdir)s"/>
1692 <booleanAttribute key="org.eclipse.cdt.launch.ui.ApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
1693 <booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
1694 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
1695 <listEntry value="/%(project)s"/>
1696 </listAttribute>
1697 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
1698 <listEntry value="4"/>
1699 </listAttribute>
1700 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
1701 <mapAttribute key="org.eclipse.debug.core.environmentVariables">
1702 %(environment)s
1703 </mapAttribute>
1704 <mapAttribute key="org.eclipse.debug.core.preferred_launchers">
1705 <mapEntry key="[debug]" value="org.eclipse.cdt.cdi.launch.localCLaunch"/>
1706 </mapAttribute>
1707 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
1708 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
1709 </listAttribute>
1710 </launchConfiguration>
1711 """ % data
1712 
1713  # Write the output file
1714  open(destfile, "w").write(xml)
1715  #open(destfile + "_copy.xml", "w").write(xml)
1716 
1717 
try:
def GaudiTest.GaudiExeTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 1155 of file GaudiTest.py.

1156  def _expandReferenceFileName(self, reffile):
1157  # if no file is passed, do nothing
1158  if not reffile:
1159  return ""
1160 
1161  # function to split an extension in constituents parts
1162  platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
1163 
1164  reference = os.path.normpath(os.path.expandvars(reffile))
1165  # old-style platform-specific reference name
1166  spec_ref = reference[:-3] + self.GetPlatform()[0:3] + reference[-3:]
1167  if os.path.isfile(spec_ref):
1168  reference = spec_ref
1169  else: # look for new-style platform specific reference files:
1170  # get all the files whose name start with the reference filename
1171  dirname, basename = os.path.split(reference)
1172  if not dirname: dirname = '.'
1173  head = basename + "."
1174  head_len = len(head)
1175  platform = platformSplit(self.GetPlatform())
1176  candidates = []
1177  for f in os.listdir(dirname):
1178  if f.startswith(head):
1179  req_plat = platformSplit(f[head_len:])
1180  if platform.issuperset(req_plat):
1181  candidates.append( (len(req_plat), f) )
1182  if candidates: # take the one with highest matching
1183  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1184  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1185  candidates.sort()
1186  reference = os.path.join(dirname, candidates[-1][1])
1187  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 1224 of file GaudiTest.py.

1225  ignore = None):
1226  """
1227  Compare the TTree summaries in stdout with the ones in trees_dict or in
1228  the reference file. By default ignore the size, compression and basket
1229  fields.
1230  The presence of TTree summaries when none is expected is not a failure.
1231  """
1232  if dict is None:
1233  reference = self._expandReferenceFileName(self.reference)
1234  # call the validator if the file exists
1235  if reference and os.path.isfile(reference):
1236  dict = findHistosSummaries(open(reference).read())
1237  else:
1238  dict = {}
1239 
1240  from pprint import PrettyPrinter
1241  pp = PrettyPrinter()
1242  if dict:
1243  result["GaudiTest.Histos.expected"] = result.Quote(pp.pformat(dict))
1244  if ignore:
1245  result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1246 
1247  histos = findHistosSummaries(stdout)
1248  failed = cmpTreesDicts(dict, histos, ignore)
1249  if failed:
1250  causes.append("histos summaries")
1251  msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1252  result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1253  result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1254 
1255  return causes
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 1190 of file GaudiTest.py.

1191  ignore = r"Basket|.*size|Compression"):
1192  """
1193  Compare the TTree summaries in stdout with the ones in trees_dict or in
1194  the reference file. By default ignore the size, compression and basket
1195  fields.
1196  The presence of TTree summaries when none is expected is not a failure.
1197  """
1198  if trees_dict is None:
1199  reference = self._expandReferenceFileName(self.reference)
1200  # call the validator if the file exists
1201  if reference and os.path.isfile(reference):
1202  trees_dict = findTTreeSummaries(open(reference).read())
1203  else:
1204  trees_dict = {}
1205 
1206  from pprint import PrettyPrinter
1207  pp = PrettyPrinter()
1208  if trees_dict:
1209  result["GaudiTest.TTrees.expected"] = result.Quote(pp.pformat(trees_dict))
1210  if ignore:
1211  result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1212 
1213  trees = findTTreeSummaries(stdout)
1214  failed = cmpTreesDicts(trees_dict, trees, ignore)
1215  if failed:
1216  causes.append("trees summaries")
1217  msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees, failed)
1218  result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1219  result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1220 
1221  return causes
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 1378 of file GaudiTest.py.

1379  def DumpEnvironment(self, result):
1380  """
1381  Add the content of the environment to the result object.
1382 
1383  Copied from the QMTest class of COOL.
1384  """
1385  vars = os.environ.keys()
1386  vars.sort()
1387  result['GaudiTest.environment'] = \
1388  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 1133 of file GaudiTest.py.

1134  def GetPlatform(self):
1135  """
1136  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1137  """
1138  arch = "None"
1139  # check architecture name
1140  if "CMTCONFIG" in os.environ:
1141  arch = os.environ["CMTCONFIG"]
1142  elif "SCRAM_ARCH" in os.environ:
1143  arch = os.environ["SCRAM_ARCH"]
1144  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 1145 of file GaudiTest.py.

1146  def isWinPlatform(self):
1147  """
1148  Return True if the current platform is Windows.
1149 
1150  This function was needed because of the change in the CMTCONFIG format,
1151  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1152  """
1153  platform = self.GetPlatform()
1154  return "winxp" in platform or platform.startswith("win")
def GaudiTest.GaudiExeTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1119 of file GaudiTest.py.

1120  def PlatformIsNotSupported(self, context, result):
1121  platform = self.GetPlatform()
1122  unsupported = [ re.compile(x)
1123  for x in [ str(y).strip()
1124  for y in self.unsupported_platforms ]
1125  if x
1126  ]
1127  for p_re in unsupported:
1128  if p_re.search(platform):
1129  result.SetOutcome(result.UNTESTED)
1130  result[result.CAUSE] = 'Platform not supported.'
1131  return True
1132  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 1389 of file GaudiTest.py.

1390  def Run(self, context, result):
1391  """Run the test.
1392 
1393  'context' -- A 'Context' giving run-time parameters to the
1394  test.
1395 
1396  'result' -- A 'Result' object. The outcome will be
1397  'Result.PASS' when this method is called. The 'result' may be
1398  modified by this method to indicate outcomes other than
1399  'Result.PASS' or to add annotations."""
1400 
1401  # Check if the platform is supported
1402  if self.PlatformIsNotSupported(context, result):
1403  return
1404 
1405  # Prepare program name and arguments (expanding variables, and converting to absolute)
1406  if self.program:
1407  prog = rationalizepath(self.program)
1408  elif "GAUDIEXE" in os.environ:
1409  prog = os.environ["GAUDIEXE"]
1410  else:
1411  prog = "Gaudi.exe"
1412  self.program = prog
1413 
1414  dummy, prog_ext = os.path.splitext(prog)
1415  if prog_ext not in [ ".exe", ".py", ".bat" ] and self.isWinPlatform():
1416  prog += ".exe"
1417  prog_ext = ".exe"
1418 
1419  prog = which(prog) or prog
1420 
1421  # Convert paths to absolute paths in arguments and reference files
1422  args = map(rationalizepath, self.args)
1425 
1426 
1427  # check if the user provided inline options
1428  tmpfile = None
1429  if self.options.strip():
1430  ext = ".opts"
1431  if re.search(r"from\s+Gaudi.Configuration\s+import\s+\*|from\s+Configurables\s+import", self.options):
1432  ext = ".py"
1433  tmpfile = TempFile(ext)
1434  tmpfile.writelines("\n".join(self.options.splitlines()))
1435  tmpfile.flush()
1436  args.append(tmpfile.name)
1437  result["GaudiTest.options"] = result.Quote(self.options)
1438 
1439  # if the program is a python file, execute it through python
1440  if prog_ext == ".py":
1441  args.insert(0,prog)
1442  if self.isWinPlatform():
1443  prog = which("python.exe") or "python.exe"
1444  else:
1445  prog = which("python") or "python"
1446 
1447  # Change to the working directory if specified or to the default temporary
1448  origdir = os.getcwd()
1449  if self.workdir:
1450  os.chdir(str(os.path.normpath(os.path.expandvars(self.workdir))))
1451  elif self.use_temp_dir == "true":
1452  if "QMTEST_TMPDIR" in os.environ:
1453  qmtest_tmpdir = os.environ["QMTEST_TMPDIR"]
1454  if not os.path.exists(qmtest_tmpdir):
1455  os.makedirs(qmtest_tmpdir)
1456  os.chdir(qmtest_tmpdir)
1457  elif "qmtest.tmpdir" in context:
1458  os.chdir(context["qmtest.tmpdir"])
1459 
1460  if "QMTEST_IGNORE_TIMEOUT" not in os.environ:
1461  self.timeout = max(self.timeout,600)
1462  else:
1463  self.timeout = -1
1464 
1465  try:
1466  # Generate eclipse.org debug launcher for the test
1467  self._CreateEclipseLaunch(prog, args, destdir = os.path.join(origdir, '.eclipse'))
1468  # Run the test
1469  self.RunProgram(prog,
1470  [ prog ] + args,
1471  context, result)
1472  # Record the content of the enfironment for failing tests
1473  if result.GetOutcome() not in [ result.PASS ]:
1474  self.DumpEnvironment(result)
1475  finally:
1476  # revert to the original directory
1477  os.chdir(origdir)
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 1478 of file GaudiTest.py.

1479  def RunProgram(self, program, arguments, context, result):
1480  """Run the 'program'.
1481 
1482  'program' -- The path to the program to run.
1483 
1484  'arguments' -- A list of the arguments to the program. This
1485  list must contain a first argument corresponding to 'argv[0]'.
1486 
1487  'context' -- A 'Context' giving run-time parameters to the
1488  test.
1489 
1490  'result' -- A 'Result' object. The outcome will be
1491  'Result.PASS' when this method is called. The 'result' may be
1492  modified by this method to indicate outcomes other than
1493  'Result.PASS' or to add annotations.
1494 
1495  @attention: This method has been copied from command.ExecTestBase
1496  (QMTest 2.3.0) and modified to keep stdout and stderr
1497  for tests that have been terminated by a signal.
1498  (Fundamental for debugging in the Application Area)
1499  """
1500 
1501  # Construct the environment.
1502  environment = self.MakeEnvironment(context)
1503  # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
1504  if "slc6" in environment.get('CMTCONFIG', ''):
1505  environment['TERM'] = 'dumb'
1506  # Create the executable.
1507  if self.timeout >= 0:
1508  timeout = self.timeout
1509  else:
1510  # If no timeout was specified, we sill run this process in a
1511  # separate process group and kill the entire process group
1512  # when the child is done executing. That means that
1513  # orphaned child processes created by the test will be
1514  # cleaned up.
1515  timeout = -2
1516  e = GaudiFilterExecutable(self.stdin, timeout)
1517  # Run it.
1518  exit_status = e.Run(arguments, environment, path = program)
1519  # Get the stack trace from the temporary file (if present)
1520  if e.stack_trace_file and os.path.exists(e.stack_trace_file):
1521  stack_trace = open(e.stack_trace_file).read()
1522  os.remove(e.stack_trace_file)
1523  else:
1524  stack_trace = None
1525  if stack_trace:
1526  result["ExecTest.stack_trace"] = result.Quote(stack_trace)
1527 
1528  # If the process terminated normally, check the outputs.
1529  if (sys.platform == "win32" or os.WIFEXITED(exit_status)
1530  or self.signal == os.WTERMSIG(exit_status)):
1531  # There are no causes of failure yet.
1532  causes = []
1533  # The target program terminated normally. Extract the
1534  # exit code, if this test checks it.
1535  if self.exit_code is None:
1536  exit_code = None
1537  elif sys.platform == "win32":
1538  exit_code = exit_status
1539  else:
1540  exit_code = os.WEXITSTATUS(exit_status)
1541  # Get the output generated by the program.
1542  stdout = e.stdout
1543  stderr = e.stderr
1544  # Record the results.
1545  result["ExecTest.exit_code"] = str(exit_code)
1546  result["ExecTest.stdout"] = result.Quote(stdout)
1547  result["ExecTest.stderr"] = result.Quote(stderr)
1548  # Check to see if the exit code matches.
1549  if exit_code != self.exit_code:
1550  causes.append("exit_code")
1551  result["ExecTest.expected_exit_code"] \
1552  = str(self.exit_code)
1553  # Validate the output.
1554  causes += self.ValidateOutput(stdout, stderr, result)
1555  # If anything went wrong, the test failed.
1556  if causes:
1557  result.Fail("Unexpected %s." % string.join(causes, ", "))
1558  elif os.WIFSIGNALED(exit_status):
1559  # The target program terminated with a signal. Construe
1560  # that as a test failure.
1561  signal_number = str(os.WTERMSIG(exit_status))
1562  if not stack_trace:
1563  result.Fail("Program terminated by signal.")
1564  else:
1565  # The presence of stack_trace means tha we stopped the job because
1566  # of a time-out
1567  result.Fail("Exceeded time limit (%ds), terminated." % timeout)
1568  result["ExecTest.signal_number"] = signal_number
1569  result["ExecTest.stdout"] = result.Quote(e.stdout)
1570  result["ExecTest.stderr"] = result.Quote(e.stderr)
1571  if self.signal:
1572  result["ExecTest.expected_signal_number"] = str(self.signal)
1573  elif os.WIFSTOPPED(exit_status):
1574  # The target program was stopped. Construe that as a
1575  # test failure.
1576  signal_number = str(os.WSTOPSIG(exit_status))
1577  if not stack_trace:
1578  result.Fail("Program stopped by signal.")
1579  else:
1580  # The presence of stack_trace means tha we stopped the job because
1581  # of a time-out
1582  result.Fail("Exceeded time limit (%ds), stopped." % timeout)
1583  result["ExecTest.signal_number"] = signal_number
1584  result["ExecTest.stdout"] = result.Quote(e.stdout)
1585  result["ExecTest.stderr"] = result.Quote(e.stderr)
1586  else:
1587  # The target program terminated abnormally in some other
1588  # manner. (This shouldn't normally happen...)
1589  result.Fail("Program did not terminate normally.")
1590 
1591  # Marco Cl.: This is a special trick to fix a "problem" with the output
1592  # of gaudi jobs when they use colors
1593  esc = '\x1b'
1594  repr_esc = '\\x1b'
1595  result["ExecTest.stdout"] = result["ExecTest.stdout"].replace(esc,repr_esc)
1596  # TODO: (MCl) improve the hack for colors in standard output
1597  # may be converting them to HTML tags
def GaudiTest.GaudiExeTest.ValidateOutput (   self,
  stdout,
  stderr,
  result 
)

Definition at line 1313 of file GaudiTest.py.

1314  def ValidateOutput(self, stdout, stderr, result):
1315  causes = []
1316  # if the test definition contains a custom validator, use it
1317  if self.validator.strip() != "":
1318  class CallWrapper(object):
1319  """
1320  Small wrapper class to dynamically bind some default arguments
1321  to a callable.
1322  """
1323  def __init__(self, callable, extra_args = {}):
1324  self.callable = callable
1325  self.extra_args = extra_args
1326  # get the list of names of positional arguments
1327  from inspect import getargspec
1328  self.args_order = getargspec(callable)[0]
1329  # Remove "self" from the list of positional arguments
1330  # since it is added automatically
1331  if self.args_order[0] == "self":
1332  del self.args_order[0]
1333  def __call__(self, *args, **kwargs):
1334  # Check which positional arguments are used
1335  positional = self.args_order[:len(args)]
1336 
1337  kwargs = dict(kwargs) # copy the arguments dictionary
1338  for a in self.extra_args:
1339  # use "extra_args" for the arguments not specified as
1340  # positional or keyword
1341  if a not in positional and a not in kwargs:
1342  kwargs[a] = self.extra_args[a]
1343  return apply(self.callable, args, kwargs)
1344  # local names to be exposed in the script
1345  exported_symbols = {"self":self,
1346  "stdout":stdout,
1347  "stderr":stderr,
1348  "result":result,
1349  "causes":causes,
1350  "findReferenceBlock":
1351  CallWrapper(findReferenceBlock, {"stdout":stdout,
1352  "result":result,
1353  "causes":causes}),
1354  "validateWithReference":
1355  CallWrapper(self.ValidateWithReference, {"stdout":stdout,
1356  "stderr":stderr,
1357  "result":result,
1358  "causes":causes}),
1359  "countErrorLines":
1360  CallWrapper(countErrorLines, {"stdout":stdout,
1361  "result":result,
1362  "causes":causes}),
1363  "checkTTreesSummaries":
1364  CallWrapper(self.CheckTTreesSummaries, {"stdout":stdout,
1365  "result":result,
1366  "causes":causes}),
1367  "checkHistosSummaries":
1368  CallWrapper(self.CheckHistosSummaries, {"stdout":stdout,
1369  "result":result,
1370  "causes":causes}),
1371 
1372  }
1373  exec self.validator in globals(), exported_symbols
1374  else:
1375  self.ValidateWithReference(stdout, stderr, result, causes)
1376 
1377  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 1256 of file GaudiTest.py.

1257  def ValidateWithReference(self, stdout, stderr, result, causes, preproc = None):
1258  """
1259  Default validation action: compare standard output and error to the
1260  reference files.
1261  """
1262  # set the default output preprocessor
1263  if preproc is None:
1264  preproc = normalizeExamples
1265  # check standard output
1266  reference = self._expandReferenceFileName(self.reference)
1267  # call the validator if the file exists
1268  if reference and os.path.isfile(reference):
1269  result["GaudiTest.output_reference"] = reference
1270  causes += ReferenceFileValidator(reference,
1271  "standard output",
1272  "GaudiTest.output_diff",
1273  preproc = preproc)(stdout, result)
1274 
1275  # Compare TTree summaries
1276  causes = self.CheckTTreesSummaries(stdout, result, causes)
1277  causes = self.CheckHistosSummaries(stdout, result, causes)
1278 
1279  if causes: # Write a new reference file for stdout
1280  try:
1281  newref = open(reference + ".new","w")
1282  # sanitize newlines
1283  for l in stdout.splitlines():
1284  newref.write(l.rstrip() + '\n')
1285  del newref # flush and close
1286  except IOError:
1287  # Ignore IO errors when trying to update reference files
1288  # because we may be in a read-only filesystem
1289  pass
1290 
1291  # check standard error
1292  reference = self._expandReferenceFileName(self.error_reference)
1293  # call the validator if we have a file to use
1294  if reference and os.path.isfile(reference):
1295  result["GaudiTest.error_reference"] = reference
1296  newcauses = ReferenceFileValidator(reference,
1297  "standard error",
1298  "GaudiTest.error_diff",
1299  preproc = preproc)(stderr, result)
1300  causes += newcauses
1301  if newcauses: # Write a new reference file for stdedd
1302  newref = open(reference + ".new","w")
1303  # sanitize newlines
1304  for l in stderr.splitlines():
1305  newref.write(l.rstrip() + '\n')
1306  del newref # flush and close
1307  else:
1308  causes += BasicOutputValidator(self.stderr,
1309  "standard error",
1310  "ExecTest.expected_stderr")(stderr, result)
1311 
1312  return causes

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1327 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 998 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1323 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1423 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1324 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1411 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1422 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1529 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1460 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1450 of file GaudiTest.py.


The documentation for this class was generated from the following file:
Generated at Wed Dec 4 2013 14:33:23 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004