The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / tools / run-tests.py @ f230a1cf

History | View | Annotate | Download (15.1 KB)

1
#!/usr/bin/env python
2
#
3
# Copyright 2012 the V8 project authors. All rights reserved.
4
# Redistribution and use in source and binary forms, with or without
5
# modification, are permitted provided that the following conditions are
6
# met:
7
#
8
#     * Redistributions of source code must retain the above copyright
9
#       notice, this list of conditions and the following disclaimer.
10
#     * Redistributions in binary form must reproduce the above
11
#       copyright notice, this list of conditions and the following
12
#       disclaimer in the documentation and/or other materials provided
13
#       with the distribution.
14
#     * Neither the name of Google Inc. nor the names of its
15
#       contributors may be used to endorse or promote products derived
16
#       from this software without specific prior written permission.
17
#
18
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29

    
30

    
31
import multiprocessing
32
import optparse
33
import os
34
from os.path import join
35
import shlex
36
import subprocess
37
import sys
38
import time
39

    
40
from testrunner.local import execution
41
from testrunner.local import progress
42
from testrunner.local import testsuite
43
from testrunner.local import utils
44
from testrunner.local import verbose
45
from testrunner.network import network_execution
46
from testrunner.objects import context
47

    
48

    
49
ARCH_GUESS = utils.DefaultArch()
50
DEFAULT_TESTS = ["mjsunit", "cctest", "message", "preparser"]
51
TIMEOUT_DEFAULT = 60
52
TIMEOUT_SCALEFACTOR = {"debug"   : 4,
53
                       "release" : 1 }
54

    
55
# Use this to run several variants of the tests.
56
VARIANT_FLAGS = [[],
57
                 ["--stress-opt", "--always-opt"],
58
                 ["--nocrankshaft"]]
59
MODE_FLAGS = {
60
    "debug"   : ["--nobreak-on-abort", "--nodead-code-elimination",
61
                 "--nofold-constants", "--enable-slow-asserts",
62
                 "--debug-code", "--verify-heap"],
63
    "release" : ["--nobreak-on-abort", "--nodead-code-elimination",
64
                 "--nofold-constants"]}
65

    
66
SUPPORTED_ARCHS = ["android_arm",
67
                   "android_ia32",
68
                   "arm",
69
                   "ia32",
70
                   "mipsel",
71
                   "nacl_ia32",
72
                   "nacl_x64",
73
                   "x64"]
74
# Double the timeout for these:
75
SLOW_ARCHS = ["android_arm",
76
              "android_ia32",
77
              "arm",
78
              "mipsel",
79
              "nacl_ia32",
80
              "nacl_x64"]
81

    
82

    
83
def BuildOptions():
84
  result = optparse.OptionParser()
85
  result.add_option("--arch",
86
                    help=("The architecture to run tests for, "
87
                          "'auto' or 'native' for auto-detect"),
88
                    default="ia32,x64,arm")
89
  result.add_option("--arch-and-mode",
90
                    help="Architecture and mode in the format 'arch.mode'",
91
                    default=None)
92
  result.add_option("--buildbot",
93
                    help="Adapt to path structure used on buildbots",
94
                    default=False, action="store_true")
95
  result.add_option("--cat", help="Print the source of the tests",
96
                    default=False, action="store_true")
97
  result.add_option("--flaky-tests",
98
                    help="Regard tests marked as flaky (run|skip|dontcare)",
99
                    default="dontcare")
100
  result.add_option("--command-prefix",
101
                    help="Prepended to each shell command used to run a test",
102
                    default="")
103
  result.add_option("--download-data", help="Download missing test suite data",
104
                    default=False, action="store_true")
105
  result.add_option("--extra-flags",
106
                    help="Additional flags to pass to each test command",
107
                    default="")
108
  result.add_option("--isolates", help="Whether to test isolates",
109
                    default=False, action="store_true")
110
  result.add_option("-j", help="The number of parallel tasks to run",
111
                    default=0, type="int")
