| The Gaudi Framework v29r0 (ff2e7097)

- 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 1048 of file BaseTest.py.

1048 def _parseTTreeSummary(lines, pos):
1049 """
1050 Parse the TTree summary table in lines, starting from pos.
1051 Returns a tuple with the dictionary with the digested informations and the
1052 position of the first line after the summary.
1053 """
1054 result = {}
1055 i = pos + 1 # first line is a sequence of '*'
1056 count = len(lines)
1057
1058 def splitcols(l): return [f.strip() for f in l.strip("*\n").split(':', 2)]
1059
1060 def parseblock(ll):
1061 r = {}
1062 cols = splitcols(ll[0])
1063 r["Name"], r["Title"] = cols[1:]
1064
1065 cols = splitcols(ll[1])
1066 r["Entries"] = int(cols[1])
1067
1068 sizes = cols[2].split()
1069 r["Total size"] = int(sizes[2])
1070 if sizes[-1] == "memory":
1071 r["File size"] = 0
1072 else:
1073 r["File size"] = int(sizes[-1])
1074
1075 cols = splitcols(ll[2])
1076 sizes = cols[2].split()
1077 if cols[0] == "Baskets":
1078 r["Baskets"] = int(cols[1])
1079 r["Basket size"] = int(sizes[2])
1080 r["Compression"] = float(sizes[-1])
1081 return r
1082
1083 if i < (count - 3) and lines[i].startswith("*Tree"):
1084 result = parseblock(lines[i:i + 3])
1085 result["Branches"] = {}
1086 i += 4
1087 while i < (count - 3) and lines[i].startswith("*Br"):
1088 if i < (count - 2) and lines[i].startswith("*Branch "):
1089 # skip branch header
1090 i += 3
1091 continue
1092 branch = parseblock(lines[i:i + 3])
1093 result["Branches"][branch["Name"]] = branch
1094 i += 4
1095
1096 return (result, i)
1097
1098
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:1048

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 999 of file BaseTest.py.

999 def cmpTreesDicts(reference, to_check, ignore=None):
1000 """
1001 Check that all the keys in reference are in to_check too, with the same value.
1002 If the value is a dict, the function is called recursively. to_check can
1003 contain more keys than reference, that will not be tested.
1004 The function returns at the first difference found.
1005 """
1006 fail_keys = []
1007 # filter the keys in the reference dictionary
1008 if ignore:
1009 ignore_re = re.compile(ignore)
1010 keys = [key for key in reference if not ignore_re.match(key)]
1011 else:
1012 keys = reference.keys()
1013 # loop over the keys (not ignored) in the reference dictionary
1014 for k in keys:
1015 if k in to_check: # the key must be in the dictionary to_check
1016 if (type(reference[k]) is dict) and (type(to_check[k]) is dict):
1017 # if both reference and to_check values are dictionaries, recurse
1018 failed = fail_keys = cmpTreesDicts(
1019 reference[k], to_check[k], ignore)
1020 else:
1021 # compare the two values
1022 failed = to_check[k] != reference[k]
1023 else: # handle missing keys in the dictionary to check (i.e. failure)
1024 to_check[k] = None
1025 failed = True
1026 if failed:
1027 fail_keys.insert(0, k)
1028 break # exit from the loop at the first failure
1029 return fail_keys # return the list of keys bringing to the different values
1030
1031
GaudiTesting.BaseTest.cmpTreesDicts
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: BaseTest.py:999
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 1166 of file BaseTest.py.

1166 def findHistosSummaries(stdout):
1167 """
1168 Scan stdout to find ROOT TTree summaries and digest them.
1169 """
1170 outlines = stdout.splitlines()
1171 nlines = len(outlines) - 1
1172 summaries = {}
1173 global h_count_re
1174
1175 pos = 0
1176 while pos < nlines:
1177 summ = {}
1178 # find first line of block:
1179 match = h_count_re.search(outlines[pos])
1180 while pos < nlines and not match:
1181 pos += 1
1182 match = h_count_re.search(outlines[pos])
1183 if match:
1184 summ, pos = parseHistosSummary(outlines, pos)
1185 summaries.update(summ)
1186 return summaries
1187
1188
GaudiTesting.BaseTest.findHistosSummaries
def findHistosSummaries(stdout)
Definition: BaseTest.py:1166
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:1099

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

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 977 of file BaseTest.py.

977 def findTTreeSummaries(stdout):
978 """
979 Scan stdout to find ROOT TTree summaries and digest them.
980 """
981 stars = re.compile(r"^\*+$")
982 outlines = stdout.splitlines()
983 nlines = len(outlines)
984 trees = {}
985
986 i = 0
987 while i < nlines: # loop over the output
988 # look for
989 while i < nlines and not stars.match(outlines[i]):
990 i += 1
991 if i < nlines:
992 tree, i = _parseTTreeSummary(outlines, i)
993 if tree:
994 trees[tree["Name"]] = tree
995
996 return trees
997
998
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:1048
GaudiTesting.BaseTest.findTTreeSummaries
def findTTreeSummaries(stdout)
Definition: BaseTest.py:977

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

Definition at line 1032 of file BaseTest.py.

1032 def getCmpFailingValues(reference, to_check, fail_path):
1033 c = to_check
1034 r = reference
1035 for k in fail_path:
1036 c = c.get(k, None)
1037 r = r.get(k, None)
1038 if c is None or r is None:
1039 break # one of the dictionaries is not deep enough
1040 return (fail_path, r, c)
1041
1042
1043 # signature of the print-out of the histograms
GaudiTesting.BaseTest.getCmpFailingValues
def getCmpFailingValues(reference, to_check, fail_path)
Definition: BaseTest.py:1032

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

        Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1201 of file BaseTest.py.

