blob: 7f9673dd5cd9bd0db69fd4200f29b8ed240a2986 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import optparse
import os
import platform
import re
import sys
import types
import traceback
import unittest
def discover(dir, filters):
if hasattr(unittest.TestLoader, 'discover'):
return unittest.TestLoader().discover(dir, '*')
# poor mans unittest.discover
loader = unittest.TestLoader()
subsuites = []
for (dirpath, dirnames, filenames) in os.walk(dir):
for filename in [x for x in filenames if re.match('.*_test\.py$', x)]:
if filename.startswith('.') or filename.startswith('_'):
continue
fqn = dirpath.replace(
'/', '.') + '.' + re.match('(.+)\.py$', filename).group(1)
# load the test
try:
module = __import__(fqn,fromlist=[True])
except:
print "While importing [%s]\n" % fqn
traceback.print_exc()
continue
def test_is_selected(name):
for f in filters:
if re.search(f,name):
return True
return False
if hasattr(module, 'suite'):
base_suite = module.suite()
else:
base_suite = loader.loadTestsFromModule(module)
new_suite = unittest.TestSuite()
for t in base_suite:
if isinstance(t, unittest.TestSuite):
for i in t:
if test_is_selected(i.id()):
new_suite.addTest(i)
elif isinstance(t, unittest.TestCase):
if test_is_selected(t.id()):
new_suite.addTest(t)
else:
raise Exception("Wtf, expected TestSuite or TestCase, got %s" % t)
if new_suite.countTestCases():
subsuites.append(new_suite)
return unittest.TestSuite(subsuites)
def main():
parser = optparse.OptionParser()
parser.add_option(
'-v', '--verbose', action='count', default=0,
help='Increase verbosity level (repeat as needed)')
parser.add_option('--debug', dest='debug', action='store_true', default=False,
help='Break into pdb when an assertion fails')
parser.add_option('--incremental', dest='incremental', action='store_true',
default=False, help='Run tests one at a time.')
parser.add_option('--stop', dest='stop_on_error', action='store_true',
default=False, help='Stop running tests on error.')
(options, args) = parser.parse_args()
if options.verbose >= 2:
logging.basicConfig(level=logging.DEBUG)
elif options.verbose:
logging.basicConfig(level=logging.INFO)
else:
logging.basicConfig(level=logging.WARNING)
# install hook on set_trace if --debug
if options.debug:
import exceptions
class DebuggingAssertionError(exceptions.AssertionError):
def __init__(self, *args):
exceptions.AssertionError.__init__(self, *args)
print "Assertion failed, entering PDB..."
import pdb
if hasattr(sys, '_getframe'):
pdb.Pdb().set_trace(sys._getframe().f_back.f_back)
else:
pdb.set_trace()
unittest.TestCase.failureException = DebuggingAssertionError
def hook(*args):
import traceback, pdb
traceback.print_exception(*args)
pdb.pm()
sys.excepthook = hook
import browser
browser.debug_mode = True
else:
def hook(exc, value, tb):
import traceback
if not str(value).startswith("_noprint"):
traceback.print_exception(exc, value, tb)
import src.message_loop
if src.message_loop.is_main_loop_running():
if not str(value).startswith("_noprint"):
print "Untrapped exception! Exiting message loop with exception."
src.message_loop.quit_main_loop(quit_with_exception=True)
sys.excepthook = hook
# make sure cwd is the base directory!
os.chdir(os.path.dirname(__file__))
if len(args) > 0:
suites = discover('trace_event_impl', args)
else:
suites = discover('trace_event_impl', ['.*'])
r = unittest.TextTestRunner()
if not options.incremental:
res = r.run(suites)
if res.wasSuccessful():
return 0
return 255
else:
ok = True
for s in suites:
if isinstance(s, unittest.TestSuite):
for t in s:
print '--------------------------------------------------------------'
print 'Running %s' % str(t)
res = r.run(t)
if not res.wasSuccessful():
ok = False
if options.stop_on_error:
break
if ok == False and options.stop_on_error:
break
else:
res = r.run(s)
if not res.wasSuccessful():
ok = False
if options.stop_on_error:
break
if ok:
return 0
return 255
if __name__ == "__main__":
sys.exit(main())