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

917 def _parseTTreeSummary(lines, pos):
918  """
919  Parse the TTree summary table in lines, starting from pos.
920  Returns a tuple with the dictionary with the digested informations and the
921  position of the first line after the summary.
922  """
923  result = {}
924  i = pos + 1 # first line is a sequence of '*'
925  count = len(lines)
926 
927  splitcols = lambda l: [ f.strip() for f in l.strip("*\n").split(':',2) ]
928  def parseblock(ll):
929  r = {}
930  cols = splitcols(ll[0])
931  r["Name"], r["Title"] = cols[1:]
932 
933  cols = splitcols(ll[1])
934  r["Entries"] = int(cols[1])
935 
936  sizes = cols[2].split()
937  r["Total size"] = int(sizes[2])
938  if sizes[-1] == "memory":
939  r["File size"] = 0
940  else:
941  r["File size"] = int(sizes[-1])
942 
943  cols = splitcols(ll[2])
944  sizes = cols[2].split()
945  if cols[0] == "Baskets":
946  r["Baskets"] = int(cols[1])
947  r["Basket size"] = int(sizes[2])
948  r["Compression"] = float(sizes[-1])
949  return r
950 
951  if i < (count - 3) and lines[i].startswith("*Tree"):
952  result = parseblock(lines[i:i+3])
953  result["Branches"] = {}
954  i += 4
955  while i < (count - 3) and lines[i].startswith("*Br"):
956  if i < (count - 2) and lines[i].startswith("*Branch "):
957  # skip branch header
958  i += 3
959  continue
960  branch = parseblock(lines[i:i+3])
961  result["Branches"][branch["Name"]] = branch
962  i += 4
963 
964  return (result, i)
965 
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:917
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 872 of file BaseTest.py.

872 def cmpTreesDicts(reference, to_check, ignore = None):
873  """
874  Check that all the keys in reference are in to_check too, with the same value.
875  If the value is a dict, the function is called recursively. to_check can
876  contain more keys than reference, that will not be tested.
877  The function returns at the first difference found.
878  """
879  fail_keys = []
880  # filter the keys in the reference dictionary
881  if ignore:
882  ignore_re = re.compile(ignore)
883  keys = [ key for key in reference if not ignore_re.match(key) ]
884  else:
885  keys = reference.keys()
886  # loop over the keys (not ignored) in the reference dictionary
887  for k in keys:
888  if k in to_check: # the key must be in the dictionary to_check
889  if (type(reference[k]) is dict) and (type(to_check[k]) is dict):
890  # if both reference and to_check values are dictionaries, recurse
891  failed = fail_keys = cmpTreesDicts(reference[k], to_check[k], ignore)
892  else:
893  # compare the two values
894  failed = to_check[k] != reference[k]
895  else: # handle missing keys in the dictionary to check (i.e. failure)
896  to_check[k] = None
897  failed = True
898  if failed:
899  fail_keys.insert(0, k)
900  break # exit from the loop at the first failure
901  return fail_keys # return the list of keys bringing to the different values
902 
string type
Definition: gaudirun.py:151
def GaudiTesting.BaseTest.findHistosSummaries (   stdout)
    Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 1031 of file BaseTest.py.

1032  """
1033  Scan stdout to find ROOT TTree summaries and digest them.
1034  """
1035  outlines = stdout.splitlines()
1036  nlines = len(outlines) - 1
1037  summaries = {}
1038  global h_count_re
1039 
1040  pos = 0
1041  while pos < nlines:
1042  summ = {}
1043  # find first line of block:
1044  match = h_count_re.search(outlines[pos])
1045  while pos < nlines and not match:
1046  pos += 1
1047  match = h_count_re.search(outlines[pos])
1048  if match:
1049  summ, pos = parseHistosSummary(outlines, pos)
1050  summaries.update(summ)
1051  return summaries
1052 
def findHistosSummaries(stdout)
Definition: BaseTest.py:1031
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:966
def GaudiTesting.BaseTest.findTTreeSummaries (   stdout)
    Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 851 of file BaseTest.py.