112
  result.add_option("-m", "--mode",
113
                    help="The test modes in which to run (comma-separated)",
114
                    default="release,debug")
115
  result.add_option("--no-i18n", "--noi18n",
116
                    help="Skip internationalization tests",
117
                    default=False, action="store_true")
118
  result.add_option("--no-network", "--nonetwork",
119
                    help="Don't distribute tests on the network",
120
                    default=(utils.GuessOS() != "linux"),
121
                    dest="no_network", action="store_true")
122
  result.add_option("--no-presubmit", "--nopresubmit",
123
                    help='Skip presubmit checks',
124
                    default=False, dest="no_presubmit", action="store_true")
125
  result.add_option("--no-stress", "--nostress",
126
                    help="Don't run crankshaft --always-opt --stress-op test",
127
                    default=False, dest="no_stress", action="store_true")
128
  result.add_option("--no-variants", "--novariants",
129
                    help="Don't run any testing variants",
130
                    default=False, dest="no_variants", action="store_true")
131
  result.add_option("--outdir", help="Base directory with compile output",
132
                    default="out")
133
  result.add_option("-p", "--progress",
134
                    help=("The style of progress indicator"
135
                          " (verbose, dots, color, mono)"),
136
                    choices=progress.PROGRESS_INDICATORS.keys(), default="mono")
137
  result.add_option("--report", help="Print a summary of the tests to be run",
138
                    default=False, action="store_true")
139
  result.add_option("--shard-count",
140
                    help="Split testsuites into this number of shards",
141
                    default=1, type="int")
142
  result.add_option("--shard-run",
143
                    help="Run this shard from the split up tests.",
144
                    default=1, type="int")
145
  result.add_option("--shell", help="DEPRECATED! use --shell-dir", default="")
146
  result.add_option("--shell-dir", help="Directory containing executables",
147
                    default="")
148
  result.add_option("--stress-only",
149
                    help="Only run tests with --always-opt --stress-opt",
150
                    default=False, action="store_true")
151
  result.add_option("--time", help="Print timing information after running",
152
                    default=False, action="store_true")
153
  result.add_option("-t", "--timeout", help="Timeout in seconds",
154
                    default= -1, type="int")
155
  result.add_option("-v", "--verbose", help="Verbose output",
156
                    default=False, action="store_true")
157
  result.add_option("--valgrind", help="Run tests through valgrind",
158
                    default=False, action="store_true")
159
  result.add_option("--warn-unused", help="Report unused rules",
160
                    default=False, action="store_true")
161
  result.add_option("--junitout", help="File name of the JUnit output")
162
  result.add_option("--junittestsuite",
163
                    help="The testsuite name in the JUnit output file",
164
                    default="v8tests")
165
  return result
166

    
167

    
168
def ProcessOptions(options):
169
  global VARIANT_FLAGS
170

    
171
  # Architecture and mode related stuff.
172
  if options.arch_and_mode:
173
    tokens = options.arch_and_mode.split(".")
174
    options.arch = tokens[0]
175
    options.mode = tokens[1]
176
  options.mode = options.mode.split(",")
177
  for mode in options.mode:
178
    if not mode.lower() in ["debug", "release"]:
179
      print "Unknown mode %s" % mode
180
      return False
181
  if options.arch in ["auto", "native"]:
182
    options.arch = ARCH_GUESS
183
  options.arch = options.arch.split(",")
184
  for arch in options.arch:
185
    if not arch in SUPPORTED_ARCHS:
186
      print "Unknown architecture %s" % arch
187
      return False
188

    
189
  # Special processing of other options, sorted alphabetically.
190

    
191
  if options.buildbot:
192
    # Buildbots run presubmit tests as a separate step.
193
    options.no_presubmit = True
194
    options.no_network = True
195
  if options.command_prefix:
196
    print("Specifying --command-prefix disables network distribution, "
197
          "running tests locally.")
198
    options.no_network = True
199
  options.command_prefix = shlex.split(options.command_prefix)
