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