851 def findTTreeSummaries(stdout):
852  """
853  Scan stdout to find ROOT TTree summaries and digest them.
854  """
855  stars = re.compile(r"^\*+$")
856  outlines = stdout.splitlines()
857  nlines = len(outlines)
858  trees = {}
859 
860  i = 0
861  while i < nlines: #loop over the output
862  # look for
863  while i < nlines and not stars.match(outlines[i]):
864  i += 1
865  if i < nlines:
866  tree, i = _parseTTreeSummary(outlines, i)
867  if tree:
868  trees[tree["Name"]] = tree
869 
870  return trees
871 
def findTTreeSummaries(stdout)
Definition: BaseTest.py:851
def _parseTTreeSummary(lines, pos)
Definition: BaseTest.py:917
def GaudiTesting.BaseTest.getCmpFailingValues (   reference,
  to_check,
  fail_path 
)

Definition at line 903 of file BaseTest.py.

903 def getCmpFailingValues(reference, to_check, fail_path):
904  c = to_check
905  r = reference
906  for k in fail_path:
907  c = c.get(k,None)
908  r = r.get(k,None)
909  if c is None or r is None:
910  break # one of the dictionaries is not deep enough
911  return (fail_path, r, c)
912 
913 # signature of the print-out of the histograms
def getCmpFailingValues(reference, to_check, fail_path)
Definition: BaseTest.py:903
def GaudiTesting.BaseTest.GetPlatform (   self)
    Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 1063 of file BaseTest.py.

1063 def GetPlatform(self):
1064  """
1065  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
1066  """
1067  arch = "None"
1068  # check architecture name
1069  if "CMTCONFIG" in os.environ:
1070  arch = os.environ["CMTCONFIG"]
1071  elif "SCRAM_ARCH" in os.environ:
1072  arch = os.environ["SCRAM_ARCH"]
1073  return arch
1074 
def GetPlatform(self)
Definition: BaseTest.py:1063
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 1075 of file BaseTest.py.

1075 def isWinPlatform(self):
1076  """
1077  Return True if the current platform is Windows.
1078 
1079  This function was needed because of the change in the CMTCONFIG format,
1080  from win32_vc71_dbg to i686-winxp-vc9-dbg.
1081  """
1082  platform = GetPlatform(self)
1083  return "winxp" in platform or platform.startswith("win")
1084 
1085 
def GetPlatform(self)
Definition: BaseTest.py:1063
def isWinPlatform(self)
Definition: BaseTest.py:1075
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 966 of file BaseTest.py.

966 def parseHistosSummary(lines, pos):
967  """
968  Extract the histograms infos from the lines starting at pos.
969  Returns the position of the first line after the summary block.
970  """
971  global h_count_re
972  h_table_head = re.compile(r'SUCCESS\s+List of booked (1D|2D|3D|1D profile|2D profile) histograms in directory\s+"(\w*)"')
973  h_short_summ = re.compile(r"ID=([^\"]+)\s+\"([^\"]+)\"\s+(.*)")
974 
975  nlines = len(lines)
976 
977  # decode header
978  m = h_count_re.search(lines[pos])
979  name = m.group(1).strip()
980  total = int(m.group(2))
981  header = {}
982  for k, v in [ x.split("=") for x in m.group(3).split() ]:
983  header[k] = int(v)
984  pos += 1
985  header["Total"] = total
986 
987  summ = {}
988  while pos < nlines:
989  m = h_table_head.search(lines[pos])
990  if m:
991  t, d = m.groups(1) # type and directory
992  t = t.replace(" profile", "Prof")
993  pos += 1
994  if pos < nlines:
995  l = lines[pos]
996  else:
997  l = ""
998  cont = {}
999  if l.startswith(" | ID"):
1000  # table format
1001  titles = [ x.strip() for x in l.split("|")][1:]
1002  pos += 1
1003  while pos < nlines and lines[pos].startswith(" |"):
1004  l = lines[pos]
1005  values = [ x.strip() for x in l.split("|")][1:]
1006  hcont = {}
1007  for i in range(len(titles)):
1008  hcont[titles[i]] = values[i]
1009  cont[hcont["ID"]] = hcont
1010  pos += 1
1011  elif l.startswith(" ID="):
1012  while pos < nlines and lines[pos].startswith(" ID="):
1013  values = [ x.strip() for x in h_short_summ.search(lines[pos]).groups() ]
1014  cont[values[0]] = values
1015  pos += 1
1016  else: # not interpreted
1017  raise RuntimeError("Cannot understand line %d: '%s'" % (pos, l))
1018  if not d in summ:
1019  summ[d] = {}
1020  summ[d][t] = cont
1021  summ[d]["header"] = header
1022  else:
1023  break
1024  if not summ:
1025  # If the full table is not present, we use only the header
1026  summ[name] = {"header": header}
1027  return summ, pos
1028 
1029 
1030 
def parseHistosSummary(lines, pos)
Definition: BaseTest.py:966
NamedRange_< CONTAINER > range(const CONTAINER &cnt, const std::string &name)
simple function to create the named range form arbitrary container
Definition: NamedRange.h:133
def GaudiTesting.BaseTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 1053 of file BaseTest.py.

