| The Gaudi Framework v30r0 (c919700c)

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

- Namespace List
- Namespace Members

Classes | Functions | Variables
GaudiTesting.BaseTest Namespace Reference

## Classes
class | BaseTest
class | BasicOutputValidator
class | BlockSkipper
class | FilePreprocessor
class | FilePreprocessorSequence
class | LineSkipper
class | LineSorter
class | ReferenceFileValidator
class | RegexpReplacer
class | Result
class | SortGroupOfLines

## Functions
def | sanitize_for_xml (data)
def | dumpProcs (name)
def | kill_tree (ppid, sig)
def | ROOT6WorkAroundEnabled (id=None)
def | RationalizePath (p)
def | which (executable)
def | findTTreeSummaries (stdout)
def | cmpTreesDicts (reference, to_check, ignore=None)
def | getCmpFailingValues (reference, to_check, fail_path)
def | _parseTTreeSummary (lines, pos)
def | parseHistosSummary (lines, pos)
def | findHistosSummaries (stdout)
def | PlatformIsNotSupported (self, context, result)
def | GetPlatform (self)
def | isWinPlatform (self)

## Variables
| maskPointers = RegexpReplacer("0x[0-9a-fA-F]{4,16}", "0x########")
| normalizeDate
| normalizeEOL = FilePreprocessor()
| __processLine__
| skipEmptyLines = FilePreprocessor()
| normalizeExamples = maskPointers+normalizeDate
| lineSkipper
| regexps
| h_count_re

## Function Documentation

def GaudiTesting.BaseTest._parseTTreeSummary | ( |  | lines,
|  |  | pos
| ) |  |
| private

    Parse the TTree summary table in lines, starting from pos.
    Returns a tuple with the dictionary with the digested informations and the
    position of the first line after the summary.

Definition at line 1071 of file BaseTest.py.

1071 def _parseTTreeSummary(lines, pos):
1072 """
1073 Parse the TTree summary table in lines, starting from pos.
1074 Returns a tuple with the dictionary with the digested informations and the
1075 position of the first line after the summary.
1076 """
1077 result = {}
1078 i = pos + 1 # first line is a sequence of '*'
1079 count = len(lines)
1080
1081 def splitcols(l): return [f.strip() for f in l.strip("*\n").split(':', 2)]
1082
1083 def parseblock(ll):
1084 r = {}
1085 cols = splitcols(ll[0])
1086 r["Name"], r["Title"] = cols[1:]
1087
1088 cols = splitcols(ll[1])
1089 r["Entries"] = int(cols[1])
1090
1091 sizes = cols[2].split()
1092 r["Total size"] = int(sizes[2])
1093 if sizes[-1] == "memory":
1094 r["File size"] = 0
1095 else:
1096 r["File size"] = int(sizes[-1])
1097
1098 cols = splitcols(ll[2])
1099 sizes = cols[2].split()
1100 if cols[0] == "Baskets":
1101 r["Baskets"] = int(cols[1])
1102 r["Basket size"] = int(sizes[2])
1103 r["Compression"] = float(sizes[-1])
1104 return r
1105
1106 if i < (count - 3) and lines[i].startswith("*Tree"):
1107 result = parseblock(lines[i:i + 3])
1108 result["Branches"] = {}
1109 i += 4
1110 while i < (count - 3) and lines[i].startswith("*Br"):
1111 if i < (count - 2) and lines[i].startswith("*Branch "):
1112 # skip branch header
1113 i += 3
1114 continue
1115 branch = parseblock(lines[i:i + 3])
1116 result["Branches"][branch["Name"]] = branch
1117 i += 4
1118
1119 return (result, i)
1120
1121
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:1071

def GaudiTesting.BaseTest.cmpTreesDicts | ( |  | reference,
|  |  | to_check,
|  |  | ignore = `None`
| ) |  |

        Check that all the keys in reference are in to_check too, with the same value.
        If the value is a dict, the function is called recursively. to_check can
        contain more keys than reference, that will not be tested.
        The function returns at the first difference found.

