1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/mach_commands.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,237 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +from __future__ import print_function, unicode_literals 1.9 + 1.10 +import os 1.11 + 1.12 +from mach.decorators import ( 1.13 + CommandArgument, 1.14 + CommandProvider, 1.15 + Command, 1.16 +) 1.17 + 1.18 +from mozbuild.base import MachCommandBase 1.19 + 1.20 + 1.21 +HANDLE_FILE_ERROR = ''' 1.22 +%s is a file. 1.23 +However, I do not yet know how to run tests from files. You'll need to run 1.24 +the mach command for the test type you are trying to run. e.g. 1.25 +$ mach xpcshell-test path/to/file 1.26 +'''.strip() 1.27 + 1.28 +HANDLE_DIR_ERROR = ''' 1.29 +%s is a directory. 1.30 +However, I do not yet know how to run tests from directories. You can try 1.31 +running the mach command for the tests in that directory. e.g. 1.32 +$ mach xpcshell-test path/to/directory 1.33 +'''.strip() 1.34 + 1.35 +UNKNOWN_TEST = ''' 1.36 +I don't know how to run the test: %s 1.37 + 1.38 +You need to specify a test suite name or abbreviation. It's possible I just 1.39 +haven't been told about this test suite yet. If you suspect that's the issue, 1.40 +please file a bug at https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=General 1.41 +and request support be added. 1.42 +'''.strip() 1.43 + 1.44 +MOCHITEST_CHUNK_BY_DIR = 4 1.45 +MOCHITEST_TOTAL_CHUNKS = 5 1.46 + 1.47 +TEST_SUITES = { 1.48 + 'cppunittest': { 1.49 + 'aliases': ('Cpp', 'cpp'), 1.50 + 'mach_command': 'cppunittest', 1.51 + 'kwargs': {'test_file': None}, 1.52 + }, 1.53 + 'crashtest': { 1.54 + 'aliases': ('C', 'Rc', 'RC', 'rc'), 1.55 + 'mach_command': 'crashtest', 1.56 + 'kwargs': {'test_file': None}, 1.57 + }, 1.58 + 'crashtest-ipc': { 1.59 + 'aliases': ('Cipc', 'cipc'), 1.60 + 'mach_command': 'crashtest-ipc', 1.61 + 'kwargs': {'test_file': None}, 1.62 + }, 1.63 + 'jetpack': { 1.64 + 'aliases': ('J',), 1.65 + 'mach_command': 'jetpack-test', 1.66 + 'kwargs': {}, 1.67 + }, 1.68 + 'jittest': { 1.69 + 'aliases': ('Jit', 'jit'), 1.70 + 'mach_command': 'jittest', 1.71 + 'kwargs': {'test_file': None}, 1.72 + }, 1.73 + 'mochitest-a11y': { 1.74 + 'mach_command': 'mochitest-a11y', 1.75 + 'kwargs': {'test_file': None}, 1.76 + }, 1.77 + 'mochitest-browser': { 1.78 + 'aliases': ('bc', 'BC', 'Bc'), 1.79 + 'mach_command': 'mochitest-browser', 1.80 + 'kwargs': {'test_file': None}, 1.81 + }, 1.82 + 'mochitest-chrome': { 1.83 + 'mach_command': 'mochitest-chrome', 1.84 + 'kwargs': {'test_file': None}, 1.85 + }, 1.86 + 'mochitest-devtools': { 1.87 + 'aliases': ('dt', 'DT', 'Dt'), 1.88 + 'mach_command': 'mochitest-browser --subsuite=devtools', 1.89 + 'kwargs': {'test_file': None}, 1.90 + }, 1.91 + 'mochitest-ipcplugins': { 1.92 + 'make_target': 'mochitest-ipcplugins', 1.93 + }, 1.94 + 'mochitest-plain': { 1.95 + 'mach_command': 'mochitest-plain', 1.96 + 'kwargs': {'test_file': None}, 1.97 + }, 1.98 + 'reftest': { 1.99 + 'aliases': ('RR', 'rr', 'Rr'), 1.100 + 'mach_command': 'reftest', 1.101 + 'kwargs': {'test_file': None}, 1.102 + }, 1.103 + 'reftest-ipc': { 1.104 + 'aliases': ('Ripc',), 1.105 + 'mach_command': 'reftest-ipc', 1.106 + 'kwargs': {'test_file': None}, 1.107 + }, 1.108 + 'valgrind': { 1.109 + 'aliases': ('V', 'v'), 1.110 + 'mach_command': 'valgrind-test', 1.111 + 'kwargs': {}, 1.112 + }, 1.113 + 'xpcshell': { 1.114 + 'aliases': ('X', 'x'), 1.115 + 'mach_command': 'xpcshell-test', 1.116 + 'kwargs': {'test_file': 'all'}, 1.117 + }, 1.118 +} 1.119 + 1.120 +for i in range(1, MOCHITEST_TOTAL_CHUNKS + 1): 1.121 + TEST_SUITES['mochitest-%d' %i] = { 1.122 + 'aliases': ('M%d' % i, 'm%d' % i), 1.123 + 'mach_command': 'mochitest-plain', 1.124 + 'kwargs': { 1.125 + 'chunk_by_dir': MOCHITEST_CHUNK_BY_DIR, 1.126 + 'total_chunks': MOCHITEST_TOTAL_CHUNKS, 1.127 + 'this_chunk': i, 1.128 + 'test_file': None, 1.129 + }, 1.130 + } 1.131 + 1.132 +TEST_HELP = ''' 1.133 +Test or tests to run. Tests can be specified by test suite name or alias. 1.134 +The following test suites and aliases are supported: %s 1.135 +''' % ', '.join(sorted(TEST_SUITES)) 1.136 +TEST_HELP = TEST_HELP.strip() 1.137 + 1.138 + 1.139 +@CommandProvider 1.140 +class Test(MachCommandBase): 1.141 + @Command('test', category='testing', description='Run tests.') 1.142 + @CommandArgument('what', default=None, nargs='*', help=TEST_HELP) 1.143 + def test(self, what): 1.144 + status = None 1.145 + for entry in what: 1.146 + status = self._run_test(entry) 1.147 + 1.148 + if status: 1.149 + break 1.150 + 1.151 + return status 1.152 + 1.153 + def _run_test(self, what): 1.154 + suite = None 1.155 + if what in TEST_SUITES: 1.156 + suite = TEST_SUITES[what] 1.157 + else: 1.158 + for v in TEST_SUITES.values(): 1.159 + if what in v.get('aliases', []): 1.160 + suite = v 1.161 + break 1.162 + 1.163 + if suite: 1.164 + if 'mach_command' in suite: 1.165 + return self._mach_context.commands.dispatch( 1.166 + suite['mach_command'], self._mach_context, **suite['kwargs']) 1.167 + 1.168 + if 'make_target' in suite: 1.169 + return self._run_make(target=suite['make_target'], 1.170 + pass_thru=True) 1.171 + 1.172 + raise Exception('Do not know how to run suite. This is a logic ' 1.173 + 'error in this mach command.') 1.174 + 1.175 + if os.path.isfile(what): 1.176 + print(HANDLE_FILE_ERROR % what) 1.177 + return 1 1.178 + 1.179 + if os.path.isdir(what): 1.180 + print(HANDLE_DIR_ERROR % what) 1.181 + return 1 1.182 + 1.183 + print(UNKNOWN_TEST % what) 1.184 + return 1 1.185 + 1.186 +@CommandProvider 1.187 +class MachCommands(MachCommandBase): 1.188 + @Command('cppunittest', category='testing', 1.189 + description='Run cpp unit tests.') 1.190 + @CommandArgument('test_files', nargs='*', metavar='N', 1.191 + help='Test to run. Can be specified as one or more files or ' \ 1.192 + 'directories, or omitted. If omitted, the entire test suite is ' \ 1.193 + 'executed.') 1.194 + 1.195 + def run_cppunit_test(self, **params): 1.196 + import runcppunittests as cppunittests 1.197 + import logging 1.198 + 1.199 + if len(params['test_files']) == 0: 1.200 + testdir = os.path.join(self.distdir, 'cppunittests') 1.201 + progs = cppunittests.extract_unittests_from_args([testdir], None) 1.202 + else: 1.203 + progs = cppunittests.extract_unittests_from_args(params['test_files'], None) 1.204 + 1.205 + # See if we have crash symbols 1.206 + symbols_path = os.path.join(self.distdir, 'crashreporter-symbols') 1.207 + if not os.path.isdir(symbols_path): 1.208 + symbols_path = None 1.209 + 1.210 + tester = cppunittests.CPPUnitTests() 1.211 + try: 1.212 + result = tester.run_tests(progs, self.bindir, symbols_path) 1.213 + except Exception, e: 1.214 + self.log(logging.ERROR, 'cppunittests', 1.215 + {'exception': str(e)}, 1.216 + 'Caught exception running cpp unit tests: {exception}') 1.217 + result = False 1.218 + 1.219 + return 0 if result else 1 1.220 + 1.221 +@CommandProvider 1.222 +class JittestCommand(MachCommandBase): 1.223 + @Command('jittest', category='testing', description='Run jit-test tests.') 1.224 + @CommandArgument('--valgrind', action='store_true', help='Run jit-test suite with valgrind flag') 1.225 + 1.226 + def run_jittest(self, **params): 1.227 + import subprocess 1.228 + import sys 1.229 + 1.230 + if sys.platform.startswith('win'): 1.231 + js = os.path.join(self.bindir, 'js.exe') 1.232 + else: 1.233 + js = os.path.join(self.bindir, 'js') 1.234 + cmd = [os.path.join(self.topsrcdir, 'js', 'src', 'jit-test', 'jit_test.py'), 1.235 + js, '--no-slow', '--no-progress', '--tinderbox', '--tbpl'] 1.236 + 1.237 + if params['valgrind']: 1.238 + cmd.append('--valgrind') 1.239 + 1.240 + return subprocess.call(cmd)