| The Gaudi Framework v28r2-patches (bc4ad17a)

- 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
| Special preprocessor sorting the list of strings (whitespace separated) that follow a signature on a single line. More...
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 = re.compile(r"^(.*)SUCCESS\s+Booked (\d+) Histogram\(s\) :\s+([\s\w=-]*)")

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

968 def _parseTTreeSummary(lines, pos):
969 """
970 Parse the TTree summary table in lines, starting from pos.
971 Returns a tuple with the dictionary with the digested informations and the
972 position of the first line after the summary.
973 """
974 result = {}
975 i = pos + 1 # first line is a sequence of '*'
976 count = len(lines)
977
978 splitcols = lambda l: [ f.strip() for f in l.strip("*\n").split(':',2) ]
979 def parseblock(ll):
980 r = {}
981 cols = splitcols(ll[0])
982 r["Name"], r["Title"] = cols[1:]
983
984 cols = splitcols(ll[1])
985 r["Entries"] = int(cols[1])
986
987 sizes = cols[2].split()
988 r["Total size"] = int(sizes[2])
989 if sizes[-1] == "memory":
990 r["File size"] = 0
991 else:
992 r["File size"] = int(sizes[-1])
993
994 cols = splitcols(ll[2])
995 sizes = cols[2].split()
996 if cols[0] == "Baskets":
997 r["Baskets"] = int(cols[1])
998 r["Basket size"] = int(sizes[2])
999 r["Compression"] = float(sizes[-1])
1000 return r
1001
1002 if i < (count - 3) and lines[i].startswith("*Tree"):
1003 result = parseblock(lines[i:i+3])
1004 result["Branches"] = {}
1005 i += 4
1006 while i < (count - 3) and lines[i].startswith("*Br"):
1007 if i < (count - 2) and lines[i].startswith("*Branch "):
1008 # skip branch header
1009 i += 3
1010 continue
1011 branch = parseblock(lines[i:i+3])
1012 result["Branches"][branch["Name"]] = branch
1013 i += 4
1014
1015 return (result, i)
1016
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:968

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

923 def cmpTreesDicts(reference, to_check, ignore = None):
924 """
925 Check that all the keys in reference are in to_check too, with the same value.
926 If the value is a dict, the function is called recursively. to_check can
927 contain more keys than reference, that will not be tested.
928 The function returns at the first difference found.
929 """
930 fail_keys = []
931 # filter the keys in the reference dictionary
932 if ignore:
933 ignore_re = re.compile(ignore)
934 keys = [ key for key in reference if not ignore_re.match(key) ]
935 else:
936 keys = reference.keys()
937 # loop over the keys (not ignored) in the reference dictionary
938 for k in keys:
939 if k in to_check: # the key must be in the dictionary to_check
940 if (type(reference[k]) is dict) and (type(to_check[k]) is dict):
941 # if both reference and to_check values are dictionaries, recurse
942 failed = fail_keys = cmpTreesDicts(reference[k], to_check[k], ignore)
943 else:
944 # compare the two values
945 failed = to_check[k] != reference[k]
946 else: # handle missing keys in the dictionary to check (i.e. failure)
947 to_check[k] = None
948 failed = True
949 if failed:
950 fail_keys.insert(0, k)
951 break # exit from the loop at the first failure
952 return fail_keys # return the list of keys bringing to the different values
953
GaudiTesting.BaseTest.cmpTreesDicts
def cmpTreesDicts(reference, to_check, ignore=None)
Definition: BaseTest.py:923
gaudirun.type
type
Definition: gaudirun.py:125

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

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

Definition at line 30 of file BaseTest.py.

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

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

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 1082 of file BaseTest.py.

1082 def findHistosSummaries(stdout):
1083 """
1084 Scan stdout to find ROOT TTree summaries and digest them.
1085 """
1086 outlines = stdout.splitlines()
1087 nlines = len(outlines) - 1
1088 summaries = {}
1089 global h_count_re
1090
1091 pos = 0
1092 while pos < nlines:
1093 summ = {}
1094 # find first line of block:
1095 match = h_count_re.search(outlines[pos])
1096 while pos < nlines and not match:
1097 pos += 1
1098 match = h_count_re.search(outlines[pos])
1099 if match:
1100 summ, pos = parseHistosSummary(outlines, pos)
1101 summaries.update(summ)
1102 return summaries
1103
GaudiTesting.BaseTest.findHistosSummaries
def findHistosSummaries(stdout)
Definition: BaseTest.py:1082
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:1017

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

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 902 of file BaseTest.py.

