| The Gaudi Framework v29r1 (5cd95fa2)

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

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

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

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

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

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

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 979 of file BaseTest.py.

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

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

Definition at line 1034 of file BaseTest.py.

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

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

        Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1203 of file BaseTest.py.

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

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

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

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

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

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

Definition at line 1191 of file BaseTest.py.

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

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

GaudiTesting.BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 788 of file BaseTest.py.