All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 ROOT6WorkAroundEnabled
 
def RationalizePath
 
def which
 
def findTTreeSummaries
 
def cmpTreesDicts
 
def getCmpFailingValues
 
def _parseTTreeSummary
 
def parseHistosSummary
 
def findHistosSummaries
 
def PlatformIsNotSupported
 
def GetPlatform
 
def isWinPlatform
 
def _expandReferenceFileName
 

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 BaseTest._expandReferenceFileName (   self,
  reffile 
)
private

Definition at line 999 of file BaseTest.py.

1000 def _expandReferenceFileName(self, reffile):
1001  # if no file is passed, do nothing
1002  if not reffile:
1003  return ""
1004 
1005  # function to split an extension in constituents parts
1006  platformSplit = lambda p: set(p.split('-' in p and '-' or '_'))
1007 
1008  reference = os.path.normpath(os.path.expandvars(reffile))
1009  # old-style platform-specific reference name
1010  spec_ref = reference[:-3] + GetPlatform(self)[0:3] + reference[-3:]
1011  if os.path.isfile(spec_ref):
1012  reference = spec_ref
1013  else: # look for new-style platform specific reference files:
1014  # get all the files whose name start with the reference filename
1015  dirname, basename = os.path.split(reference)
1016  if not dirname: dirname = '.'
1017  head = basename + "."
1018  head_len = len(head)
1019  platform = platformSplit(GetPlatform(self))
1020  candidates = []
1021  for f in os.listdir(dirname):
1022  if f.startswith(head):
1023  req_plat = platformSplit(f[head_len:])
1024  if platform.issuperset(req_plat):
1025  candidates.append( (len(req_plat), f) )
1026  if candidates: # take the one with highest matching
1027  # FIXME: it is not possible to say if x86_64-slc5-gcc43-dbg
1028  # has to use ref.x86_64-gcc43 or ref.slc5-dbg
1029  candidates.sort()
1030  reference = os.path.join(dirname, candidates[-1][1])
1031  return reference
1032 
1033 
#-------------------------------------------------------------------------#
def _expandReferenceFileName
Definition: BaseTest.py:999
def GetPlatform
Definition: BaseTest.py:976
def 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 830 of file BaseTest.py.

831 def _parseTTreeSummary(lines, pos):
832  """
833  Parse the TTree summary table in lines, starting from pos.
834  Returns a tuple with the dictionary with the digested informations and the
835  position of the first line after the summary.
836  """
837  result = {}
838  i = pos + 1 # first line is a sequence of '*'
839  count = len(lines)
840 
841  splitcols = lambda l: [ f.strip() for f in l.strip("*\n").split(':',2) ]
842  def parseblock(ll):
843  r = {}
844  cols = splitcols(ll[0])
845  r["Name"], r["Title"] = cols[1:]
846 
847  cols = splitcols(ll[1])
848  r["Entries"] = int(cols[1])
849 
850  sizes = cols[2].split()
851  r["Total size"] = int(sizes[2])
852  if sizes[-1] == "memory":
853  r["File size"] = 0
854  else:
855  r["File size"] = int(sizes[-1])
856 
857  cols = splitcols(ll[2])
858  sizes = cols[2].split()
859  if cols[0] == "Baskets":
860  r["Baskets"] = int(cols[1])
861  r["Basket size"] = int(sizes[2])
862  r["Compression"] = float(sizes[-1])
863  return r
864 
865  if i < (count - 3) and lines[i].startswith("*Tree"):
866  result = parseblock(lines[i:i+3])
867  result["Branches"] = {}
868  i += 4
869  while i < (count - 3) and lines[i].startswith("*Br"):
870  if i < (count - 2) and lines[i].startswith("*Branch "):
871  # skip branch header
872  i += 3
873  continue
874  branch = parseblock(lines[i:i+3])
875  result["Branches"][branch["Name"]] = branch
876  i += 4
877 
878  return (result, i)
def _parseTTreeSummary
Definition: BaseTest.py:830
def 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 785 of file BaseTest.py.

786 def cmpTreesDicts(reference, to_check, ignore = None):
787  """
788  Check that all the keys in reference are in to_check too, with the same value.
789  If the value is a dict, the function is called recursively. to_check can
790  contain more keys than reference, that will not be tested.
791  The function returns at the first difference found.
792  """
793  fail_keys = []
794  # filter the keys in the reference dictionary
795  if ignore:
796  ignore_re = re.compile(ignore)
797  keys = [ key for key in reference if not ignore_re.match(key) ]
798  else:
799  keys = reference.keys()
800  # loop over the keys (not ignored) in the reference dictionary
801  for k in keys:
802  if k in to_check: # the key must be in the dictionary to_check
803  if (type(reference[k]) is dict) and (type(to_check[k]) is dict):
804  # if both reference and to_check values are dictionaries, recurse
805  failed = fail_keys = cmpTreesDicts(reference[k], to_check[k], ignore)
806  else:
807  # compare the two values
808  failed = to_check[k] != reference[k]
809  else: # handle missing keys in the dictionary to check (i.e. failure)
810  to_check[k] = None
811  failed = True
812  if failed:
813  fail_keys.insert(0, k)
814  break # exit from the loop at the first failure
815  return fail_keys # return the list of keys bringing to the different values
string type
Definition: gaudirun.py:126
def cmpTreesDicts
Definition: BaseTest.py:785
def BaseTest.findHistosSummaries (   stdout)
    Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 944 of file BaseTest.py.