902 def findTTreeSummaries(stdout):
903 """
904 Scan stdout to find ROOT TTree summaries and digest them.
905 """
906 stars = re.compile(r"^\*+$")
907 outlines = stdout.splitlines()
908 nlines = len(outlines)
909 trees = {}
910
911 i = 0
912 while i < nlines: #loop over the output
913 # look for
914 while i < nlines and not stars.match(outlines[i]):
915 i += 1
916 if i < nlines:
917 tree, i = _parseTTreeSummary(outlines, i)
918 if tree:
919 trees[tree["Name"]] = tree
920
921 return trees
922
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:968
GaudiTesting.BaseTest.findTTreeSummaries
def findTTreeSummaries(stdout)
Definition: BaseTest.py:902

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

Definition at line 954 of file BaseTest.py.

954 def getCmpFailingValues(reference, to_check, fail_path):
955 c = to_check
956 r = reference
957 for k in fail_path:
958 c = c.get(k,None)
959 r = r.get(k,None)
960 if c is None or r is None:
961 break # one of the dictionaries is not deep enough
962 return (fail_path, r, c)
963
964 # signature of the print-out of the histograms
GaudiTesting.BaseTest.getCmpFailingValues
def getCmpFailingValues(reference, to_check, fail_path)
Definition: BaseTest.py:954

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

        Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1114 of file BaseTest.py.

1114 def GetPlatform(self):
1115 """
1116 Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1117 """
1118 arch = "None"
1119 # check architecture name
1120 if "BINARY_TAG" in os.environ:
1121 arch = os.environ["BINARY_TAG"]
1122 elif "CMTCONFIG" in os.environ:
1123 arch = os.environ["CMTCONFIG"]
1124 elif "SCRAM_ARCH" in os.environ:
1125 arch = os.environ["SCRAM_ARCH"]
1126 return arch
1127
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1114

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

1128 def isWinPlatform(self):
1129 """
1130 Return True if the current platform is Windows.
1131
1132 This function was needed because of the change in the CMTCONFIG format,
1133 from win32_vc71_dbg to i686-winxp-vc9-dbg.
1134 """
1135 platform = GetPlatform(self)
1136 return "winxp" in platform or platform.startswith("win")
1137
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1114
GaudiTesting.BaseTest.isWinPlatform
def isWinPlatform(self)
Definition: BaseTest.py:1128

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

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

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

1017 def parseHistosSummary(lines, pos):
1018 """
1019 Extract the histograms infos from the lines starting at pos.
1020 Returns the position of the first line after the summary block.
1021 """
1022 global h_count_re
1023 h_table_head = re.compile(r'SUCCESS\s+List of booked (1D|2D|3D|1D profile|2D profile) histograms in directory\s+"(\w*)"')
1024 h_short_summ = re.compile(r"ID=([^\"]+)\s+\"([^\"]+)\"\s+(.*)")
1025
1026 nlines = len(lines)
1027
1028 # decode header
1029 m = h_count_re.search(lines[pos])
1030 name = m.group(1).strip()
1031 total = int(m.group(2))
1032 header = {}
1033 for k, v in [ x.split("=") for x in m.group(3).split() ]:
1034 header[k] = int(v)
1035 pos += 1
1036 header["Total"] = total
1037
1038 summ = {}
1039 while pos < nlines:
1040 m = h_table_head.search(lines[pos])
1041 if m:
1042 t, d = m.groups(1) # type and directory
1043 t = t.replace(" profile", "Prof")
1044 pos += 1
1045 if pos < nlines:
1046 l = lines[pos]
1047 else:
1048 l = ""
1049 cont = {}
1050 if l.startswith(" | ID"):
1051 # table format
1052 titles = [ x.strip() for x in l.split("|")][1:]
1053 pos += 1
1054 while pos < nlines and lines[pos].startswith(" |"):
1055 l = lines[pos]
1056 values = [ x.strip() for x in l.split("|")][1:]
1057 hcont = {}
1058 for i in range(len(titles)):
1059 hcont[titles[i]] = values[i]
1060 cont[hcont["ID"]] = hcont
1061 pos += 1
1062 elif l.startswith(" ID="):
1063 while pos < nlines and lines[pos].startswith(" ID="):
1064 values = [ x.strip() for x in h_short_summ.search(lines[pos]).groups() ]
1065 cont[values[0]] = values
1066 pos += 1
1067 else: # not interpreted
1068 raise RuntimeError("Cannot understand line %d: '%s'" % (pos, l))
1069 if not d in summ:
1070 summ[d] = {}
1071 summ[d][t] = cont
1072 summ[d]["header"] = header
1073 else:
1074 break
1075 if not summ:
1076 # If the full table is not present, we use only the header
1077 summ[name] = {"header": header}
1078 return summ, pos
1079
1080
1081
Gaudi::Functional::details::zip::range
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.
Definition: FunctionalDetails.h:57
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:1017

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

