The Gaudi Framework  v36r16 (ea80daf8)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Run.py
Go to the documentation of this file.
1 
11 from __future__ import print_function
12 
13 import importlib
14 import logging
15 import os
16 import sys
17 import xml.sax.saxutils as XSS
18 
19 from GaudiTesting import BaseTest as GT
20 
21 # FIXME: module alias for backward compatibility
22 sys.modules["GaudiTest"] = GT
23 
24 
25 def basic_report(results):
26  """
27  Report function taking the dictionary from BasicTest.run() and display
28  stdout and stderr from it.
29  """
30  print("=== stdout ===")
31  print(results.get("stdout", ""))
32  print("=== stderr ===")
33  print(results.get("stderr", ""))
34  print("=== result ===")
35  print(results.get("Status"))
36  if results.get("Status") != "passed" and "Causes" in results:
37  print(" ", "unexpected " + ", ".join(results["Causes"]))
38 
39 
40 def quiet_report(results):
41  """
42  Do not report anything from the result of the test.
43  """
44  pass
45 
46 
47 def ctest_report(results):
48  """
49  Report function taking the dictionary from BasicTest.run() and report data
50  from it in a CTest-friendly way.
51  """
52  # It's weird, I know, but it tells CTest not to cut the output.
53  print("CTEST_FULL_OUTPUT")
54  print(results.get("stdout", ""))
55  handler = {
56  "Runtime Environment": lambda v: "<pre>%s</pre>"
57  % "\n".join("{0}={1}".format(*item) for item in sorted(v.items())),
58  "Causes": lambda v: "unexpected " + ", ".join(v),
59  }
60 
61  def id_handler(v):
62  return str(v)
63 
64  ignore = set(["Status", "Name", "stdout", "Exit Code"])
65  template = '<DartMeasurement type="text/string" name="{0}">{1}</DartMeasurement>'
66 
67  for key in results:
68  if key in ignore:
69  continue
70  hndlr = handler.get(key, id_handler)
71  data = XSS.escape(GT.sanitize_for_xml(hndlr(results[key])))
72  print(template.format(key, data))
73 
74 
75 def pprint_report(results):
76  """
77  Report function taking the dictionary from BasicTest.run() and print it with
78  the pprint module.
79  """
80  from pprint import pprint
81 
82  pprint(results)
83 
84 
85 def main():
86  """
87  Main function of the script.
88  """
89  from optparse import OptionGroup, OptionParser
90 
91  parser = OptionParser()
92 
93  parser.add_option(
94  "--report",
95  action="store",
96  choices=[n.replace("_report", "") for n in globals() if n.endswith("_report")],
97  help="choose a report method [default %default]",
98  )
99  parser.add_option(
100  "--common-tmpdir",
101  action="store",
102  help="directory to be used as common temporary directory",
103  )
104  parser.add_option(
105  "-C",
106  "--workdir",
107  action="store",
108  help="directory to change to before starting the test",
109  )
110 
111  parser.add_option(
112  "--skip-return-code",
113  type="int",
114  help="return code to use to flag a test as skipped " "[default %default]",
115  )
116 
117  verbosity_opts = OptionGroup(
118  parser, "Verbosity Level", "set the verbosity level of messages"
119  )
120  verbosity_opts.add_option(
121  "--silent",
122  action="store_const",
123  dest="log_level",
124  const=logging.CRITICAL,
125  help="only critical error messages",
126  )
127  verbosity_opts.add_option(
128  "--quiet",
129  action="store_const",
130  dest="log_level",
131  const=logging.ERROR,
132  help="error messages",
133  )
134  verbosity_opts.add_option(
135  "--warning",
136  action="store_const",
137  dest="log_level",
138  const=logging.WARNING,
139  help="warning and error messages",
140  )
141  verbosity_opts.add_option(
142  "--verbose",
143  action="store_const",
144  dest="log_level",
145  const=logging.INFO,
146  help="progress information messages",
147  )
148  verbosity_opts.add_option(
149  "--debug",
150  action="store_const",
151  dest="log_level",
152  const=logging.DEBUG,
153  help="debugging messages",
154  )
155  parser.add_option_group(verbosity_opts)
156 
157  parser.set_defaults(
158  log_level=logging.WARNING, report="basic", workdir=os.curdir, skip_return_code=0
159  )
160 
161  opts, args = parser.parse_args()
162  if len(args) != 1:
163  parser.error("only one test allowed")
164  filename = args[0]
165 
166  logging.basicConfig(level=opts.log_level)
167 
168  if opts.common_tmpdir:
169  if not os.path.isdir(opts.common_tmpdir):
170  os.makedirs(opts.common_tmpdir)
171  GT.BaseTest._common_tmpdir = opts.common_tmpdir
172 
173  os.chdir(opts.workdir)
174 
175  # FIXME: whithout this, we get some spurious '\x1b[?1034' in the std out on SLC6
176  if "slc6" in (os.environ.get("BINARY_TAG", "") or os.environ.get("CMTCONFIG", "")):
177  os.environ["TERM"] = "dumb"
178 
179  # If running sanitizer builds, set LD_PRELOAD in environment
180  sanitizer = os.environ.get("PRELOAD_SANITIZER_LIB", "")
181  ld_preload = os.environ.get("LD_PRELOAD", "")
182  if sanitizer and sanitizer not in ld_preload:
183  if ld_preload:
184  os.environ["LD_PRELOAD"] = sanitizer + " " + ld_preload
185  else:
186  os.environ["LD_PRELOAD"] = sanitizer
187 
188  # Testing the file beginning with "Test" or if it is a qmt file and doing the test
189  logging.debug("processing %s", filename)
190  if filename.endswith("_test.py"):
191  indexFilePart = filename.rfind("/")
192  fileToImport = filename[indexFilePart + 1 :]
193  sys.path.append(GT.RationalizePath(filename)[: -len(fileToImport) - 1])
194  imp = __import__(fileToImport[:-3])
195  fileToExec = imp.Test()
196  results = fileToExec.run()
197  elif filename.endswith(".qmt"):
198  # Check which class should be used to instantiate QMTests
199  # by default it is QMTTest but this can be overwritten via the environment
200  test_module = os.environ.get("GAUDI_QMTEST_MODULE", "GaudiTesting.QMTTest")
201  test_class = os.environ.get("GAUDI_QMTEST_CLASS", "QMTTest")
202  test_class = getattr(importlib.import_module(test_module), test_class)
203  fileToTest = test_class(filename)
204  results = fileToTest.run()
205 
206  report = globals()[opts.report + "_report"]
207  report(results)
208 
209  if results.get("Status") == "failed":
210  logging.debug("test failed: unexpected %s", ", ".join(results["Causes"]))
211  return int(results.get("Exit Code", "1"))
212  elif results.get("Status") == "skipped":
213  return opts.skip_return_code
214  return 0
215 
216 
217 if __name__ == "__main__":
218  sys.exit(main())
GaudiTesting.Run.main
def main()
Definition: Run.py:85
GaudiTesting.Run.quiet_report
def quiet_report(results)
Definition: Run.py:40
GaudiTesting.Run.basic_report
def basic_report(results)
Definition: Run.py:25
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
GaudiTesting.Run.pprint_report
def pprint_report(results)
Definition: Run.py:75
GaudiTesting.Run.ctest_report
def ctest_report(results)
Definition: Run.py:47