1201 def GetPlatform(self):
1202 """
1203 Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1204 """
1205 arch = "None"
1206 # check architecture name
1207 if "BINARY_TAG" in os.environ:
1208 arch = os.environ["BINARY_TAG"]
1209 elif "CMTCONFIG" in os.environ:
1210 arch = os.environ["CMTCONFIG"]
1211 elif "SCRAM_ARCH" in os.environ:
1212 arch = os.environ["SCRAM_ARCH"]
1213 return arch
1214
1215
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1201

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 1216 of file BaseTest.py.

1216 def isWinPlatform(self):
1217 """
1218 Return True if the current platform is Windows.
1219
1220 This function was needed because of the change in the CMTCONFIG format,
1221 from win32_vc71_dbg to i686-winxp-vc9-dbg.
1222 """
1223 platform = GetPlatform(self)
1224 return "winxp" in platform or platform.startswith("win")
1225
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1201
GaudiTesting.BaseTest.isWinPlatform
def isWinPlatform(self)
Definition: BaseTest.py:1216

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 1099 of file BaseTest.py.

1099 def parseHistosSummary(lines, pos):
1100 """
1101 Extract the histograms infos from the lines starting at pos.
1102 Returns the position of the first line after the summary block.
1103 """
1104 global h_count_re
1105 h_table_head = re.compile(
1106 r'SUCCESS\s+List of booked (1D|2D|3D|1D profile|2D profile) histograms in directory\s+"(\w*)"')
1107 h_short_summ = re.compile(r"ID=([^\"]+)\s+\"([^\"]+)\"\s+(.*)")
1108
1109 nlines = len(lines)
1110
1111 # decode header
1112 m = h_count_re.search(lines[pos])
1113 name = m.group(1).strip()
1114 total = int(m.group(2))
1115 header = {}
1116 for k, v in [x.split("=") for x in m.group(3).split()]:
1117 header[k] = int(v)
1118 pos += 1
1119 header["Total"] = total
1120
1121 summ = {}
1122 while pos < nlines:
1123 m = h_table_head.search(lines[pos])
1124 if m:
1125 t, d = m.groups(1) # type and directory
1126 t = t.replace(" profile", "Prof")
1127 pos += 1
1128 if pos < nlines:
1129 l = lines[pos]
1130 else:
1131 l = ""
1132 cont = {}
1133 if l.startswith(" | ID"):
1134 # table format
1135 titles = [x.strip() for x in l.split("|")][1:]
1136 pos += 1
1137 while pos < nlines and lines[pos].startswith(" |"):
1138 l = lines[pos]
1139 values = [x.strip() for x in l.split("|")][1:]
1140 hcont = {}
1141 for i in range(len(titles)):
1142 hcont[titles[i]] = values[i]
1143 cont[hcont["ID"]] = hcont
1144 pos += 1
1145 elif l.startswith(" ID="):
1146 while pos < nlines and lines[pos].startswith(" ID="):
1147 values = [x.strip()
1148 for x in h_short_summ.search(lines[pos]).groups()]
1149 cont[values[0]] = values
1150 pos += 1
1151 else: # not interpreted
1152 raise RuntimeError(
1153 "Cannot understand line %d: '%s'" % (pos, l))
1154 if not d in summ:
1155 summ[d] = {}
1156 summ[d][t] = cont
1157 summ[d]["header"] = header
1158 else:
1159 break
1160 if not summ:
1161 # If the full table is not present, we use only the header
1162 summ[name] = {"header": header}
1163 return summ, pos
1164
1165
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:1099

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

Definition at line 1189 of file BaseTest.py.

1189 def PlatformIsNotSupported(self, context, result):
1190 platform = GetPlatform(self)
1191 unsupported = [re.compile(x) for x in [str(y).strip()
1192 for y in unsupported_platforms] if x]
1193 for p_re in unsupported:
1194 if p_re.search(platform):
1195 result.SetOutcome(result.UNTESTED)
1196 result[result.CAUSE] = 'Platform not supported.'
1197 return True
1198 return False
1199
1200
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1201
GaudiTesting.BaseTest.PlatformIsNotSupported
def PlatformIsNotSupported(self, context, result)
Definition: BaseTest.py:1189

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

    Function used to normalize the used path

Definition at line 560 of file BaseTest.py.

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

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

Definition at line 553 of file BaseTest.py.

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

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 570 of file BaseTest.py.

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

## Variable Documentation

GaudiTesting.BaseTest.__processLine__
| private

Definition at line 786 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 1044 of file BaseTest.py.

GaudiTesting.BaseTest.lineSkipper

Definition at line 860 of file BaseTest.py.

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

Definition at line 782 of file BaseTest.py.

GaudiTesting.BaseTest.normalizeDate

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

Definition at line 783 of file BaseTest.py.

GaudiTesting.BaseTest.normalizeEOL = FilePreprocessor()

Definition at line 785 of file BaseTest.py.

tuple GaudiTesting.BaseTest.normalizeExamples = maskPointers+normalizeDate

Definition at line 836 of file BaseTest.py.

GaudiTesting.BaseTest.regexps

Definition at line 930 of file BaseTest.py.

GaudiTesting.BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 788 of file BaseTest.py.