| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

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:
[legend]
Collaboration diagram for GaudiTest.GaudiExeTest:
[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 1049 of file GaudiTest.py.

## Member Function Documentation

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

Definition at line 1652 of file GaudiTest.py.

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

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

Definition at line 1209 of file GaudiTest.py.

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

1278
1279 ignore = None):
1280 """
1281 Compare the TTree summaries in stdout with the ones in trees_dict or in
1282 the reference file. By default ignore the size, compression and basket
1283 fields.
1284 The presence of TTree summaries when none is expected is not a failure.
1285 """
1286 if dict is None:
1287 reference = self._expandReferenceFileName(self.reference)
1288 # call the validator if the file exists
1289 if reference and os.path.isfile(reference):
1290 dict = findHistosSummaries(open(reference).read())
1291 else:
1292 dict = {}
1293
1294 from pprint import PrettyPrinter
1295 pp = PrettyPrinter()
1296 if dict:
1297 result["GaudiTest.Histos.expected"] = result.Quote(pp.pformat(dict))
1298 if ignore:
1299 result["GaudiTest.Histos.ignore"] = result.Quote(ignore)
1300
1301 histos = findHistosSummaries(stdout)
1302 failed = cmpTreesDicts(dict, histos, ignore)
1303 if failed:
1304 causes.append("histos summaries")
1305 msg = "%s: %s != %s" % getCmpFailingValues(dict, histos, failed)
1306 result["GaudiTest.Histos.failure_on"] = result.Quote(msg)
1307 result["GaudiTest.Histos.found"] = result.Quote(pp.pformat(histos))
1308
1309 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 1244 of file GaudiTest.py.

1244
1245 ignore = r"Basket|.*size|Compression"):
1246 """
1247 Compare the TTree summaries in stdout with the ones in trees_dict or in
1248 the reference file. By default ignore the size, compression and basket
1249 fields.
1250 The presence of TTree summaries when none is expected is not a failure.
1251 """
1252 if trees_dict is None:
1253 reference = self._expandReferenceFileName(self.reference)
1254 # call the validator if the file exists
1255 if reference and os.path.isfile(reference):
1256 trees_dict = findTTreeSummaries(open(reference).read())
1257 else:
1258 trees_dict = {}
1259
1260 from pprint import PrettyPrinter
1261 pp = PrettyPrinter()
1262 if trees_dict:
1263 result["GaudiTest.TTrees.expected"] = result.Quote(pp.pformat(trees_dict))
1264 if ignore:
1265 result["GaudiTest.TTrees.ignore"] = result.Quote(ignore)
1266
1267 trees = findTTreeSummaries(stdout)
1268 failed = cmpTreesDicts(trees_dict, trees, ignore)
1269 if failed:
1270 causes.append("trees summaries")
1271 msg = "%s: %s != %s" % getCmpFailingValues(trees_dict, trees, failed)
1272 result["GaudiTest.TTrees.failure_on"] = result.Quote(msg)
1273 result["GaudiTest.TTrees.found"] = result.Quote(pp.pformat(trees))
1274
1275 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 1432 of file GaudiTest.py.

1432
1433 def DumpEnvironment(self, result):
1434 """
1435 Add the content of the environment to the result object.
1436
1437 Copied from the QMTest class of COOL.
1438 """
1439 vars = os.environ.keys()
1440 vars.sort()
1441 result['GaudiTest.environment'] = \
1442 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 1187 of file GaudiTest.py.

1187
1188 def GetPlatform(self):
1189 """
1190 Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1191 """
1192 arch = "None"
1193 # check architecture name
1194 if "CMTCONFIG" in os.environ:
1195 arch = os.environ["CMTCONFIG"]
1196 elif "SCRAM_ARCH" in os.environ:
1197 arch = os.environ["SCRAM_ARCH"]
1198 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 1199 of file GaudiTest.py.

1199
1200 def isWinPlatform(self):
1201 """
1202 Return True if the current platform is Windows.
1203
1204 This function was needed because of the change in the CMTCONFIG format,
1205 from win32_vc71_dbg to i686-winxp-vc9-dbg.
1206 """
1207 platform = self.GetPlatform()
1208 return "winxp" in platform or platform.startswith("win")

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

Definition at line 1173 of file GaudiTest.py.

1173
1174 def PlatformIsNotSupported(self, context, result):
1175 platform = self.GetPlatform()
1176 unsupported = [ re.compile(x)
1177 for x in [ str(y).strip()
1178 for y in self.unsupported_platforms ]
1179 if x
1180 ]
1181 for p_re in unsupported:
1182 if p_re.search(platform):
1183 result.SetOutcome(result.UNTESTED)
1184 result[result.CAUSE] = 'Platform not supported.'
1185 return True
1186 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 1443 of file GaudiTest.py.

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

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

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

Definition at line 1367 of file GaudiTest.py.

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

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

## Member Data Documentation

GaudiTest.GaudiExeTest.args_order

Definition at line 1381 of file GaudiTest.py.

list GaudiTest.GaudiExeTest.arguments
| static

Definition at line 1052 of file GaudiTest.py.

GaudiTest.GaudiExeTest.callable

Definition at line 1377 of file GaudiTest.py.

GaudiTest.GaudiExeTest.error_reference

Definition at line 1477 of file GaudiTest.py.

GaudiTest.GaudiExeTest.extra_args

Definition at line 1378 of file GaudiTest.py.

GaudiTest.GaudiExeTest.program

Definition at line 1465 of file GaudiTest.py.

GaudiTest.GaudiExeTest.reference

Definition at line 1476 of file GaudiTest.py.

GaudiTest.GaudiExeTest.signal

Definition at line 1583 of file GaudiTest.py.

GaudiTest.GaudiExeTest.timeout

Definition at line 1514 of file GaudiTest.py.

GaudiTest.GaudiExeTest.use_temp_dir

Definition at line 1504 of file GaudiTest.py.

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

- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v25r0/GaudiPolicy/qmtest_classes/GaudiTest.py