testing/mach_commands.py

changeset 0
6474c204b198
     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)

mercurial