Definition at line 1021 of file BaseTest.py.

1021 def cmpTreesDicts(reference, to_check, ignore=None):
1022 """
1023 Check that all the keys in reference are in to_check too, with the same value.
1024 If the value is a dict, the function is called recursively. to_check can
1025 contain more keys than reference, that will not be tested.
1026 The function returns at the first difference found.
1027 """
1028 fail_keys = []
1029 # filter the keys in the reference dictionary
1030 if ignore:
1031 ignore_re = re.compile(ignore)
1032 keys = [key for key in reference if not ignore_re.match(key)]
1033 else:
1034 keys = reference.keys()
1035 # loop over the keys (not ignored) in the reference dictionary
1036 for k in keys:
1037 if k in to_check: # the key must be in the dictionary to_check
1038 if (type(reference[k]) is dict) and (type(to_check[k]) is dict):
1039 # if both reference and to_check values are dictionaries,
1040 # recurse
1041 failed = fail_keys = cmpTreesDicts(
1042 reference[k], to_check[k], ignore)
1043 else:
1044 # compare the two values
1045 failed = to_check[k] != reference[k]
1046 else: # handle missing keys in the dictionary to check (i.e. failure)
1047 to_check[k] = None
1048 failed = True
1049 if failed:
1050 fail_keys.insert(0, k)
1051 break # exit from the loop at the first failure
1052 return fail_keys # return the list of keys bringing to the different values
1053
1054
GaudiTesting.BaseTest.cmpTreesDicts
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: BaseTest.py:1021
gaudirun.type
type
Definition: gaudirun.py:133

def GaudiTesting.BaseTest.dumpProcs | ( |  | name | ) |

    helper to debug GAUDI-1084, dump the list of processes

Definition at line 34 of file BaseTest.py.

34 def dumpProcs(name):
35 '''helper to debug GAUDI-1084, dump the list of processes'''
36 from getpass import getuser
37 if 'WORKSPACE' in os.environ:
38 p = Popen(['ps', '-fH', '-U', getuser()], stdout=PIPE)
39 with open(os.path.join(os.environ['WORKSPACE'], name), 'w') as f:
40 f.write(p.communicate()[0])
41
42
GaudiTesting.BaseTest.dumpProcs
def dumpProcs(name)
Definition: BaseTest.py:34

def GaudiTesting.BaseTest.findHistosSummaries | ( |  | stdout | ) |

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 1189 of file BaseTest.py.

1189 def findHistosSummaries(stdout):
1190 """
1191 Scan stdout to find ROOT TTree summaries and digest them.
1192 """
1193 outlines = stdout.splitlines()
1194 nlines = len(outlines) - 1
1195 summaries = {}
1196 global h_count_re
1197
1198 pos = 0
1199 while pos < nlines:
1200 summ = {}
1201 # find first line of block:
1202 match = h_count_re.search(outlines[pos])
1203 while pos < nlines and not match:
1204 pos += 1
1205 match = h_count_re.search(outlines[pos])
1206 if match:
1207 summ, pos = parseHistosSummary(outlines, pos)
1208 summaries.update(summ)
1209 return summaries
1210
1211
GaudiTesting.BaseTest.findHistosSummaries
def findHistosSummaries(stdout)
Definition: BaseTest.py:1189
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:1122

def GaudiTesting.BaseTest.findTTreeSummaries | ( |  | stdout | ) |

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 999 of file BaseTest.py.

999 def findTTreeSummaries(stdout):
1000 """
1001 Scan stdout to find ROOT TTree summaries and digest them.
1002 """
1003 stars = re.compile(r"^\*+$")
1004 outlines = stdout.splitlines()
1005 nlines = len(outlines)
1006 trees = {}
1007
1008 i = 0
1009 while i < nlines: # loop over the output
1010 # look for
1011 while i < nlines and not stars.match(outlines[i]):
1012 i += 1
1013 if i < nlines:
1014 tree, i = _parseTTreeSummary(outlines, i)
1015 if tree:
1016 trees[tree["Name"]] = tree
1017
1018 return trees
1019
1020
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:1071
GaudiTesting.BaseTest.findTTreeSummaries
def findTTreeSummaries(stdout)
Definition: BaseTest.py:999

