1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#!/usr/bin/env python
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Copyright 2012 the V8 project authors. All rights reserved.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Redistribution and use in source and binary forms, with or without
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# modification, are permitted provided that the following conditions are
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# met:
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#     * Redistributions of source code must retain the above copyright
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#       notice, this list of conditions and the following disclaimer.
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#     * Redistributions in binary form must reproduce the above
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#       copyright notice, this list of conditions and the following
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#       disclaimer in the documentation and/or other materials provided
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#       with the distribution.
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#     * Neither the name of Google Inc. nor the names of its
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#       contributors may be used to endorse or promote products derived
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#       from this software without specific prior written permission.
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport json
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport math
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport multiprocessing
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport optparse
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport os
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom os.path import join
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport random
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport shlex
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport subprocess
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport sys
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport time
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom testrunner.local import execution
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom testrunner.local import progress
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom testrunner.local import testsuite
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom testrunner.local import utils
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom testrunner.local import verbose
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom testrunner.objects import context
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochARCH_GUESS = utils.DefaultArch()
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFAULT_TESTS = ["mjsunit", "webkit"]
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTIMEOUT_DEFAULT = 60
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTIMEOUT_SCALEFACTOR = {"debug"   : 4,
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "release" : 1 }
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMODE_FLAGS = {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "debug"   : ["--nohard-abort", "--nodead-code-elimination",
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 "--nofold-constants", "--enable-slow-asserts",
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 "--debug-code", "--verify-heap",
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 "--noconcurrent-recompilation"],
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "release" : ["--nohard-abort", "--nodead-code-elimination",
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 "--nofold-constants", "--noconcurrent-recompilation"]}
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSUPPORTED_ARCHS = ["android_arm",
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "android_ia32",
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "arm",
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "ia32",
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "mipsel",
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "nacl_ia32",
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "nacl_x64",
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "x64"]
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Double the timeout for these:
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSLOW_ARCHS = ["android_arm",
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              "android_ia32",
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              "arm",
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              "mipsel",
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              "nacl_ia32",
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              "nacl_x64"]
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAX_DEOPT = 1000000000
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDISTRIBUTION_MODES = ["smooth", "random"]
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RandomDistribution:
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  def __init__(self, seed=None):
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    seed = seed or random.randint(1, sys.maxint)
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print "Using random distribution with seed %d" % seed
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    self._random = random.Random(seed)
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  def Distribute(self, n, m):
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if n > m:
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      n = m
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return self._random.sample(xrange(1, m + 1), n)
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SmoothDistribution:
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  """Distribute n numbers into the interval [1:m].
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  F1: Factor of the first derivation of the distribution function.
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  F2: Factor of the second derivation of the distribution function.
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  With F1 and F2 set to 0, the distribution will be equal.
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  """
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  def __init__(self, factor1=2.0, factor2=0.2):
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    self._factor1 = factor1
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    self._factor2 = factor2
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  def Distribute(self, n, m):
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if n > m:
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      n = m
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if n <= 1:
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return [ 1 ]
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = []
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x = 0.0
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    dx = 1.0
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ddx = self._factor1
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    dddx = self._factor2
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for i in range(0, n):
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result += [ x ]
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      x += dx
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      dx += ddx
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ddx += dddx
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    # Project the distribution into the interval [0:M].
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = [ x * m / result[-1] for x in result ]
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    # Equalize by n. The closer n is to m, the more equal will be the
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    # distribution.
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (i, x) in enumerate(result):
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      # The value of x if it was equally distributed.
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      equal_x = i / float(n - 1) * float(m - 1) + 1
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      # Difference factor between actual and equal distribution.
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      diff = 1 - (x / equal_x)
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      # Equalize x dependent on the number of values to distribute.
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result[i] = int(x + (i + 1) * diff)
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef Distribution(options):
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.distribution_mode == "random":
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return RandomDistribution(options.seed)
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.distribution_mode == "smooth":
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SmoothDistribution(options.distribution_factor1,
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              options.distribution_factor2)
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef BuildOptions():
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result = optparse.OptionParser()
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--arch",
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help=("The architecture to run tests for, "
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          "'auto' or 'native' for auto-detect"),
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="ia32,x64,arm")
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--arch-and-mode",
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Architecture and mode in the format 'arch.mode'",
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=None)
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--asan",
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Regard test expectations for ASAN",
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=False, action="store_true")
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--buildbot",
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Adapt to path structure used on buildbots",
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=False, action="store_true")
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--command-prefix",
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Prepended to each shell command used to run a test",
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="")
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--coverage", help=("Exponential test coverage "
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "(range 0.0, 1.0) -- 0.0: one test, 1.0 all tests (slow)"),
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=0.4, type="float")
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--coverage-lift", help=("Lifts test coverage for tests "
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "with a small number of deopt points (range 0, inf)"),
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=20, type="int")
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--download-data", help="Download missing test suite data",
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=False, action="store_true")
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--distribution-factor1", help=("Factor of the first "
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "derivation of the distribution function"), default=2.0,
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    type="float")
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--distribution-factor2", help=("Factor of the second "
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "derivation of the distribution function"), default=0.7,
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    type="float")
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--distribution-mode", help=("How to select deopt points "
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "for a given test (smooth|random)"),
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="smooth")
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--dump-results-file", help=("Dump maximum number of "
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "deopt points per test to a file"))
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--extra-flags",
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Additional flags to pass to each test command",
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="")
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--isolates", help="Whether to test isolates",
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=False, action="store_true")
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("-j", help="The number of parallel tasks to run",
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=0, type="int")
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("-m", "--mode",
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="The test modes in which to run (comma-separated)",
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="release,debug")
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--outdir", help="Base directory with compile output",
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="out")
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("-p", "--progress",
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help=("The style of progress indicator"
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          " (verbose, dots, color, mono)"),
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    choices=progress.PROGRESS_INDICATORS.keys(),
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="mono")
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--shard-count",
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Split testsuites into this number of shards",
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=1, type="int")
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--shard-run",
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Run this shard from the split up tests.",
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=1, type="int")
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--shell-dir", help="Directory containing executables",
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default="")
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--seed", help="The seed for the random distribution",
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    type="int")
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("-t", "--timeout", help="Timeout in seconds",
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default= -1, type="int")
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("-v", "--verbose", help="Verbose output",
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    default=False, action="store_true")
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result.add_option("--random-seed", default=0, dest="random_seed",
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    help="Default seed for initializing random generator")
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef ProcessOptions(options):
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  global VARIANT_FLAGS
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  # Architecture and mode related stuff.
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.arch_and_mode:
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    tokens = options.arch_and_mode.split(".")
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.arch = tokens[0]
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.mode = tokens[1]
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  options.mode = options.mode.split(",")
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for mode in options.mode:
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if not mode.lower() in ["debug", "release"]:
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      print "Unknown mode %s" % mode
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return False
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.arch in ["auto", "native"]:
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.arch = ARCH_GUESS
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  options.arch = options.arch.split(",")
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for arch in options.arch:
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if not arch in SUPPORTED_ARCHS:
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      print "Unknown architecture %s" % arch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return False
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  # Special processing of other options, sorted alphabetically.
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  options.command_prefix = shlex.split(options.command_prefix)
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  options.extra_flags = shlex.split(options.extra_flags)
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.j == 0:
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.j = multiprocessing.cpu_count()
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while options.random_seed == 0:
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.random_seed = random.SystemRandom().randint(-2147483648, 2147483647)
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if not options.distribution_mode in DISTRIBUTION_MODES:
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print "Unknown distribution mode %s" % options.distribution_mode
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return False
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.distribution_factor1 < 0.0:
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print ("Distribution factor1 %s is out of range. Defaulting to 0.0"
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        % options.distribution_factor1)
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.distribution_factor1 = 0.0
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.distribution_factor2 < 0.0:
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print ("Distribution factor2 %s is out of range. Defaulting to 0.0"
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        % options.distribution_factor2)
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.distribution_factor2 = 0.0
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.coverage < 0.0 or options.coverage > 1.0:
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print ("Coverage %s is out of range. Defaulting to 0.4"
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        % options.coverage)
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.coverage = 0.4
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.coverage_lift < 0:
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print ("Coverage lift %s is out of range. Defaulting to 0"
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        % options.coverage_lift)
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options.coverage_lift = 0
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return True
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef ShardTests(tests, shard_count, shard_run):
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if shard_count < 2:
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return tests
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if shard_run < 1 or shard_run > shard_count:
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print "shard-run not a valid number, should be in [1:shard-count]"
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print "defaulting back to running all tests"
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return tests
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  count = 0
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shard = []
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for test in tests:
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if count % shard_count == shard_run - 1:
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shard.append(test)
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    count += 1
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return shard
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef Main():
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  parser = BuildOptions()
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  (options, args) = parser.parse_args()
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if not ProcessOptions(options):
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    parser.print_help()
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  exit_code = 0
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), ".."))
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  suite_paths = utils.GetSuitePaths(join(workspace, "test"))
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if len(args) == 0:
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    suite_paths = [ s for s in suite_paths if s in DEFAULT_TESTS ]
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  else:
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    args_suites = set()
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for arg in args:
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      suite = arg.split(os.path.sep)[0]
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if not suite in args_suites:
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        args_suites.add(suite)
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    suite_paths = [ s for s in suite_paths if s in args_suites ]
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  suites = []
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for root in suite_paths:
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    suite = testsuite.TestSuite.LoadTestSuite(
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        os.path.join(workspace, "test", root))
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if suite:
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      suites.append(suite)
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if options.download_data:
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for s in suites:
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      s.DownloadData()
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for mode in options.mode:
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for arch in options.arch:
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      try:
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        code = Execute(arch, mode, args, options, suites, workspace)
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        exit_code = exit_code or code
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      except KeyboardInterrupt:
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return 2
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return exit_code
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef CalculateNTests(m, options):
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  """Calculates the number of tests from m deopt points with exponential
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  coverage.
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  The coverage is expected to be between 0.0 and 1.0.
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  The 'coverage lift' lifts the coverage for tests with smaller m values.
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  """
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  c = float(options.coverage)
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  l = float(options.coverage_lift)
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return int(math.pow(m, (m * c + l) / (m + l)))
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef Execute(arch, mode, args, options, suites, workspace):
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  print(">>> Running tests for %s.%s" % (arch, mode))
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  dist = Distribution(options)
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shell_dir = options.shell_dir
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if not shell_dir:
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if options.buildbot:
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shell_dir = os.path.join(workspace, options.outdir, mode)
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      mode = mode.lower()
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    else:
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shell_dir = os.path.join(workspace, options.outdir,
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               "%s.%s" % (arch, mode))
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shell_dir = os.path.relpath(shell_dir)
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  # Populate context object.
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mode_flags = MODE_FLAGS[mode]
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  timeout = options.timeout
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if timeout == -1:
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    # Simulators are slow, therefore allow a longer default timeout.
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if arch in SLOW_ARCHS:
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      timeout = 2 * TIMEOUT_DEFAULT;
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    else:
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      timeout = TIMEOUT_DEFAULT;
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  timeout *= TIMEOUT_SCALEFACTOR[mode]
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ctx = context.Context(arch, mode, shell_dir,
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        mode_flags, options.verbose,
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        timeout, options.isolates,
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        options.command_prefix,
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        options.extra_flags,
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        False,  # Keep i18n on by default.
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        options.random_seed,
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        True,  # No sorting of test cases.
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        0,  # Don't rerun failing tests.
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        0,  # No use of a rerun-failing-tests maximum.
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        False)  # No predictable mode.
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  # Find available test suites and read test cases from them.
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  variables = {
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "arch": arch,
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "asan": options.asan,
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "deopt_fuzzer": True,
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "gc_stress": False,
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "isolates": options.isolates,
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "mode": mode,
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "no_i18n": False,
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "no_snap": False,
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "simulator": utils.UseSimulator(arch),
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "system": utils.GuessOS(),
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "tsan": False,
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  all_tests = []
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  num_tests = 0
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_id = 0
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  # Remember test case prototypes for the fuzzing phase.
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_backup = dict((s, []) for s in suites)
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for s in suites:
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s.ReadStatusFile(variables)
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s.ReadTestCases(ctx)
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if len(args) > 0:
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      s.FilterTestCasesByArgs(args)
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    all_tests += s.tests
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s.FilterTestCasesByStatus(False)
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    test_backup[s] = s.tests
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    analysis_flags = ["--deopt-every-n-times", "%d" % MAX_DEOPT,
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      "--print-deopt-stress"]
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s.tests = [ t.CopyAddingFlags(analysis_flags) for t in s.tests ]
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    num_tests += len(s.tests)
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for t in s.tests:
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      t.id = test_id
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      test_id += 1
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if num_tests == 0:
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print "No tests to run."
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  print(">>> Collection phase")
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  runner = execution.Runner(suites, progress_indicator, ctx)
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  exit_code = runner.Run(options.j)
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  print(">>> Analysis phase")
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  num_tests = 0
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_id = 0
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for s in suites:
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    test_results = {}
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for t in s.tests:
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for line in t.output.stdout.splitlines():
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if line.startswith("=== Stress deopt counter: "):
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          test_results[t.path] = MAX_DEOPT - int(line.split(" ")[-1])
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for t in s.tests:
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if t.path not in test_results:
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        print "Missing results for %s" % t.path
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if options.dump_results_file:
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      results_dict = dict((t.path, n) for (t, n) in test_results.iteritems())
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      with file("%s.%d.txt" % (dump_results_file, time.time()), "w") as f:
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        f.write(json.dumps(results_dict))
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    # Reset tests and redistribute the prototypes from the collection phase.
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s.tests = []
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if options.verbose:
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      print "Test distributions:"
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for t in test_backup[s]:
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_deopt = test_results.get(t.path, 0)
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if max_deopt == 0:
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      n_deopt = CalculateNTests(max_deopt, options)
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      distribution = dist.Distribute(n_deopt, max_deopt)
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if options.verbose:
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        print "%s %s" % (t.path, distribution)
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for i in distribution:
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        fuzzing_flags = ["--deopt-every-n-times", "%d" % i]
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        s.tests.append(t.CopyAddingFlags(fuzzing_flags))
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    num_tests += len(s.tests)
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for t in s.tests:
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      t.id = test_id
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      test_id += 1
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if num_tests == 0:
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    print "No tests to run."
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  print(">>> Deopt fuzzing phase (%d test cases)" % num_tests)
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  runner = execution.Runner(suites, progress_indicator, ctx)
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code = runner.Run(options.j)
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return exit_code or code
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochif __name__ == "__main__":
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  sys.exit(Main())
477