My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
Checkout   Browse   Changes  
Changes to /trunk/tools/testrunner/local/execution.py
r0 vs. r12643 Compare: vs.  Format:
Revision r12643
Go to: 
Project members, sign in to write a code review
/trunk/tools/testrunner/local/execution.py /trunk/tools/testrunner/local/execution.py   r12643
Properties
 svn:eol-style
   1 LF
  
Contents
  1 # Copyright 2012 the V8 project authors. All rights reserved.
  2 # Redistribution and use in source and binary forms, with or without
  3 # modification, are permitted provided that the following conditions are
  4 # met:
  5 #
  6 # * Redistributions of source code must retain the above copyright
  7 # notice, this list of conditions and the following disclaimer.
  8 # * Redistributions in binary form must reproduce the above
  9 # copyright notice, this list of conditions and the following
  10 # disclaimer in the documentation and/or other materials provided
  11 # with the distribution.
  12 # * Neither the name of Google Inc. nor the names of its
  13 # contributors may be used to endorse or promote products derived
  14 # from this software without specific prior written permission.
  15 #
  16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27
  28
  29 import multiprocessing
  30 import os
  31 import threading
  32 import time
  33
  34 from . import commands
  35 from . import utils
  36
  37
  38 class Job(object):
  39 def __init__(self, command, dep_command, test_id, timeout, verbose):
  40 self.command = command
  41 self.dep_command = dep_command
  42 self.id = test_id
  43 self.timeout = timeout
  44 self.verbose = verbose
  45
  46
  47 def RunTest(job):
  48 try:
  49 start_time = time.time()
  50 if job.dep_command is not None:
  51 dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout)
  52 # TODO(jkummerow): We approximate the test suite specific function
  53 # IsFailureOutput() by just checking the exit code here. Currently
  54 # only cctests define dependencies, for which this simplification is
  55 # correct.
  56 if dep_output.exit_code != 0:
  57 return (job.id, dep_output, time.time() - start_time)
  58 output = commands.Execute(job.command, job.verbose, job.timeout)
  59 return (job.id, output, time.time() - start_time)
  60 except Exception, e:
  61 print(">>> EXCEPTION: %s" % e)
  62 return (-1, -1, 0)
  63
  64
  65 class Runner(object):
  66
  67 def __init__(self, suites, progress_indicator, context):
  68 self.tests = [ t for s in suites for t in s.tests ]
  69 self._CommonInit(len(self.tests), progress_indicator, context)
  70
  71 def _CommonInit(self, num_tests, progress_indicator, context):
  72 self.indicator = progress_indicator
  73 progress_indicator.runner = self
  74 self.context = context
  75 self.succeeded = 0
  76 self.total = num_tests
  77 self.remaining = num_tests
  78 self.failed = []
  79 self.crashed = 0
  80 self.terminate = False
  81 self.lock = threading.Lock()
  82
  83 def Run(self, jobs):
  84 self.indicator.Starting()
  85 self._RunInternal(jobs)
  86 self.indicator.Done()
  87 return not self.failed
  88
  89 def _RunInternal(self, jobs):
  90 pool = multiprocessing.Pool(processes=jobs)
  91 test_map = {}
  92 queue = []
  93 for test in self.tests:
  94 assert test.id >= 0
  95 test_map[test.id] = test
  96 command = self.GetCommand(test)
  97 timeout = self.context.timeout
  98 if ("--stress-opt" in test.flags or
  99 "--stress-opt" in self.context.mode_flags or
  100 "--stress-opt" in self.context.extra_flags):
  101 timeout *= 4
  102 if test.dependency is not None:
  103 dep_command = [ c.replace(test.path, test.dependency) for c in command ]
  104 else:
  105 dep_command = None
  106 job = Job(command, dep_command, test.id, timeout, self.context.verbose)
  107 queue.append(job)
  108 try:
  109 kChunkSize = 1
  110 it = pool.imap_unordered(RunTest, queue, kChunkSize)
  111 for result in it:
  112 test_id = result[0]
  113 if test_id < 0:
  114 raise BreakNowException("User pressed Ctrl+C or IO went wrong")
  115 test = test_map[test_id]
  116 self.indicator.AboutToRun(test)
  117 test.output = result[1]
  118 test.duration = result[2]
  119 if test.suite.HasUnexpectedOutput(test):
  120 self.failed.append(test)
  121 if test.output.HasCrashed():
  122 self.crashed += 1
  123 else:
  124 self.succeeded += 1
  125 self.remaining -= 1
  126 self.indicator.HasRun(test)
  127 except:
  128 pool.terminate()
  129 pool.join()
  130 raise
  131 return
  132
  133
  134 def GetCommand(self, test):
  135 d8testflag = []
  136 shell = test.suite.shell()
  137 if shell == "d8":
  138 d8testflag = ["--test"]
  139 if utils.IsWindows():
  140 shell += ".exe"
  141 cmd = ([self.context.command_prefix] +
  142 [os.path.join(self.context.shell_dir, shell)] +
  143 d8testflag +
  144 test.suite.GetFlagsForTestCase(test, self.context) +
  145 [self.context.extra_flags])
  146 cmd = [ c for c in cmd if c != "" ]
  147 return cmd
  148
  149
  150 class BreakNowException(Exception):
  151 def __init__(self, value):
  152 self.value = value
  153 def __str__(self):
  154 return repr(self.value)
Powered by Google Project Hosting