| The Gaudi Framework v27r1

- 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

## Functions
def | sanitize_for_xml (data)
def | dumpProcs (name)
def | kill_tree (ppid, sig)
def | ROOT6WorkAroundEnabled
def | RationalizePath (p)
def | which (executable)
def | findTTreeSummaries (stdout)
def | cmpTreesDicts
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
tuple | maskPointers = RegexpReplacer("0x[0-9a-fA-F]{4,16}","0x########")
tuple | normalizeDate
tuple | normalizeEOL = FilePreprocessor()
tuple | skipEmptyLines = FilePreprocessor()
| normalizeExamples = maskPointers+normalizeDate
tuple | lineSkipper
tuple | 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 947 of file BaseTest.py.

947 def _parseTTreeSummary(lines, pos):
948 """
949 Parse the TTree summary table in lines, starting from pos.
950 Returns a tuple with the dictionary with the digested informations and the
951 position of the first line after the summary.
952 """
953 result = {}
954 i = pos + 1 # first line is a sequence of '*'
955 count = len(lines)
956
957 splitcols = lambda l: [ f.strip() for f in l.strip("*\n").split(':',2) ]
958 def parseblock(ll):
959 r = {}
960 cols = splitcols(ll[0])
961 r["Name"], r["Title"] = cols[1:]
962
963 cols = splitcols(ll[1])
964 r["Entries"] = int(cols[1])
965
966 sizes = cols[2].split()
967 r["Total size"] = int(sizes[2])
968 if sizes[-1] == "memory":
969 r["File size"] = 0
970 else:
971 r["File size"] = int(sizes[-1])
972
973 cols = splitcols(ll[2])
974 sizes = cols[2].split()
975 if cols[0] == "Baskets":
976 r["Baskets"] = int(cols[1])
977 r["Basket size"] = int(sizes[2])
978 r["Compression"] = float(sizes[-1])
979 return r
980
981 if i < (count - 3) and lines[i].startswith("*Tree"):
982 result = parseblock(lines[i:i+3])
983 result["Branches"] = {}
984 i += 4
985 while i < (count - 3) and lines[i].startswith("*Br"):
986 if i < (count - 2) and lines[i].startswith("*Branch "):
987 # skip branch header
988 i += 3
989 continue
990 branch = parseblock(lines[i:i+3])
991 result["Branches"][branch["Name"]] = branch
992 i += 4
993
994 return (result, i)
995
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:947

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

902 def cmpTreesDicts(reference, to_check, ignore = None):
903 """
904 Check that all the keys in reference are in to_check too, with the same value.
905 If the value is a dict, the function is called recursively. to_check can
906 contain more keys than reference, that will not be tested.
907 The function returns at the first difference found.
908 """
909 fail_keys = []
910 # filter the keys in the reference dictionary
911 if ignore:
912 ignore_re = re.compile(ignore)
913 keys = [ key for key in reference if not ignore_re.match(key) ]
914 else:
915 keys = reference.keys()
916 # loop over the keys (not ignored) in the reference dictionary
917 for k in keys:
918 if k in to_check: # the key must be in the dictionary to_check
919 if (type(reference[k]) is dict) and (type(to_check[k]) is dict):
920 # if both reference and to_check values are dictionaries, recurse
921 failed = fail_keys = cmpTreesDicts(reference[k], to_check[k], ignore)
922 else:
923 # compare the two values
924 failed = to_check[k] != reference[k]
925 else: # handle missing keys in the dictionary to check (i.e. failure)
926 to_check[k] = None
927 failed = True
928 if failed:
929 fail_keys.insert(0, k)
930 break # exit from the loop at the first failure
931 return fail_keys # return the list of keys bringing to the different values
932
gaudirun.type
string type
Definition: gaudirun.py:151
GaudiTesting.BaseTest.cmpTreesDicts
def cmpTreesDicts
Definition: BaseTest.py:902

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

1061 def findHistosSummaries(stdout):
1062 """
1063 Scan stdout to find ROOT TTree summaries and digest them.
1064 """
1065 outlines = stdout.splitlines()
1066 nlines = len(outlines) - 1
1067 summaries = {}
1068 global h_count_re
1069
1070 pos = 0
1071 while pos < nlines:
1072 summ = {}
1073 # find first line of block:
1074 match = h_count_re.search(outlines[pos])
1075 while pos < nlines and not match:
1076 pos += 1
1077 match = h_count_re.search(outlines[pos])
1078 if match:
1079 summ, pos = parseHistosSummary(outlines, pos)
1080 summaries.update(summ)
1081 return summaries
1082
GaudiTesting.BaseTest.findHistosSummaries
def findHistosSummaries(stdout)
Definition: BaseTest.py:1061
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:996

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

        Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 881 of file BaseTest.py.