200
  options.extra_flags = shlex.split(options.extra_flags)
201
  if options.j == 0:
202
    options.j = multiprocessing.cpu_count()
203

    
204
  def excl(*args):
205
    """Returns true if zero or one of multiple arguments are true."""
206
    return reduce(lambda x, y: x + y, args) <= 1
207

    
208
  if not excl(options.no_stress, options.stress_only, options.no_variants):
209
    print "Use only one of --no-stress, --stress-only or --no-variants."
210
    return False
211
  if options.no_stress:
212
    VARIANT_FLAGS = [[], ["--nocrankshaft"]]
213
  if options.no_variants:
214
    VARIANT_FLAGS = [[]]
215
  if not options.shell_dir:
216
    if options.shell:
217
      print "Warning: --shell is deprecated, use --shell-dir instead."
218
      options.shell_dir = os.path.dirname(options.shell)
219
  if options.stress_only:
220
    VARIANT_FLAGS = [["--stress-opt", "--always-opt"]]
221
  if options.valgrind:
222
    run_valgrind = os.path.join("tools", "run-valgrind.py")
223
    # This is OK for distributed running, so we don't need to set no_network.
224
    options.command_prefix = (["python", "-u", run_valgrind] +
225
                              options.command_prefix)
226
  if not options.flaky_tests in ["run", "skip", "dontcare"]:
227
    print "Unknown flaky test mode %s" % options.flaky_tests
228
    return False
229
  if not options.no_i18n:
230
    DEFAULT_TESTS.append("intl")
231
  return True
232

    
233

    
234
def ShardTests(tests, shard_count, shard_run):
235
  if shard_count < 2:
236
    return tests
237
  if shard_run < 1 or shard_run > shard_count:
238
    print "shard-run not a valid number, should be in [1:shard-count]"
239
    print "defaulting back to running all tests"
240
    return tests
241
  count = 0
242
  shard = []
243
  for test in tests:
244
    if count % shard_count == shard_run - 1:
245
      shard.append(test)
246
    count += 1
247
  return shard
248

    
249

    
250
def Main():
251
  parser = BuildOptions()
252
  (options, args) = parser.parse_args()
253
  if not ProcessOptions(options):
254
    parser.print_help()
255
    return 1
256

    
257
  exit_code = 0
258
  workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), ".."))
259
  if not options.no_presubmit:
260
    print ">>> running presubmit tests"
261
    code = subprocess.call(
262
        [sys.executable, join(workspace, "tools", "presubmit.py")])
263
    exit_code = code
264

    
265
  suite_paths = utils.GetSuitePaths(join(workspace, "test"))
266

    
267
  if len(args) == 0:
268
    suite_paths = [ s for s in suite_paths if s in DEFAULT_TESTS ]
269
  else:
270
    args_suites = set()
271
    for arg in args:
272
      suite = arg.split(os.path.sep)[0]
273
      if not suite in args_suites:
274
        args_suites.add(suite)
275
    suite_paths = [ s for s in suite_paths if s in args_suites ]
276

    
277
  suites = []
278
  for root in suite_paths:
279
    suite = testsuite.TestSuite.LoadTestSuite(
280
        os.path.join(workspace, "test", root))
281
    if suite:
282
      suites.append(suite)
283

    
284
  if options.download_data:
285
    for s in suites:
286
      s.DownloadData()
287

    
288
  for mode in options.mode:
289
    for arch in options.arch:
290
      code = Execute(arch, mode, args, options, suites, workspace)
291
      exit_code = exit_code or code
292
  return exit_code
293

    
294

    
295
def Execute(arch, mode, args, options, suites, workspace):
296
  print(">>> Running tests for %s.%s" % (arch, mode))
297

    
298
  shell_dir = options.shell_dir
299
  if not shell_dir:
300
    if options.buildbot:
301
      shell_dir = os.path.join(workspace, options.outdir, mode)
302
      mode = mode.lower()
303
    else:
