OLD | NEW |
1 # Copyright 2012 the V8 project authors. All rights reserved. | 1 # Copyright 2012 the V8 project authors. All rights reserved. |
2 # Redistribution and use in source and binary forms, with or without | 2 # Redistribution and use in source and binary forms, with or without |
3 # modification, are permitted provided that the following conditions are | 3 # modification, are permitted provided that the following conditions are |
4 # met: | 4 # met: |
5 # | 5 # |
6 # * Redistributions of source code must retain the above copyright | 6 # * Redistributions of source code must retain the above copyright |
7 # notice, this list of conditions and the following disclaimer. | 7 # notice, this list of conditions and the following disclaimer. |
8 # * Redistributions in binary form must reproduce the above | 8 # * Redistributions in binary form must reproduce the above |
9 # copyright notice, this list of conditions and the following | 9 # copyright notice, this list of conditions and the following |
10 # disclaimer in the documentation and/or other materials provided | 10 # disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 | 28 |
29 import os | 29 import os |
30 import time | 30 import time |
31 | 31 |
32 from pool import Pool | 32 from pool import Pool |
33 from . import commands | 33 from . import commands |
| 34 from . import perfdata |
34 from . import utils | 35 from . import utils |
35 | 36 |
36 | 37 |
37 class Job(object): | 38 class Job(object): |
38 def __init__(self, command, dep_command, test_id, timeout, verbose): | 39 def __init__(self, command, dep_command, test_id, timeout, verbose): |
39 self.command = command | 40 self.command = command |
40 self.dep_command = dep_command | 41 self.dep_command = dep_command |
41 self.id = test_id | 42 self.id = test_id |
42 self.timeout = timeout | 43 self.timeout = timeout |
43 self.verbose = verbose | 44 self.verbose = verbose |
44 | 45 |
45 | 46 |
46 def RunTest(job): | 47 def RunTest(job): |
47 start_time = time.time() | 48 start_time = time.time() |
48 if job.dep_command is not None: | 49 if job.dep_command is not None: |
49 dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout) | 50 dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout) |
50 # TODO(jkummerow): We approximate the test suite specific function | 51 # TODO(jkummerow): We approximate the test suite specific function |
51 # IsFailureOutput() by just checking the exit code here. Currently | 52 # IsFailureOutput() by just checking the exit code here. Currently |
52 # only cctests define dependencies, for which this simplification is | 53 # only cctests define dependencies, for which this simplification is |
53 # correct. | 54 # correct. |
54 if dep_output.exit_code != 0: | 55 if dep_output.exit_code != 0: |
55 return (job.id, dep_output, time.time() - start_time) | 56 return (job.id, dep_output, time.time() - start_time) |
56 output = commands.Execute(job.command, job.verbose, job.timeout) | 57 output = commands.Execute(job.command, job.verbose, job.timeout) |
57 return (job.id, output, time.time() - start_time) | 58 return (job.id, output, time.time() - start_time) |
58 | 59 |
59 class Runner(object): | 60 class Runner(object): |
60 | 61 |
61 def __init__(self, suites, progress_indicator, context): | 62 def __init__(self, suites, progress_indicator, context): |
| 63 datapath = os.path.join("out", "testrunner_data") |
| 64 self.perf_data_manager = perfdata.PerfDataManager(datapath) |
| 65 self.perfdata = self.perf_data_manager.GetStore(context.arch, context.mode) |
62 self.tests = [ t for s in suites for t in s.tests ] | 66 self.tests = [ t for s in suites for t in s.tests ] |
| 67 for t in self.tests: |
| 68 t.duration = self.perfdata.FetchPerfData(t) or 1.0 |
63 self._CommonInit(len(self.tests), progress_indicator, context) | 69 self._CommonInit(len(self.tests), progress_indicator, context) |
64 | 70 |
65 def _CommonInit(self, num_tests, progress_indicator, context): | 71 def _CommonInit(self, num_tests, progress_indicator, context): |
66 self.indicator = progress_indicator | 72 self.indicator = progress_indicator |
67 progress_indicator.runner = self | 73 progress_indicator.runner = self |
68 self.context = context | 74 self.context = context |
69 self.succeeded = 0 | 75 self.succeeded = 0 |
70 self.total = num_tests | 76 self.total = num_tests |
71 self.remaining = num_tests | 77 self.remaining = num_tests |
72 self.failed = [] | 78 self.failed = [] |
73 self.crashed = 0 | 79 self.crashed = 0 |
74 | 80 |
75 def Run(self, jobs): | 81 def Run(self, jobs): |
76 self.indicator.Starting() | 82 self.indicator.Starting() |
77 self._RunInternal(jobs) | 83 self._RunInternal(jobs) |
78 self.indicator.Done() | 84 self.indicator.Done() |
79 if self.failed or self.remaining: | 85 if self.failed or self.remaining: |
80 return 1 | 86 return 1 |
81 return 0 | 87 return 0 |
82 | 88 |
83 def _RunInternal(self, jobs): | 89 def _RunInternal(self, jobs): |
84 pool = Pool(jobs) | 90 pool = Pool(jobs) |
85 test_map = {} | 91 test_map = {} |
86 # TODO(machenbach): Instead of filling the queue completely before | 92 # TODO(machenbach): Instead of filling the queue completely before |
87 # pool.imap_unordered, make this a generator that already starts testing | 93 # pool.imap_unordered, make this a generator that already starts testing |
88 # while the queue is filled. | 94 # while the queue is filled. |
89 queue = [] | 95 queue = [] |
90 queued_exception = None | 96 queued_exception = None |
91 for test in self.tests: | 97 for test in sorted(self.tests, key=lambda t: t.duration, reverse=True): |
92 assert test.id >= 0 | 98 assert test.id >= 0 |
93 test_map[test.id] = test | 99 test_map[test.id] = test |
94 try: | 100 try: |
95 command = self.GetCommand(test) | 101 command = self.GetCommand(test) |
96 except Exception, e: | 102 except Exception, e: |
97 # If this failed, save the exception and re-raise it later (after | 103 # If this failed, save the exception and re-raise it later (after |
98 # all other tests have had a chance to run). | 104 # all other tests have had a chance to run). |
99 queued_exception = e | 105 queued_exception = e |
100 continue | 106 continue |
101 timeout = self.context.timeout | 107 timeout = self.context.timeout |
(...skipping 15 matching lines...) Expand all Loading... |
117 test.output = result[1] | 123 test.output = result[1] |
118 test.duration = result[2] | 124 test.duration = result[2] |
119 has_unexpected_output = test.suite.HasUnexpectedOutput(test) | 125 has_unexpected_output = test.suite.HasUnexpectedOutput(test) |
120 if has_unexpected_output: | 126 if has_unexpected_output: |
121 self.failed.append(test) | 127 self.failed.append(test) |
122 if test.output.HasCrashed(): | 128 if test.output.HasCrashed(): |
123 self.crashed += 1 | 129 self.crashed += 1 |
124 else: | 130 else: |
125 self.succeeded += 1 | 131 self.succeeded += 1 |
126 self.remaining -= 1 | 132 self.remaining -= 1 |
| 133 try: |
| 134 self.perfdata.UpdatePerfData(test) |
| 135 except Exception, e: |
| 136 print("UpdatePerfData exception: %s" % e) |
| 137 pass # Just keep working. |
127 self.indicator.HasRun(test, has_unexpected_output) | 138 self.indicator.HasRun(test, has_unexpected_output) |
128 finally: | 139 finally: |
129 pool.terminate() | 140 pool.terminate() |
130 if queued_exception: | 141 if queued_exception: |
131 raise queued_exception | 142 raise queued_exception |
132 | 143 |
133 | 144 |
134 def GetCommand(self, test): | 145 def GetCommand(self, test): |
135 d8testflag = [] | 146 d8testflag = [] |
136 shell = test.suite.shell() | 147 shell = test.suite.shell() |
137 if shell == "d8": | 148 if shell == "d8": |
138 d8testflag = ["--test"] | 149 d8testflag = ["--test"] |
139 if utils.IsWindows(): | 150 if utils.IsWindows(): |
140 shell += ".exe" | 151 shell += ".exe" |
141 cmd = (self.context.command_prefix + | 152 cmd = (self.context.command_prefix + |
142 [os.path.abspath(os.path.join(self.context.shell_dir, shell))] + | 153 [os.path.abspath(os.path.join(self.context.shell_dir, shell))] + |
143 d8testflag + | 154 d8testflag + |
144 ["--random-seed=%s" % self.context.random_seed] + | 155 ["--random-seed=%s" % self.context.random_seed] + |
145 test.suite.GetFlagsForTestCase(test, self.context) + | 156 test.suite.GetFlagsForTestCase(test, self.context) + |
146 self.context.extra_flags) | 157 self.context.extra_flags) |
147 return cmd | 158 return cmd |
148 | 159 |
149 | 160 |
150 class BreakNowException(Exception): | 161 class BreakNowException(Exception): |
151 def __init__(self, value): | 162 def __init__(self, value): |
152 self.value = value | 163 self.value = value |
153 def __str__(self): | 164 def __str__(self): |
154 return repr(self.value) | 165 return repr(self.value) |
OLD | NEW |