881 def findTTreeSummaries(stdout):
882 """
883 Scan stdout to find ROOT TTree summaries and digest them.
884 """
885 stars = re.compile(r"^\*+$")
886 outlines = stdout.splitlines()
887 nlines = len(outlines)
888 trees = {}
889
890 i = 0
891 while i < nlines: #loop over the output
892 # look for
893 while i < nlines and not stars.match(outlines[i]):
894 i += 1
895 if i < nlines:
896 tree, i = _parseTTreeSummary(outlines, i)
897 if tree:
898 trees[tree["Name"]] = tree
899
900 return trees
901
GaudiTesting.BaseTest._parseTTreeSummary
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:947
GaudiTesting.BaseTest.findTTreeSummaries
def findTTreeSummaries(stdout)
Definition: BaseTest.py:881

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

Definition at line 933 of file BaseTest.py.

933 def getCmpFailingValues(reference, to_check, fail_path):
934 c = to_check
935 r = reference
936 for k in fail_path:
937 c = c.get(k,None)
938 r = r.get(k,None)
939 if c is None or r is None:
940 break # one of the dictionaries is not deep enough
941 return (fail_path, r, c)
942
943 # signature of the print-out of the histograms
GaudiTesting.BaseTest.getCmpFailingValues
def getCmpFailingValues(reference, to_check, fail_path)
Definition: BaseTest.py:933

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

        Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1093 of file BaseTest.py.

1093 def GetPlatform(self):
1094 """
1095 Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1096 """
1097 arch = "None"
1098 # check architecture name
1099 if "BINARY_TAG" in os.environ:
1100 arch = os.environ["BINARY_TAG"]
1101 elif "CMTCONFIG" in os.environ:
1102 arch = os.environ["CMTCONFIG"]
1103 elif "SCRAM_ARCH" in os.environ:
1104 arch = os.environ["SCRAM_ARCH"]
1105 return arch
1106
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1093

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

1107 def isWinPlatform(self):
1108 """
1109 Return True if the current platform is Windows.
1110
1111 This function was needed because of the change in the CMTCONFIG format,
1112 from win32_vc71_dbg to i686-winxp-vc9-dbg.
1113 """
1114 platform = GetPlatform(self)
1115 return "winxp" in platform or platform.startswith("win")
1116
1117
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1093
GaudiTesting.BaseTest.isWinPlatform
def isWinPlatform(self)
Definition: BaseTest.py:1107

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

996 def parseHistosSummary(lines, pos):
997 """
998 Extract the histograms infos from the lines starting at pos.
999 Returns the position of the first line after the summary block.
1000 """
1001 global h_count_re
1002 h_table_head = re.compile(r'SUCCESS\s+List of booked (1D|2D|3D|1D profile|2D profile) histograms in directory\s+"(\w*)"')
1003 h_short_summ = re.compile(r"ID=([^\"]+)\s+\"([^\"]+)\"\s+(.*)")
1004
1005 nlines = len(lines)
1006
1007 # decode header
1008 m = h_count_re.search(lines[pos])
1009 name = m.group(1).strip()
1010 total = int(m.group(2))
1011 header = {}
1012 for k, v in [ x.split("=") for x in m.group(3).split() ]:
1013 header[k] = int(v)
1014 pos += 1
1015 header["Total"] = total
1016
1017 summ = {}
1018 while pos < nlines:
1019 m = h_table_head.search(lines[pos])
1020 if m:
1021 t, d = m.groups(1) # type and directory
1022 t = t.replace(" profile", "Prof")
1023 pos += 1
1024 if pos < nlines:
1025 l = lines[pos]
1026 else:
1027 l = ""
1028 cont = {}
1029 if l.startswith(" | ID"):
1030 # table format
1031 titles = [ x.strip() for x in l.split("|")][1:]
1032 pos += 1
1033 while pos < nlines and lines[pos].startswith(" |"):
1034 l = lines[pos]
1035 values = [ x.strip() for x in l.split("|")][1:]
1036 hcont = {}
1037 for i in range(len(titles)):
1038 hcont[titles[i]] = values[i]
1039 cont[hcont["ID"]] = hcont
1040 pos += 1
1041 elif l.startswith(" ID="):
1042 while pos < nlines and lines[pos].startswith(" ID="):
1043 values = [ x.strip() for x in h_short_summ.search(lines[pos]).groups() ]
1044 cont[values[0]] = values
1045 pos += 1
1046 else: # not interpreted
1047 raise RuntimeError("Cannot understand line %d: '%s'" % (pos, l))
1048 if not d in summ:
1049 summ[d] = {}
1050 summ[d][t] = cont
1051 summ[d]["header"] = header
1052 else:
1053 break
1054 if not summ:
1055 # If the full table is not present, we use only the header
1056 summ[name] = {"header": header}
1057 return summ, pos
1058
1059
1060
Gaudi::range
NamedRange_< CONTAINER > range(const CONTAINER &cnt, std::string name)
simple function to create the named range form arbitrary container
Definition: NamedRange.h:130
GaudiTesting.BaseTest.parseHistosSummary
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:996

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