def GaudiTesting.BaseTest.getCmpFailingValues | ( |  | reference,
|  |  | to_check,
|  |  | fail_path
| ) |  |

Definition at line 1055 of file BaseTest.py.

1055 def getCmpFailingValues(reference, to_check, fail_path):
1056 c = to_check
1057 r = reference
1058 for k in fail_path:
1059 c = c.get(k, None)
1060 r = r.get(k, None)
1061 if c is None or r is None:
1062 break # one of the dictionaries is not deep enough
1063 return (fail_path, r, c)
1064
1065
1066 # signature of the print-out of the histograms
GaudiTesting.BaseTest.getCmpFailingValues
def getCmpFailingValues(reference, to_check, fail_path)
Definition: BaseTest.py:1055

def GaudiTesting.BaseTest.GetPlatform | ( |  | self | ) |

        Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1224 of file BaseTest.py.

1224 def GetPlatform(self):
1225 """
1226 Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1227 """
1228 arch = "None"
1229 # check architecture name
1230 if "BINARY_TAG" in os.environ:
1231 arch = os.environ["BINARY_TAG"]
1232 elif "CMTCONFIG" in os.environ:
1233 arch = os.environ["CMTCONFIG"]
1234 elif "SCRAM_ARCH" in os.environ:
1235 arch = os.environ["SCRAM_ARCH"]
1236 return arch
1237
1238
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1224

def GaudiTesting.BaseTest.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 1239 of file BaseTest.py.

1239 def isWinPlatform(self):
1240 """
1241 Return True if the current platform is Windows.
1242
1243 This function was needed because of the change in the CMTCONFIG format,
1244 from win32_vc71_dbg to i686-winxp-vc9-dbg.
1245 """
1246 platform = GetPlatform(self)
1247 return "winxp" in platform or platform.startswith("win")
1248
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1224
GaudiTesting.BaseTest.isWinPlatform
def isWinPlatform(self)
Definition: BaseTest.py:1239

def GaudiTesting.BaseTest.kill_tree | ( |  | ppid,
|  |  | sig
| ) |  |

    Send a signal to a process and all its child processes (starting from the
    leaves).

Definition at line 43 of file BaseTest.py.

43 def kill_tree(ppid, sig):
44 '''
45 Send a signal to a process and all its child processes (starting from the
46 leaves).
47 '''
48 log = logging.getLogger('kill_tree')
49 ps_cmd = ['ps', '--no-headers', '-o', 'pid', '--ppid', str(ppid)]
50 get_children = Popen(ps_cmd, stdout=PIPE, stderr=PIPE)
51 children = map(int, get_children.communicate()[0].split())
52 for child in children:
53 kill_tree(child, sig)
54 try:
55 log.debug('killing process %d', ppid)
56 os.kill(ppid, sig)
57 except OSError, err:
58 if err.errno != 3: # No such process
59 raise
60 log.debug('no such process %d', ppid)
61
62 # -------------------------------------------------------------------------#
63
64
Containers::map
struct GAUDI_API map
Parametrisation class for map-like implementation.
Definition: KeyedObjectManager.h:26
GaudiTesting.BaseTest.kill_tree
def kill_tree(ppid, sig)
Definition: BaseTest.py:43

def GaudiTesting.BaseTest.parseHistosSummary | ( |  | lines,
|  |  | pos
| ) |  |

        Extract the histograms infos from the lines starting at pos.
        Returns the position of the first line after the summary block.

Definition at line 1122 of file BaseTest.py.