1053 def PlatformIsNotSupported(self, context, result):
1054  platform = GetPlatform(self)
1055  unsupported = [ re.compile(x) for x in [ str(y).strip() for y in unsupported_platforms ] if x]
1056  for p_re in unsupported :
1057  if p_re.search(platform):
1058  result.SetOutcome(result.UNTESTED)
1059  result[result.CAUSE] = 'Platform not supported.'
1060  return True
1061  return False
1062 
def GetPlatform(self)
Definition: BaseTest.py:1063
def PlatformIsNotSupported(self, context, result)
Definition: BaseTest.py:1053
def GaudiTesting.BaseTest.RationalizePath (   p)
Function used to normalize the used path

Definition at line 509 of file BaseTest.py.

510  """
511  Function used to normalize the used path
512  """
513  newPath = os.path.normpath(os.path.expandvars(p))
514  if os.path.exists(newPath) :
515  p = os.path.realpath(newPath)
516  return p
517 
518 
def GaudiTesting.BaseTest.ROOT6WorkAroundEnabled (   id = None)

Definition at line 503 of file BaseTest.py.

504  # dummy implementation
505  return False
506 
507 #--------------------------------- TOOLS ---------------------------------#
508 
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 
30 #-------------------------------------------------------------------------#
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 519 of file BaseTest.py.

519 def which(executable):
520  """
521  Locates an executable in the executables path ($PATH) and returns the full
522  path to it. An application is looked for with or without the '.exe' suffix.
523  If the executable cannot be found, None is returned
524  """
525  if os.path.isabs(executable):
526  if not os.path.exists(executable):
527  if executable.endswith('.exe'):
528  if os.path.exists(executable[:-4]):
529  return executable[:-4]
530  else :
531  head,executable = os.path.split(executable)
532  else :
533  return executable
534  for d in os.environ.get("PATH").split(os.pathsep):
535  fullpath = os.path.join(d, executable)
536  if os.path.exists(fullpath):
537  return fullpath
538  if executable.endswith('.exe'):
539  return which(executable[:-4])
540  return None
541 
542 
543 
544 #-------------------------------------------------------------------------#
545 #----------------------------- Result Classe -----------------------------#
546 #-------------------------------------------------------------------------#
def which(executable)
Definition: BaseTest.py:519

Variable Documentation

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

Definition at line 914 of file BaseTest.py.

tuple GaudiTesting.BaseTest.lineSkipper

Definition at line 758 of file BaseTest.py.

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

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

tuple GaudiTesting.BaseTest.normalizeEOL = FilePreprocessor()

Definition at line 714 of file BaseTest.py.

tuple GaudiTesting.BaseTest.normalizeExamples = maskPointers+normalizeDate

Definition at line 737 of file BaseTest.py.

tuple GaudiTesting.BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 717 of file BaseTest.py.