51f57a71629c79f6c3b8458762edc9d4130ebeb7
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / unittest / run_tests.py
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 import logging
5 import unittest
6
7 from telemetry.core import browser_options
8 from telemetry.core import discover
9 from telemetry.core import util
10 from telemetry.core.backends.chrome import cros_interface
11 from telemetry.unittest import gtest_testrunner
12 from telemetry.unittest import options_for_unittests
13
14 def Discover(start_dir, top_level_dir=None, pattern='test*.py'):
15   loader = unittest.defaultTestLoader
16   loader.suiteClass = gtest_testrunner.GTestTestSuite
17   subsuites = []
18
19   modules = discover.DiscoverModules(start_dir, top_level_dir, pattern)
20   for module in modules:
21     if hasattr(module, 'suite'):
22       new_suite = module.suite()
23     else:
24       new_suite = loader.loadTestsFromModule(module)
25     if new_suite.countTestCases():
26       subsuites.append(new_suite)
27   return gtest_testrunner.GTestTestSuite(subsuites)
28
29
30 def FilterSuite(suite, predicate):
31   new_suite = suite.__class__()
32   for x in suite:
33     if isinstance(x, unittest.TestSuite):
34       subsuite = FilterSuite(x, predicate)
35       if subsuite.countTestCases() == 0:
36         continue
37
38       new_suite.addTest(subsuite)
39       continue
40
41     assert isinstance(x, unittest.TestCase)
42     if predicate(x):
43       new_suite.addTest(x)
44
45   return new_suite
46
47
48 def DiscoverAndRunTests(
49     dir_name, args, top_level_dir,
50     runner=None, run_disabled_tests=False):
51   if not runner:
52     runner = gtest_testrunner.GTestTestRunner(inner=True)
53
54   suite = Discover(dir_name, top_level_dir, '*_unittest.py')
55
56   def IsTestSelected(test):
57     if len(args) != 0:
58       found = False
59       for name in args:
60         if name in test.id():
61           found = True
62       if not found:
63         return False
64
65     if hasattr(test, '_testMethodName'):
66       method = getattr(test, test._testMethodName) # pylint: disable=W0212
67       if hasattr(method, '_requires_browser_types'):
68         types = method._requires_browser_types # pylint: disable=W0212
69         if options_for_unittests.GetBrowserType() not in types:
70           logging.debug('Skipping test %s because it requires %s' %
71                         (test.id(), types))
72           return False
73
74       if (not run_disabled_tests and
75           (hasattr(method, '_disabled_test') or
76               (hasattr(method, '_disabled_test_on_cros') and
77                   cros_interface.IsRunningOnCrosDevice()))):
78         return False
79
80     return True
81
82   filtered_suite = FilterSuite(suite, IsTestSelected)
83   test_result = runner.run(filtered_suite)
84   return test_result
85
86
87 def RestoreLoggingLevel(func):
88   def _LoggingRestoreWrapper(*args, **kwargs):
89     # Cache the current logging level, this needs to be done before calling
90     # parser.parse_args, which changes logging level based on verbosity
91     # setting.
92     logging_level = logging.getLogger().getEffectiveLevel()
93     try:
94       return func(*args, **kwargs)
95     finally:
96       # Restore logging level, which may be changed in parser.parse_args.
97       logging.getLogger().setLevel(logging_level)
98
99   return _LoggingRestoreWrapper
100
101
102 @RestoreLoggingLevel
103 def Main(args, start_dir, top_level_dir, runner=None):
104   """Unit test suite that collects all test cases for telemetry."""
105   # Add unittest_data to the path so we can import packages from it.
106   util.AddDirToPythonPath(util.GetUnittestDataDir())
107
108   default_options = browser_options.BrowserFinderOptions()
109   default_options.browser_type = 'any'
110
111   parser = default_options.CreateParser('run_tests [options] [test names]')
112   parser.add_option('--repeat-count', dest='run_test_repeat_count',
113                     type='int', default=1,
114                     help='Repeats each a provided number of times.')
115   parser.add_option('-d', '--also-run-disabled-tests',
116                     dest='run_disabled_tests',
117                     action='store_true', default=False,
118                     help='Also run tests decorated with @DisabledTest.')
119
120   _, args = parser.parse_args(args)
121
122   if default_options.verbosity == 0:
123     logging.getLogger().setLevel(logging.WARN)
124
125   from telemetry.core import browser_finder
126   try:
127     browser_to_create = browser_finder.FindBrowser(default_options)
128   except browser_finder.BrowserFinderException, ex:
129     logging.error(str(ex))
130     return 1
131
132   if browser_to_create == None:
133     logging.error('No browser found of type %s. Cannot run tests.',
134                   default_options.browser_type)
135     logging.error('Re-run with --browser=list to see available browser types.')
136     return 1
137
138   options_for_unittests.Set(default_options,
139                             browser_to_create.browser_type)
140   try:
141     success = True
142     for _ in range(
143         default_options.run_test_repeat_count): # pylint: disable=E1101
144       success = success and DiscoverAndRunTests(
145         start_dir, args, top_level_dir,
146         runner, default_options.run_disabled_tests)
147     if success:
148       return 0
149   finally:
150     options_for_unittests.Set(None, None)
151
152   return 1