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+(.*)")
 

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

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

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

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

Definition at line 879 of file BaseTest.py.

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

Definition at line 931 of file BaseTest.py.

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

Definition at line 1091 of file BaseTest.py.

1091 def GetPlatform(self):
1092  """
1093  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1094  """
1095  arch = "None"
1096  # check architecture name
1097  if "CMTCONFIG" in os.environ:
1098  arch = os.environ["CMTCONFIG"]
1099  elif "SCRAM_ARCH" in os.environ:
1100  arch = os.environ["SCRAM_ARCH"]
1101  return arch
1102 
def GetPlatform(self)
Definition: BaseTest.py:1091
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 1103 of file BaseTest.py.

1103 def isWinPlatform(self):
1104  """
1105  Return True if the current platform is Windows.
1106 
1107  This function was needed because of the change in the CMTCONFIG format,
1108  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1109  """
1110  platform = GetPlatform(self)
1111  return "winxp" in platform or platform.startswith("win")
1112 
1113 
def GetPlatform(self)
Definition: BaseTest.py:1091
def isWinPlatform(self)
Definition: BaseTest.py:1103
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 #-------------------------------------------------------------------------#
def kill_tree(ppid, sig)
Definition: BaseTest.py:38
struct GAUDI_API map
Parametrisation class for map-like implementation.
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 994 of file BaseTest.py.

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

Definition at line 1081 of file BaseTest.py.

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

Definition at line 537 of file BaseTest.py.

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 
def GaudiTesting.BaseTest.ROOT6WorkAroundEnabled (   id = None)

Definition at line 531 of file BaseTest.py.

532  # dummy implementation
533  return False
534 
535 #--------------------------------- TOOLS ---------------------------------#
536 
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 
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 #-------------------------------------------------------------------------#
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+(.*)")

Definition at line 942 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")

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.