Gaudi Framework, version v23r9

Home   Generated: Thu Jul 18 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 990 of file GaudiTest.py.

Member Function Documentation

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

Definition at line 1593 of file GaudiTest.py.

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

Definition at line 1150 of file GaudiTest.py.

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

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

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

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

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

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

Definition at line 1114 of file GaudiTest.py.

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

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

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

Definition at line 1308 of file GaudiTest.py.

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

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

Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1322 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
static

Definition at line 993 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1318 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1418 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1319 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1406 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1417 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1524 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1455 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1445 of file GaudiTest.py.


The documentation for this class was generated from the following file:
Generated at Thu Jul 18 2013 12:18:15 for Gaudi Framework, version v23r9 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004