Definition at line 1083 of file BaseTest.py.

1083 def PlatformIsNotSupported(self, context, result):
1084 platform = GetPlatform(self)
1085 unsupported = [ re.compile(x) for x in [ str(y).strip() for y in unsupported_platforms ] if x]
1086 for p_re in unsupported :
1087 if p_re.search(platform):
1088 result.SetOutcome(result.UNTESTED)
1089 result[result.CAUSE] = 'Platform not supported.'
1090 return True
1091 return False
1092
GaudiTesting.BaseTest.GetPlatform
def GetPlatform(self)
Definition: BaseTest.py:1093
GaudiTesting.BaseTest.PlatformIsNotSupported
def PlatformIsNotSupported(self, context, result)
Definition: BaseTest.py:1083

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

    Function used to normalize the used path

Definition at line 537 of file BaseTest.py.

537 def RationalizePath(p) :
538 """
539 Function used to normalize the used path
540 """
541 newPath = os.path.normpath(os.path.expandvars(p))
542 if os.path.exists(newPath) :
543 p = os.path.realpath(newPath)
544 return p
545
546
GaudiTesting.BaseTest.RationalizePath
def RationalizePath(p)
Definition: BaseTest.py:537

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

Definition at line 531 of file BaseTest.py.

531 def ROOT6WorkAroundEnabled(id=None):
532 # dummy implementation
533 return False
534
535 #--------------------------------- TOOLS ---------------------------------#
536
GaudiTesting.BaseTest.ROOT6WorkAroundEnabled
def ROOT6WorkAroundEnabled
Definition: BaseTest.py:531

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

547 def which(executable):
548 """
549 Locates an executable in the executables path ($PATH) and returns the full
550 path to it. An application is looked for with or without the '.exe' suffix.
551 If the executable cannot be found, None is returned
552 """
553 if os.path.isabs(executable):
554 if not os.path.exists(executable):
555 if executable.endswith('.exe'):
556 if os.path.exists(executable[:-4]):
557 return executable[:-4]
558 else :
559 head,executable = os.path.split(executable)
560 else :
561 return executable
562 for d in os.environ.get("PATH").split(os.pathsep):
563 fullpath = os.path.join(d, executable)
564 if os.path.exists(fullpath):
565 return fullpath
566 if executable.endswith('.exe'):
567 return which(executable[:-4])
568 return None
569
570
571
572 #-------------------------------------------------------------------------#
573 #----------------------------- Result Classe -----------------------------#
574 #-------------------------------------------------------------------------#
GaudiTesting.BaseTest.which
def which(executable)
Definition: BaseTest.py:547

## Variable Documentation

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

Definition at line 944 of file BaseTest.py.

tuple GaudiTesting.BaseTest.lineSkipper

Definition at line 786 of file BaseTest.py.

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

Definition at line 739 of file BaseTest.py.

tuple 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:720

Definition at line 740 of file BaseTest.py.

tuple GaudiTesting.BaseTest.normalizeEOL = FilePreprocessor()

Definition at line 742 of file BaseTest.py.

tuple GaudiTesting.BaseTest.normalizeExamples = maskPointers+normalizeDate

Definition at line 765 of file BaseTest.py.

tuple GaudiTesting.BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 745 of file BaseTest.py.