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 17 matching lines...) Expand all Loading... |
28 | 28 |
29 import multiprocessing | 29 import multiprocessing |
30 import os | 30 import os |
31 import threading | 31 import threading |
32 import time | 32 import time |
33 | 33 |
34 from . import commands | 34 from . import commands |
35 from . import utils | 35 from . import utils |
36 | 36 |
37 | 37 |
| 38 BREAK_NOW = -1 |
| 39 EXCEPTION = -2 |
| 40 |
| 41 |
38 class Job(object): | 42 class Job(object): |
39 def __init__(self, command, dep_command, test_id, timeout, verbose): | 43 def __init__(self, command, dep_command, test_id, timeout, verbose): |
40 self.command = command | 44 self.command = command |
41 self.dep_command = dep_command | 45 self.dep_command = dep_command |
42 self.id = test_id | 46 self.id = test_id |
43 self.timeout = timeout | 47 self.timeout = timeout |
44 self.verbose = verbose | 48 self.verbose = verbose |
45 | 49 |
46 | 50 |
47 def RunTest(job): | 51 def RunTest(job): |
48 try: | 52 try: |
49 start_time = time.time() | 53 start_time = time.time() |
50 if job.dep_command is not None: | 54 if job.dep_command is not None: |
51 dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout) | 55 dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout) |
52 # TODO(jkummerow): We approximate the test suite specific function | 56 # TODO(jkummerow): We approximate the test suite specific function |
53 # IsFailureOutput() by just checking the exit code here. Currently | 57 # IsFailureOutput() by just checking the exit code here. Currently |
54 # only cctests define dependencies, for which this simplification is | 58 # only cctests define dependencies, for which this simplification is |
55 # correct. | 59 # correct. |
56 if dep_output.exit_code != 0: | 60 if dep_output.exit_code != 0: |
57 return (job.id, dep_output, time.time() - start_time) | 61 return (job.id, dep_output, time.time() - start_time) |
58 output = commands.Execute(job.command, job.verbose, job.timeout) | 62 output = commands.Execute(job.command, job.verbose, job.timeout) |
59 return (job.id, output, time.time() - start_time) | 63 return (job.id, output, time.time() - start_time) |
| 64 except KeyboardInterrupt: |
| 65 return (-1, BREAK_NOW, 0) |
60 except Exception, e: | 66 except Exception, e: |
61 print(">>> EXCEPTION: %s" % e) | 67 print(">>> EXCEPTION: %s" % e) |
62 return (-1, -1, 0) | 68 return (-1, EXCEPTION, 0) |
63 | 69 |
64 | 70 |
65 class Runner(object): | 71 class Runner(object): |
66 | 72 |
67 def __init__(self, suites, progress_indicator, context): | 73 def __init__(self, suites, progress_indicator, context): |
68 self.tests = [ t for s in suites for t in s.tests ] | 74 self.tests = [ t for s in suites for t in s.tests ] |
69 self._CommonInit(len(self.tests), progress_indicator, context) | 75 self._CommonInit(len(self.tests), progress_indicator, context) |
70 | 76 |
71 def _CommonInit(self, num_tests, progress_indicator, context): | 77 def _CommonInit(self, num_tests, progress_indicator, context): |
72 self.indicator = progress_indicator | 78 self.indicator = progress_indicator |
(...skipping 10 matching lines...) Expand all Loading... |
83 def Run(self, jobs): | 89 def Run(self, jobs): |
84 self.indicator.Starting() | 90 self.indicator.Starting() |
85 self._RunInternal(jobs) | 91 self._RunInternal(jobs) |
86 self.indicator.Done() | 92 self.indicator.Done() |
87 return not self.failed | 93 return not self.failed |
88 | 94 |
89 def _RunInternal(self, jobs): | 95 def _RunInternal(self, jobs): |
90 pool = multiprocessing.Pool(processes=jobs) | 96 pool = multiprocessing.Pool(processes=jobs) |
91 test_map = {} | 97 test_map = {} |
92 queue = [] | 98 queue = [] |
| 99 queued_exception = None |
93 for test in self.tests: | 100 for test in self.tests: |
94 assert test.id >= 0 | 101 assert test.id >= 0 |
95 test_map[test.id] = test | 102 test_map[test.id] = test |
96 command = self.GetCommand(test) | 103 try: |
| 104 command = self.GetCommand(test) |
| 105 except Exception, e: |
| 106 # If this failed, save the exception and re-raise it later (after |
| 107 # all other tests have had a chance to run). |
| 108 queued_exception = e |
| 109 continue |
97 timeout = self.context.timeout | 110 timeout = self.context.timeout |
98 if ("--stress-opt" in test.flags or | 111 if ("--stress-opt" in test.flags or |
99 "--stress-opt" in self.context.mode_flags or | 112 "--stress-opt" in self.context.mode_flags or |
100 "--stress-opt" in self.context.extra_flags): | 113 "--stress-opt" in self.context.extra_flags): |
101 timeout *= 4 | 114 timeout *= 4 |
102 if test.dependency is not None: | 115 if test.dependency is not None: |
103 dep_command = [ c.replace(test.path, test.dependency) for c in command ] | 116 dep_command = [ c.replace(test.path, test.dependency) for c in command ] |
104 else: | 117 else: |
105 dep_command = None | 118 dep_command = None |
106 job = Job(command, dep_command, test.id, timeout, self.context.verbose) | 119 job = Job(command, dep_command, test.id, timeout, self.context.verbose) |
107 queue.append(job) | 120 queue.append(job) |
108 try: | 121 try: |
109 kChunkSize = 1 | 122 kChunkSize = 1 |
110 it = pool.imap_unordered(RunTest, queue, kChunkSize) | 123 it = pool.imap_unordered(RunTest, queue, kChunkSize) |
111 for result in it: | 124 for result in it: |
112 test_id = result[0] | 125 test_id = result[0] |
113 if test_id < 0: | 126 if test_id < 0: |
| 127 if result[1] == BREAK_NOW: |
| 128 self.terminate = True |
| 129 else: |
| 130 continue |
| 131 if self.terminate: |
| 132 pool.terminate() |
| 133 pool.join() |
114 raise BreakNowException("User pressed Ctrl+C or IO went wrong") | 134 raise BreakNowException("User pressed Ctrl+C or IO went wrong") |
115 test = test_map[test_id] | 135 test = test_map[test_id] |
116 self.indicator.AboutToRun(test) | 136 self.indicator.AboutToRun(test) |
117 test.output = result[1] | 137 test.output = result[1] |
118 test.duration = result[2] | 138 test.duration = result[2] |
119 if test.suite.HasUnexpectedOutput(test): | 139 if test.suite.HasUnexpectedOutput(test): |
120 self.failed.append(test) | 140 self.failed.append(test) |
121 if test.output.HasCrashed(): | 141 if test.output.HasCrashed(): |
122 self.crashed += 1 | 142 self.crashed += 1 |
123 else: | 143 else: |
124 self.succeeded += 1 | 144 self.succeeded += 1 |
125 self.remaining -= 1 | 145 self.remaining -= 1 |
126 self.indicator.HasRun(test) | 146 self.indicator.HasRun(test) |
127 except: | 147 except KeyboardInterrupt: |
| 148 pool.terminate() |
| 149 pool.join() |
| 150 except Exception, e: |
| 151 print("Exception: %s" % e) |
128 pool.terminate() | 152 pool.terminate() |
129 pool.join() | 153 pool.join() |
130 raise | 154 raise |
| 155 if queued_exception: |
| 156 raise queued_exception |
131 return | 157 return |
132 | 158 |
133 | 159 |
134 def GetCommand(self, test): | 160 def GetCommand(self, test): |
135 d8testflag = [] | 161 d8testflag = [] |
136 shell = test.suite.shell() | 162 shell = test.suite.shell() |
137 if shell == "d8": | 163 if shell == "d8": |
138 d8testflag = ["--test"] | 164 d8testflag = ["--test"] |
139 if utils.IsWindows(): | 165 if utils.IsWindows(): |
140 shell += ".exe" | 166 shell += ".exe" |
141 cmd = ([self.context.command_prefix] + | 167 cmd = ([self.context.command_prefix] + |
142 [os.path.join(self.context.shell_dir, shell)] + | 168 [os.path.join(self.context.shell_dir, shell)] + |
143 d8testflag + | 169 d8testflag + |
144 test.suite.GetFlagsForTestCase(test, self.context) + | 170 test.suite.GetFlagsForTestCase(test, self.context) + |
145 [self.context.extra_flags]) | 171 [self.context.extra_flags]) |
146 cmd = [ c for c in cmd if c != "" ] | 172 cmd = [ c for c in cmd if c != "" ] |
147 return cmd | 173 return cmd |
148 | 174 |
149 | 175 |
150 class BreakNowException(Exception): | 176 class BreakNowException(Exception): |
151 def __init__(self, value): | 177 def __init__(self, value): |
152 self.value = value | 178 self.value = value |
153 def __str__(self): | 179 def __str__(self): |
154 return repr(self.value) | 180 return repr(self.value) |
OLD | NEW |