js/src/jit-test/jit_test.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #!/usr/bin/env python
     2 # This Source Code Form is subject to the terms of the Mozilla Public
     3 # License, v. 2.0. If a copy of the MPL was not distributed with this
     4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6 import math, os, posixpath, shlex, shutil, subprocess, sys, traceback
     8 def add_libdir_to_path():
     9     from os.path import dirname, exists, join, realpath
    10     js_src_dir = dirname(dirname(realpath(sys.argv[0])))
    11     assert exists(join(js_src_dir,'jsapi.h'))
    12     sys.path.insert(0, join(js_src_dir, 'lib'))
    13     sys.path.insert(0, join(js_src_dir, 'tests', 'lib'))
    15 add_libdir_to_path()
    17 import jittests
    18 from tests import TBPL_FLAGS
    20 def main(argv):
    22     # If no multiprocessing is available, fallback to serial test execution
    23     max_jobs_default = 1
    24     if jittests.HAVE_MULTIPROCESSING:
    25         try:
    26             max_jobs_default = jittests.cpu_count()
    27         except NotImplementedError:
    28             pass
    30     # The [TESTS] optional arguments are paths of test files relative
    31     # to the jit-test/tests directory.
    33     from optparse import OptionParser
    34     op = OptionParser(usage='%prog [options] JS_SHELL [TESTS]')
    35     op.add_option('-s', '--show-cmd', dest='show_cmd', action='store_true',
    36                   help='show js shell command run')
    37     op.add_option('-f', '--show-failed-cmd', dest='show_failed',
    38                   action='store_true', help='show command lines of failed tests')
    39     op.add_option('-o', '--show-output', dest='show_output', action='store_true',
    40                   help='show output from js shell')
    41     op.add_option('-x', '--exclude', dest='exclude', action='append',
    42                   help='exclude given test dir or path')
    43     op.add_option('--no-slow', dest='run_slow', action='store_false',
    44                   help='do not run tests marked as slow')
    45     op.add_option('-t', '--timeout', dest='timeout',  type=float, default=150.0,
    46                   help='set test timeout in seconds')
    47     op.add_option('--no-progress', dest='hide_progress', action='store_true',
    48                   help='hide progress bar')
    49     op.add_option('--tinderbox', dest='tinderbox', action='store_true',
    50                   help='Tinderbox-parseable output format')
    51     op.add_option('--args', dest='shell_args', default='',
    52                   help='extra args to pass to the JS shell')
    53     op.add_option('-w', '--write-failures', dest='write_failures', metavar='FILE',
    54                   help='Write a list of failed tests to [FILE]')
    55     op.add_option('-r', '--read-tests', dest='read_tests', metavar='FILE',
    56                   help='Run test files listed in [FILE]')
    57     op.add_option('-R', '--retest', dest='retest', metavar='FILE',
    58                   help='Retest using test list file [FILE]')
    59     op.add_option('-g', '--debug', dest='debug', action='store_true',
    60                   help='Run test in gdb')
    61     op.add_option('--valgrind', dest='valgrind', action='store_true',
    62                   help='Enable the |valgrind| flag, if valgrind is in $PATH.')
    63     op.add_option('--valgrind-all', dest='valgrind_all', action='store_true',
    64                   help='Run all tests with valgrind, if valgrind is in $PATH.')
    65     op.add_option('--jitflags', dest='jitflags', default='',
    66                   help='Example: --jitflags=m,mn to run each test with "-m" and "-m -n" [default="%default"]. ' +
    67                        'Long flags, such as "--ion-eager", should be set using --args.')
    68     op.add_option('--avoid-stdio', dest='avoid_stdio', action='store_true',
    69                   help='Use js-shell file indirection instead of piping stdio.')
    70     op.add_option('--write-failure-output', dest='write_failure_output', action='store_true',
    71                   help='With --write-failures=FILE, additionally write the output of failed tests to [FILE]')
    72     op.add_option('--ion', dest='ion', action='store_true',
    73                   help='Run tests once with --ion-eager and once with --baseline-eager (ignores --jitflags)')
    74     op.add_option('--tbpl', dest='tbpl', action='store_true',
    75                   help='Run tests with all IonMonkey option combinations (ignores --jitflags)')
    76     op.add_option('-j', '--worker-count', dest='max_jobs', type=int, default=max_jobs_default,
    77                   help='Number of tests to run in parallel (default %default)')
    78     op.add_option('--remote', action='store_true',
    79                   help='Run tests on a remote device')
    80     op.add_option('--deviceIP', action='store',
    81                   type='string', dest='device_ip',
    82                   help='IP address of remote device to test')
    83     op.add_option('--devicePort', action='store',
    84                   type=int, dest='device_port', default=20701,
    85                   help='port of remote device to test')
    86     op.add_option('--deviceSerial', action='store',
    87                   type='string', dest='device_serial', default=None,
    88                   help='ADB device serial number of remote device to test')
    89     op.add_option('--deviceTransport', action='store',
    90                   type='string', dest='device_transport', default='sut',
    91                   help='The transport to use to communicate with device: [adb|sut]; default=sut')
    92     op.add_option('--remoteTestRoot', dest='remote_test_root', action='store',
    93                   type='string', default='/data/local/tests',
    94                   help='The remote directory to use as test root (eg. /data/local/tests)')
    95     op.add_option('--localLib', dest='local_lib', action='store',
    96                   type='string',
    97                   help='The location of libraries to push -- preferably stripped')
    98     op.add_option('--repeat', type=int, default=1,
    99                   help='Repeat tests the given number of times.')
   100     op.add_option('--this-chunk', type=int, default=1,
   101                   help='The test chunk to run.')
   102     op.add_option('--total-chunks', type=int, default=1,
   103                   help='The total number of test chunks.')
   105     options, args = op.parse_args(argv)
   106     if len(args) < 1:
   107         op.error('missing JS_SHELL argument')
   108     # We need to make sure we are using backslashes on Windows.
   109     test_args = args[1:]
   111     if jittests.stdio_might_be_broken():
   112         # Prefer erring on the side of caution and not using stdio if
   113         # it might be broken on this platform.  The file-redirect
   114         # fallback should work on any platform, so at worst by
   115         # guessing wrong we might have slowed down the tests a bit.
   116         #
   117         # XXX technically we could check for broken stdio, but it
   118         # really seems like overkill.
   119         options.avoid_stdio = True
   121     if options.retest:
   122         options.read_tests = options.retest
   123         options.write_failures = options.retest
   125     test_list = []
   126     read_all = True
   128     if test_args:
   129         read_all = False
   130         for arg in test_args:
   131             test_list += jittests.find_tests(arg)
   133     if options.read_tests:
   134         read_all = False
   135         try:
   136             f = open(options.read_tests)
   137             for line in f:
   138                 test_list.append(os.path.join(jittests.TEST_DIR, line.strip('\n')))
   139             f.close()
   140         except IOError:
   141             if options.retest:
   142                 read_all = True
   143             else:
   144                 sys.stderr.write("Exception thrown trying to read test file '%s'\n"%
   145                                  options.read_tests)
   146                 traceback.print_exc()
   147                 sys.stderr.write('---\n')
   149     if read_all:
   150         test_list = jittests.find_tests()
   152     if options.exclude:
   153         exclude_list = []
   154         for exclude in options.exclude:
   155             exclude_list += jittests.find_tests(exclude)
   156         test_list = [ test for test in test_list if test not in set(exclude_list) ]
   158     if not test_list:
   159         print >> sys.stderr, "No tests found matching command line arguments."
   160         sys.exit(0)
   162     test_list = [jittests.Test.from_file(_, options) for _ in test_list]
   164     if not options.run_slow:
   165         test_list = [ _ for _ in test_list if not _.slow ]
   167     # If chunking is enabled, determine which tests are part of this chunk.
   168     # This code was adapted from testing/mochitest/runtestsremote.py.
   169     if options.total_chunks > 1:
   170         total_tests = len(test_list)
   171         tests_per_chunk = math.ceil(total_tests / float(options.total_chunks))
   172         start = int(round((options.this_chunk - 1) * tests_per_chunk))
   173         end = int(round(options.this_chunk * tests_per_chunk))
   174         test_list = test_list[start:end]
   176     # The full test list is ready. Now create copies for each JIT configuration.
   177     job_list = []
   178     if options.tbpl:
   179         # Running all bits would take forever. Instead, we test a few interesting combinations.
   180         for test in test_list:
   181             for variant in TBPL_FLAGS:
   182                 new_test = test.copy()
   183                 new_test.jitflags.extend(variant)
   184                 job_list.append(new_test)
   185     elif options.ion:
   186         flags = [['--baseline-eager'], ['--ion-eager', '--ion-parallel-compile=off']]
   187         for test in test_list:
   188             for variant in flags:
   189                 new_test = test.copy()
   190                 new_test.jitflags.extend(variant)
   191                 job_list.append(new_test)
   192     else:
   193         jitflags_list = jittests.parse_jitflags(options)
   194         for test in test_list:
   195             for jitflags in jitflags_list:
   196                 new_test = test.copy()
   197                 new_test.jitflags.extend(jitflags)
   198                 job_list.append(new_test)
   200     prefix = [os.path.abspath(args[0])] + shlex.split(options.shell_args)
   201     prolog = os.path.join(jittests.LIB_DIR, 'prolog.js')
   202     if options.remote:
   203         prolog = posixpath.join(options.remote_test_root, 'jit-tests', 'jit-tests', 'lib', 'prolog.js')
   205     prefix += ['-f', prolog]
   207     # Avoid racing on the cache by having the js shell create a new cache
   208     # subdir for each process. The js shell takes care of deleting these
   209     # subdirs when the process exits.
   210     if options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING:
   211         prefix += ['--js-cache-per-process']
   213     # Clean up any remnants from previous crashes etc
   214     shutil.rmtree(jittests.JS_CACHE_DIR, ignore_errors=True)
   215     os.mkdir(jittests.JS_CACHE_DIR)
   217     if options.debug:
   218         if len(job_list) > 1:
   219             print 'Multiple tests match command line arguments, debugger can only run one'
   220             for tc in job_list:
   221                 print '    %s' % tc.path
   222             sys.exit(1)
   224         tc = job_list[0]
   225         cmd = ['gdb', '--args'] + tc.command(prefix, jittests.LIB_DIR)
   226         subprocess.call(cmd)
   227         sys.exit()
   229     try:
   230         ok = None
   231         if options.remote:
   232             ok = jittests.run_tests_remote(job_list, prefix, options)
   233         elif options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING:
   234             ok = jittests.run_tests_parallel(job_list, prefix, options)
   235         else:
   236             ok = jittests.run_tests(job_list, prefix, options)
   237         if not ok:
   238             sys.exit(2)
   239     except OSError:
   240         if not os.path.exists(prefix[0]):
   241             print >> sys.stderr, "JS shell argument: file does not exist: '%s'" % prefix[0]
   242             sys.exit(1)
   243         else:
   244             raise
   246 if __name__ == '__main__':
   247     main(sys.argv[1:])

mercurial