1122 def parseHistosSummary(lines, pos):
1123 """
1124 Extract the histograms infos from the lines starting at pos.
1125 Returns the position of the first line after the summary block.
1126 """
1127 global h_count_re
1128 h_table_head = re.compile(
1129 r'SUCCESS\s+List of booked (1D|2D|3D|1D profile|2D profile) histograms in directory\s+"(\w*)"')
1130 h_short_summ = re.compile(r"ID=([^\"]+)\s+\"([^\"]+)\"\s+(.*)")
1131
1132 nlines = len(lines)
1133
1134 # decode header
1135 m = h_count_re.search(lines[pos])
1136 name = m.group(1).strip()
1137 total = int(m.group(2))
1138 header = {}
1139 for k, v in [x.split("=") for x in m.group(3).split()]:
1140 header[k] = int(v)
1141 pos += 1
1142 header["Total"] = total
1143
1144 summ = {}
1145 while pos < nlines:
1146 m = h_table_head.search(lines[pos])
1147 if m:
1148 t, d = m.groups(1) # type and directory
1149 t = t.replace(" profile", "Prof")
1150 pos += 1
1151 if pos < nlines:
1152 l = lines[pos]
1153 else:
1154 l = ""
1155 cont = {}
1156 if l.startswith(" | ID"):
1157 # table format
1158 titles = [x.strip() for x in l.split("|")][1:]
1159 pos += 1
1160 while pos < nlines and lines[pos].startswith(" |"):
1161 l = lines[pos]
1162 values = [x.strip() for x in l.split("|")][1:]
1163 hcont = {}
1164 for i in range(len(titles)):
1165 hcont[titles[i]] = values[i]
1166 cont[hcont["ID"]] = hcont
1167 pos += 1
1168 elif l.startswith(" ID="):
1169 while pos < nlines and lines[pos].startswith(" ID="):
1170 values = [x.strip()
1171 for x in h_short_summ.search(lines[pos]).groups()]
1172 cont[values[0]] = values
1173 pos += 1
1174 else: # not interpreted
1175 raise RuntimeError(
1176 "Cannot understand line %d: '%s'" % (pos, l))
1177 if not d in summ:
1178 summ[d] = {}
1179 summ[d][t] = cont
1180 summ[d]["header"] = header
1181 else:
1182 break
1183 if not summ:
1184 # If the full table is not present, we use only the header
1185 summ[name] = {"header": header}
1186 return summ, pos
1187
1188
Gaudi::Functional::details::zip::range
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.
Definition: FunctionalDetails.h:85
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:1122

def GaudiTesting.BaseTest.PlatformIsNotSupported | ( |  | self,
|  |  | context,
|  |  | result
| ) |  |

Definition at line 1212 of file BaseTest.py.

1212 def PlatformIsNotSupported(self, context, result):
1213 platform = GetPlatform(self)
1214 unsupported = [re.compile(x) for x in [str(y).strip()
1215 for y in unsupported_platforms] if x]
1216 for p_re in unsupported:
1217 if p_re.search(platform):
1218 result.SetOutcome(result.UNTESTED)
1219 result[result.CAUSE] = 'Platform not supported.'
1220 return True
1221 return False
1222
1223
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1224
GaudiTesting.BaseTest.PlatformIsNotSupported
def PlatformIsNotSupported(self, context, result)
Definition: BaseTest.py:1212

def GaudiTesting.BaseTest.RationalizePath | ( |  | p | ) |

    Function used to normalize the used path

Definition at line 561 of file BaseTest.py.

561 def RationalizePath(p):
562 """
563 Function used to normalize the used path
564 """
565 newPath = os.path.normpath(os.path.expandvars(p))
566 if os.path.exists(newPath):
567 p = os.path.realpath(newPath)
568 return p
569
570
GaudiTesting.BaseTest.RationalizePath
def RationalizePath(p)
Definition: BaseTest.py:561

def GaudiTesting.BaseTest.ROOT6WorkAroundEnabled | ( |  | id = `None` | ) |

Definition at line 554 of file BaseTest.py.

554 def ROOT6WorkAroundEnabled(id=None):
555 # dummy implementation
556 return False
557
558 # --------------------------------- TOOLS ---------------------------------#
559
560
GaudiTesting.BaseTest.ROOT6WorkAroundEnabled
def ROOT6WorkAroundEnabled(id=None)
Definition: BaseTest.py:554