945 def findHistosSummaries(stdout):
946  """
947  Scan stdout to find ROOT TTree summaries and digest them.
948  """
949  outlines = stdout.splitlines()
950  nlines = len(outlines) - 1
951  summaries = {}
952  global h_count_re
953 
954  pos = 0
955  while pos < nlines:
956  summ = {}
957  # find first line of block:
958  match = h_count_re.search(outlines[pos])
959  while pos < nlines and not match:
960  pos += 1
961  match = h_count_re.search(outlines[pos])
962  if match:
963  summ, pos = parseHistosSummary(outlines, pos)
964  summaries.update(summ)
965  return summaries
def parseHistosSummary
Definition: BaseTest.py:879
def findHistosSummaries
Definition: BaseTest.py:944
def BaseTest.findTTreeSummaries (   stdout)
    Scan stdout to find ROOT TTree summaries and digest them.

Definition at line 764 of file BaseTest.py.

765 def findTTreeSummaries(stdout):
766  """
767  Scan stdout to find ROOT TTree summaries and digest them.
768  """
769  stars = re.compile(r"^\*+$")
770  outlines = stdout.splitlines()
771  nlines = len(outlines)
772  trees = {}
773 
774  i = 0
775  while i < nlines: #loop over the output
776  # look for
777  while i < nlines and not stars.match(outlines[i]):
778  i += 1
779  if i < nlines:
780  tree, i = _parseTTreeSummary(outlines, i)
781  if tree:
782  trees[tree["Name"]] = tree
783 
784  return trees
def findTTreeSummaries
Definition: BaseTest.py:764
def _parseTTreeSummary
Definition: BaseTest.py:830
def BaseTest.getCmpFailingValues (   reference,
  to_check,
  fail_path 
)

Definition at line 816 of file BaseTest.py.

817 def getCmpFailingValues(reference, to_check, fail_path):
818  c = to_check
819  r = reference
820  for k in fail_path:
821  c = c.get(k,None)
822  r = r.get(k,None)
823  if c is None or r is None:
824  break # one of the dictionaries is not deep enough
825  return (fail_path, r, c)
826 
# signature of the print-out of the histograms
def getCmpFailingValues
Definition: BaseTest.py:816
def BaseTest.GetPlatform (   self)
    Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.

Definition at line 976 of file BaseTest.py.

977 def GetPlatform(self):
978  """
979  Return the platform Id defined in CMTCONFIG or SCRAM_ARCH.
980  """
981  arch = "None"
982  # check architecture name
983  if "CMTCONFIG" in os.environ:
984  arch = os.environ["CMTCONFIG"]
985  elif "SCRAM_ARCH" in os.environ:
986  arch = os.environ["SCRAM_ARCH"]
987  return arch
def GetPlatform
Definition: BaseTest.py:976
def 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 988 of file BaseTest.py.

989 def isWinPlatform(self):
990  """
991  Return True if the current platform is Windows.
992 
993  This function was needed because of the change in the CMTCONFIG format,
994  from win32_vc71_dbg to i686-winxp-vc9-dbg.
995  """
996  platform = GetPlatform(self)
997  return "winxp" in platform or platform.startswith("win")
998 
def isWinPlatform
Definition: BaseTest.py:988
def GetPlatform
Definition: BaseTest.py:976
def 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 879 of file BaseTest.py.