Definition at line 1104 of file BaseTest.py.

1104 def PlatformIsNotSupported(self, context, result):
1105 platform = GetPlatform(self)
1106 unsupported = [ re.compile(x) for x in [ str(y).strip() for y in unsupported_platforms ] if x]
1107 for p_re in unsupported :
1108 if p_re.search(platform):
1109 result.SetOutcome(result.UNTESTED)
1110 result[result.CAUSE] = 'Platform not supported.'
1111 return True
1112 return False
1113
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1114
GaudiTesting.BaseTest.PlatformIsNotSupported
def PlatformIsNotSupported(self, context, result)
Definition: BaseTest.py:1104

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

    Function used to normalize the used path

Definition at line 525 of file BaseTest.py.

525 def RationalizePath(p) :
526 """
527 Function used to normalize the used path
528 """
529 newPath = os.path.normpath(os.path.expandvars(p))
530 if os.path.exists(newPath) :
531 p = os.path.realpath(newPath)
532 return p
533
534
GaudiTesting.BaseTest.RationalizePath
def RationalizePath(p)
Definition: BaseTest.py:525

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

Definition at line 519 of file BaseTest.py.

519 def ROOT6WorkAroundEnabled(id=None):
520 # dummy implementation
521 return False
522
523 #--------------------------------- TOOLS ---------------------------------#
524
GaudiTesting.BaseTest.ROOT6WorkAroundEnabled
def ROOT6WorkAroundEnabled(id=None)
Definition: BaseTest.py:519

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

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

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

535 def which(executable):
536 """
537 Locates an executable in the executables path ($PATH) and returns the full
538 path to it. An application is looked for with or without the '.exe' suffix.
539 If the executable cannot be found, None is returned
540 """
541 if os.path.isabs(executable):
542 if not os.path.exists(executable):
543 if executable.endswith('.exe'):
544 if os.path.exists(executable[:-4]):
545 return executable[:-4]
546 else :
547 head,executable = os.path.split(executable)
548 else :
549 return executable
550 for d in os.environ.get("PATH").split(os.pathsep):
551 fullpath = os.path.join(d, executable)
552 if os.path.exists(fullpath):
553 return fullpath
554 if executable.endswith('.exe'):
555 return which(executable[:-4])
556 return None
557
558
559
560 #-------------------------------------------------------------------------#
561 #----------------------------- Result Classe -----------------------------#
562 #-------------------------------------------------------------------------#
GaudiTesting.BaseTest.which
def which(executable)
Definition: BaseTest.py:535

## Variable Documentation

GaudiTesting.BaseTest.__processLine__
| private

Definition at line 734 of file BaseTest.py.

GaudiTesting.BaseTest.h_count_re = re.compile(r"^(.*)SUCCESS\s+Booked (\d+) Histogram\(s\) :\s+([\s\w=-]*)")

Definition at line 965 of file BaseTest.py.

GaudiTesting.BaseTest.lineSkipper

Definition at line 797 of file BaseTest.py.

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

Definition at line 730 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:711

Definition at line 731 of file BaseTest.py.

GaudiTesting.BaseTest.normalizeEOL = FilePreprocessor()

Definition at line 733 of file BaseTest.py.

tuple GaudiTesting.BaseTest.normalizeExamples = maskPointers+normalizeDate

Definition at line 777 of file BaseTest.py.

GaudiTesting.BaseTest.regexps

Definition at line 858 of file BaseTest.py.

GaudiTesting.BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 736 of file BaseTest.py.