304
      shell_dir = os.path.join(workspace, options.outdir,
305
                               "%s.%s" % (arch, mode))
306
  shell_dir = os.path.relpath(shell_dir)
307

    
308
  # Populate context object.
309
  mode_flags = MODE_FLAGS[mode]
310
  timeout = options.timeout
311
  if timeout == -1:
312
    # Simulators are slow, therefore allow a longer default timeout.
313
    if arch in SLOW_ARCHS:
314
      timeout = 2 * TIMEOUT_DEFAULT;
315
    else:
316
      timeout = TIMEOUT_DEFAULT;
317

    
318
  timeout *= TIMEOUT_SCALEFACTOR[mode]
319
  ctx = context.Context(arch, mode, shell_dir,
320
                        mode_flags, options.verbose,
321
                        timeout, options.isolates,
322
                        options.command_prefix,
323
                        options.extra_flags,
324
                        options.no_i18n)
325

    
326
  # Find available test suites and read test cases from them.
327
  variables = {
328
    "mode": mode,
329
    "arch": arch,
330
    "system": utils.GuessOS(),
331
    "isolates": options.isolates,
332
    "deopt_fuzzer": False,
333
    "no_i18n": options.no_i18n,
334
  }
335
  all_tests = []
336
  num_tests = 0
337
  test_id = 0
338
  for s in suites:
339
    s.ReadStatusFile(variables)
340
    s.ReadTestCases(ctx)
341
    if len(args) > 0:
342
      s.FilterTestCasesByArgs(args)
343
    all_tests += s.tests
344
    s.FilterTestCasesByStatus(options.warn_unused, options.flaky_tests)
345
    if options.cat:
346
      verbose.PrintTestSource(s.tests)
347
      continue
348
    s.tests = [ t.CopyAddingFlags(v)
349
                for t in s.tests
350
                for v in s.VariantFlags(t, VARIANT_FLAGS) ]
351
    s.tests = ShardTests(s.tests, options.shard_count, options.shard_run)
352
    num_tests += len(s.tests)
353
    for t in s.tests:
354
      t.id = test_id
355
      test_id += 1
356

    
357
  if options.cat:
358
    return 0  # We're done here.
359

    
360
  if options.report:
361
    verbose.PrintReport(all_tests)
362

    
363
  if num_tests == 0:
364
    print "No tests to run."
365
    return 0
366

    
367
  # Run the tests, either locally or distributed on the network.
368
  try:
369
    start_time = time.time()
370
    progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
371
    if options.junitout:
372
      progress_indicator = progress.JUnitTestProgressIndicator(
373
          progress_indicator, options.junitout, options.junittestsuite)
374

    
375
    run_networked = not options.no_network
376
    if not run_networked:
377
      print("Network distribution disabled, running tests locally.")
378
    elif utils.GuessOS() != "linux":
379
      print("Network distribution is only supported on Linux, sorry!")
380
      run_networked = False
381
    peers = []
382
    if run_networked:
383
      peers = network_execution.GetPeers()
384
      if not peers:
385
        print("No connection to distribution server; running tests locally.")
386
        run_networked = False
387
      elif len(peers) == 1:
388
        print("No other peers on the network; running tests locally.")
389
        run_networked = False
390
      elif num_tests <= 100:
391
        print("Less than 100 tests, running them locally.")
392
        run_networked = False
393

    
394
    if run_networked:
395
      runner = network_execution.NetworkedRunner(suites, progress_indicator,
396
                                                 ctx, peers, workspace)
397
    else:
398
      runner = execution.Runner(suites, progress_indicator, ctx)
399

    
400
    exit_code = runner.Run(options.j)
401
    if runner.terminate:
402
      return exit_code
403
    overall_duration = time.time() - start_time
404
  except KeyboardInterrupt:
405
    return 1
406

    
407
  if options.time:
408
    verbose.PrintTestDurations(suites, overall_duration)
409
  return exit_code
410

    
411

    
412
if __name__ == "__main__":
413
  sys.exit(Main())