880 def parseHistosSummary(lines, pos):
881  """
882  Extract the histograms infos from the lines starting at pos.
883  Returns the position of the first line after the summary block.
884  """
885  global h_count_re
886  h_table_head = re.compile(r'SUCCESS\s+List of booked (1D|2D|3D|1D profile|2D profile) histograms in directory\s+"(\w*)"')
887  h_short_summ = re.compile(r"ID=([^\"]+)\s+\"([^\"]+)\"\s+(.*)")
888 
889  nlines = len(lines)
890 
891  # decode header
892  m = h_count_re.search(lines[pos])
893  name = m.group(1).strip()
894  total = int(m.group(2))
895  header = {}
896  for k, v in [ x.split("=") for x in m.group(3).split() ]:
897  header[k] = int(v)
898  pos += 1
899  header["Total"] = total
900 
901  summ = {}
902  while pos < nlines:
903  m = h_table_head.search(lines[pos])
904  if m:
905  t, d = m.groups(1) # type and directory
906  t = t.replace(" profile", "Prof")
907  pos += 1
908  if pos < nlines:
909  l = lines[pos]
910  else:
911  l = ""
912  cont = {}
913  if l.startswith(" | ID"):
914  # table format
915  titles = [ x.strip() for x in l.split("|")][1:]
916  pos += 1
917  while pos < nlines and lines[pos].startswith(" |"):
918  l = lines[pos]
919  values = [ x.strip() for x in l.split("|")][1:]
920  hcont = {}
921  for i in range(len(titles)):
922  hcont[titles[i]] = values[i]
923  cont[hcont["ID"]] = hcont
924  pos += 1
925  elif l.startswith(" ID="):
926  while pos < nlines and lines[pos].startswith(" ID="):
927  values = [ x.strip() for x in h_short_summ.search(lines[pos]).groups() ]
928  cont[values[0]] = values
929  pos += 1
930  else: # not interpreted
931  raise RuntimeError("Cannot understand line %d: '%s'" % (pos, l))
932  if not d in summ:
933  summ[d] = {}
934  summ[d][t] = cont
935  summ[d]["header"] = header
936  else:
937  break
938  if not summ:
939  # If the full table is not present, we use only the header
940  summ[name] = {"header": header}
941  return summ, pos
942 
943 
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 parseHistosSummary
Definition: BaseTest.py:879
def BaseTest.PlatformIsNotSupported (   self,
  context,
  result 
)

Definition at line 966 of file BaseTest.py.

967 def PlatformIsNotSupported(self, context, result):
968  platform = GetPlatform(self)
969  unsupported = [ re.compile(x) for x in [ str(y).strip() for y in unsupported_platforms ] if x]
970  for p_re in unsupported :
971  if p_re.search(platform):
972  result.SetOutcome(result.UNTESTED)
973  result[result.CAUSE] = 'Platform not supported.'
974  return True
975  return False
def PlatformIsNotSupported
Definition: BaseTest.py:966
def GetPlatform
Definition: BaseTest.py:976
def BaseTest.RationalizePath (   p)
Function used to normalize the used path

Definition at line 425 of file BaseTest.py.

426 def RationalizePath(p) :
427  """
428  Function used to normalize the used path
429  """
430  newPath = os.path.normpath(os.path.expandvars(p))
431  if os.path.exists(newPath) :
432  p = os.path.realpath(newPath)
433  p = os.path.realpath(newPath)
434  return p
435 
def RationalizePath
Definition: BaseTest.py:425
def BaseTest.ROOT6WorkAroundEnabled (   id = None)

Definition at line 403 of file BaseTest.py.

404  def ROOT6WorkAroundEnabled(id=None):
405  # dummy implementation
406  return False
def ROOT6WorkAroundEnabled
Definition: BaseTest.py:403
def 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 436 of file BaseTest.py.

437 def which(executable):
438  """
439  Locates an executable in the executables path ($PATH) and returns the full
440  path to it. An application is looked for with or without the '.exe' suffix.
441  If the executable cannot be found, None is returned
442  """
443  if os.path.isabs(executable):
444  if not os.path.exists(executable):
445  if executable.endswith('.exe'):
446  if os.path.exists(executable[:-4]):
447  return executable[:-4]
448  else :
449  head,executable = os.path.split(executable)
450  else :
451  return executable
452  for d in os.environ.get("PATH").split(os.pathsep):
453  fullpath = os.path.join(d, executable)
454  if os.path.exists(fullpath):
455  return fullpath
456  if executable.endswith('.exe'):
457  return which(executable[:-4])
458  return None
459 
460 
461 
462 #-------------------------------------------------------------------------#
463 #----------------------------- Result Classe -----------------------------#
#-------------------------------------------------------------------------#
def which
Definition: BaseTest.py:436

Variable Documentation

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

Definition at line 827 of file BaseTest.py.

tuple BaseTest.lineSkipper

Definition at line 673 of file BaseTest.py.

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

Definition at line 628 of file BaseTest.py.

tuple 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] *(CES?T)?",
2  "00:00:00 1970-01-01")

Definition at line 629 of file BaseTest.py.

tuple BaseTest.normalizeEOL = FilePreprocessor()

Definition at line 631 of file BaseTest.py.

tuple BaseTest.normalizeExamples = maskPointers+normalizeDate

Definition at line 654 of file BaseTest.py.

tuple BaseTest.skipEmptyLines = FilePreprocessor()

Definition at line 634 of file BaseTest.py.