def GaudiTesting.BaseTest.sanitize_for_xml | ( |  | data | ) |

    Take a string with invalid ASCII/UTF characters and quote them so that the
    string can be used in an XML text.

    >>> sanitize_for_xml('this is \x1b')
    'this is [NON-XML-CHAR-0x1B]'

Definition at line 17 of file BaseTest.py.

17 def sanitize_for_xml(data):
18 '''
19 Take a string with invalid ASCII/UTF characters and quote them so that the
20 string can be used in an XML text.
21
22 >>> sanitize_for_xml('this is \x1b')
23 'this is [NON-XML-CHAR-0x1B]'
24 '''
25 bad_chars = re.compile(
26 u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]')
27
28 def quote(match):
29 'helper function'
30 return ''.join('[NON-XML-CHAR-0x%2X]' % ord(c) for c in match.group())
31 return bad_chars.sub(quote, data)
32
33
GaudiTesting.BaseTest.sanitize_for_xml
def sanitize_for_xml(data)
Definition: BaseTest.py:17

def GaudiTesting.BaseTest.which | ( |  | executable | ) |

    Locates an executable in the executables path ($PATH) and returns the full
    path to it.  An application is looked for with or without the '.exe' suffix.
    If the executable cannot be found, None is returned

Definition at line 571 of file BaseTest.py.

571 def which(executable):
572 """
573 Locates an executable in the executables path ($PATH) and returns the full
574 path to it. An application is looked for with or without the '.exe' suffix.
575 If the executable cannot be found, None is returned
576 """
577 if os.path.isabs(executable):
578 if not os.path.exists(executable):
579 if executable.endswith('.exe'):
580 if os.path.exists(executable[:-4]):
581 return executable[:-4]
582 else:
583 head, executable = os.path.split(executable)
584 else:
585 return executable
586 for d in os.environ.get("PATH").split(os.pathsep):
587 fullpath = os.path.join(d, executable)
588 if os.path.exists(fullpath):
589 return fullpath
590 if executable.endswith('.exe'):
591 return which(executable[:-4])
592 return None
593
594
595 # -------------------------------------------------------------------------#
596 # ----------------------------- Result Classe -----------------------------#
597 # -------------------------------------------------------------------------#
GaudiTesting.BaseTest.which
def which(executable)
Definition: BaseTest.py:571

## Variable Documentation

GaudiTesting.BaseTest.__processLine__
| private

Definition at line 795 of file BaseTest.py.

GaudiTesting.BaseTest.h_count_re

Initial value:
1 = re.compile(
2 r"^(.*)SUCCESS\s+Booked (\d+) Histogram\(s\) :\s+([\s\w=-]*)")

Definition at line 1067 of file BaseTest.py.

GaudiTesting.BaseTest.lineSkipper

Definition at line 872 of file BaseTest.py.

GaudiTesting.BaseTest.maskPointers = RegexpReplacer("0x[0-9a-fA-F]{4,16}", "0x########")

Definition at line 790 of file BaseTest.py.

GaudiTesting.BaseTest.normalizeDate

Initial value:
1 = RegexpReplacer(
2 "[0-2]?[0-9]:[0-5][0-9]:[0-5][0-9] [0-9]{4}[-/][01][0-9][-/][0-3][0-9][ A-Z]*",
3 "00:00:00 1970-01-01")
GaudiTesting.BaseTest.RegexpReplacer
Definition: BaseTest.py:767

Definition at line 791 of file BaseTest.py.

GaudiTesting.BaseTest.normalizeEOL = FilePreprocessor()

Definition at line 794 of file BaseTest.py.

tuple GaudiTesting.BaseTest.normalizeExamples = maskPointers+normalizeDate

Definition at line 847 of file BaseTest.py.

GaudiTesting.BaseTest.regexps

Definition at line 951 of file BaseTest.py.

GaudiTesting.BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 797 of file BaseTest.py.