Changeset 125812 in webkit
- Timestamp:
- Aug 16, 2012 2:45:12 PM (12 years ago)
- Location:
- trunk/Tools
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r125801 r125812 1 2012-08-16 Dirk Pranke <dpranke@chromium.org> 2 3 NRWT cutting off the output from LayoutTest run under Valgrind 4 https://bugs.webkit.org/show_bug.cgi?id=94011 5 6 Reviewed by Ojan Vafai. 7 8 Make NRWT work with valgrind again ... I needed to rework the 9 driver infrastructure so that we could get the stderr written 10 between a test completing and a process being stopped and 11 associate it with the DriverOutput for the test; this meant that 12 run_test() needed to stop the driver at the end of the test 13 directly if/when appropriate. This also entailed reworking 14 run_test() so that we would gather stderr and stdout 15 consistently regardless of whether this was a normal test, or 16 stop_when_done, or a crash or timeout. 17 18 Also, I had to rework the process_stop_time() (and renamed it to 19 driver_stop_timeout) so that it would be longer if --time-out-ms 20 was long as well (so that valgrind would get enough time to 21 run), and I reworked driver.stop(kill_directly=True) to just 22 driver.stop(timeout=0.0). 23 24 Lastly, adding the new stop_when_done parameter entailed 25 touching a lot of test mock functions :(. 26 27 This change appeared to be well-covered by existing tests. 28 29 * Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py: 30 (Worker._run_test): 31 (Worker._run_test_with_timeout): 32 (Worker._run_test_in_another_thread): 33 (Worker._run_test_in_another_thread.SingleTestThread.run): 34 (Worker._run_test_in_this_thread): 35 (Worker._run_single_test): 36 * Scripts/webkitpy/layout_tests/controllers/single_test_runner.py: 37 (run_single_test): 38 (SingleTestRunner.__init__): 39 (SingleTestRunner._run_compare_test): 40 (SingleTestRunner._run_rebaseline): 41 (SingleTestRunner._run_reftest): 42 * Scripts/webkitpy/layout_tests/port/base.py: 43 (Port.driver_stop_timeout): 44 (Port.variable.default_configuration): 45 * Scripts/webkitpy/layout_tests/port/chromium_android.py: 46 (ChromiumAndroidPort.driver_stop_timeout): 47 (ChromiumAndroidDriver.stop): 48 * Scripts/webkitpy/layout_tests/port/driver.py: 49 (Driver.run_test): 50 (Driver.stop): 51 (DriverProxy.run_test): 52 * Scripts/webkitpy/layout_tests/port/driver_unittest.py: 53 (DriverTest.test_check_for_driver_crash.FakeServerProcess.stop): 54 * Scripts/webkitpy/layout_tests/port/server_process.py: 55 (ServerProcess.write): 56 (ServerProcess._wait_for_data_and_update_buffers_using_select): 57 (ServerProcess.stop): 58 (ServerProcess.kill): 59 (ServerProcess): 60 (ServerProcess._kill): 61 * Scripts/webkitpy/layout_tests/port/server_process_unittest.py: 62 (TrivialMockPort.__init__): 63 (MockProc.wait): 64 (TestServerProcess.test_basic): 65 * Scripts/webkitpy/layout_tests/port/test.py: 66 (TestDriver.run_test): 67 * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py: 68 (get_tests_run.RecordingTestDriver.run_test): 69 * Scripts/webkitpy/performance_tests/perftest.py: 70 (PerfTest.run_single): 71 * Scripts/webkitpy/performance_tests/perftest_unittest.py: 72 (TestPageLoadingPerfTest.MockDriver.run_test): 73 (TestReplayPerfTest.ReplayTestPort.__init__.ReplayTestDriver.run_test): 74 (TestReplayPerfTest.test_run_single.run_test): 75 (TestReplayPerfTest.test_run_single_fails_when_output_has_error.run_test): 76 (TestReplayPerfTest.test_prepare.run_test): 77 * Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py: 78 (MainTest.TestDriver.run_test): 79 1 80 2012-08-16 Roger Fong <roger_fong@apple.com> 2 81 -
trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py
r125204 r125812 316 316 317 317 def _run_test(self, test_input): 318 self._batch_count += 1 319 320 stop_when_done = False 321 if self._batch_size > 0 and self._batch_count >= self._batch_size: 322 self._batch_count = 0 323 stop_when_done = True 324 318 325 self._update_test_input(test_input) 319 326 test_timeout_sec = self._timeout(test_input) … … 321 328 self._caller.post('started_test', test_input, test_timeout_sec) 322 329 323 result = self._run_test_with_timeout(test_input, test_timeout_sec )330 result = self._run_test_with_timeout(test_input, test_timeout_sec, stop_when_done) 324 331 325 332 elapsed_time = time.time() - start … … 360 367 driver.stop() 361 368 362 def _run_test_with_timeout(self, test_input, timeout ):369 def _run_test_with_timeout(self, test_input, timeout, stop_when_done): 363 370 if self._options.run_singly: 364 return self._run_test_in_another_thread(test_input, timeout )365 return self._run_test_in_this_thread(test_input )371 return self._run_test_in_another_thread(test_input, timeout, stop_when_done) 372 return self._run_test_in_this_thread(test_input, stop_when_done) 366 373 367 374 def _clean_up_after_test(self, test_input, result): 368 self._batch_count += 1369 375 test_name = test_input.test_name 370 376 self._tests_run_file.write(test_name + "\n") … … 386 392 _log.debug("%s %s passed" % (self._name, test_name)) 387 393 388 if self._batch_size > 0 and self._batch_count >= self._batch_size: 389 self._kill_driver() 390 self._batch_count = 0 391 392 def _run_test_in_another_thread(self, test_input, thread_timeout_sec): 394 def _run_test_in_another_thread(self, test_input, thread_timeout_sec, stop_when_done): 393 395 """Run a test in a separate thread, enforcing a hard time limit. 394 396 … … 413 415 414 416 def run(self): 415 self.result = worker._run_single_test(driver, test_input )417 self.result = worker._run_single_test(driver, test_input, stop_when_done) 416 418 417 419 thread = SingleTestThread() … … 436 438 return result 437 439 438 def _run_test_in_this_thread(self, test_input ):440 def _run_test_in_this_thread(self, test_input, stop_when_done): 439 441 """Run a single test file using a shared DumpRenderTree process. 440 442 … … 448 450 if not self._driver: 449 451 self._driver = self._port.create_driver(self._worker_number) 450 return self._run_single_test(self._driver, test_input )451 452 def _run_single_test(self, driver, test_input ):452 return self._run_single_test(self._driver, test_input, stop_when_done) 453 454 def _run_single_test(self, driver, test_input, stop_when_done): 453 455 return single_test_runner.run_single_test(self._port, self._options, 454 test_input, driver, self._name )456 test_input, driver, self._name, stop_when_done) 455 457 456 458 -
trunk/Tools/Scripts/webkitpy/layout_tests/controllers/single_test_runner.py
r124958 r125812 42 42 43 43 44 def run_single_test(port, options, test_input, driver, worker_name ):45 runner = SingleTestRunner(options, port, driver, test_input, worker_name )44 def run_single_test(port, options, test_input, driver, worker_name, stop_when_done): 45 runner = SingleTestRunner(options, port, driver, test_input, worker_name, stop_when_done) 46 46 return runner.run() 47 47 … … 50 50 (ALONGSIDE_TEST, PLATFORM_DIR, VERSION_DIR, UPDATE) = ('alongside', 'platform', 'version', 'update') 51 51 52 def __init__(self, options, port, driver, test_input, worker_name ):52 def __init__(self, options, port, driver, test_input, worker_name, stop_when_done): 53 53 self._options = options 54 54 self._port = port … … 60 60 self._should_run_pixel_test = test_input.should_run_pixel_test 61 61 self._reference_files = test_input.reference_files 62 self._stop_when_done = stop_when_done 62 63 63 64 if self._reference_files: … … 103 104 104 105 def _run_compare_test(self): 105 driver_output = self._driver.run_test(self._driver_input() )106 driver_output = self._driver.run_test(self._driver_input(), self._stop_when_done) 106 107 expected_driver_output = self._expected_driver_output() 107 108 … … 117 118 118 119 def _run_rebaseline(self): 119 driver_output = self._driver.run_test(self._driver_input() )120 driver_output = self._driver.run_test(self._driver_input(), self._stop_when_done) 120 121 failures = self._handle_error(driver_output) 121 122 test_result_writer.write_test_result(self._filesystem, self._port, self._test_name, driver_output, None, failures) … … 280 281 281 282 def _run_reftest(self): 282 test_output = self._driver.run_test(self._driver_input() )283 test_output = self._driver.run_test(self._driver_input(), self._stop_when_done) 283 284 total_test_time = 0 284 285 reference_output = None … … 294 295 for expectation, reference_filename in putAllMismatchBeforeMatch(self._reference_files): 295 296 reference_test_name = self._port.relative_test_filename(reference_filename) 296 reference_output = self._driver.run_test(DriverInput(reference_test_name, self._timeout, test_output.image_hash, should_run_pixel_test=True) )297 reference_output = self._driver.run_test(DriverInput(reference_test_name, self._timeout, test_output.image_hash, should_run_pixel_test=True), self._stop_when_done) 297 298 test_result = self._compare_output_with_reference(test_output, reference_output, reference_filename, expectation == '!=') 298 299 -
trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py
r125524 r125812 160 160 return 35 * 1000 161 161 162 def driver_stop_timeout(self): 163 """ Returns the amount of time in seconds to wait before killing the process in driver.stop().""" 164 # We want to wait for at least 3 seconds, but if we are really slow, we want to be slow on cleanup as 165 # well (for things like ASAN, Valgrind, etc.) 166 return 3.0 * float(self.get_option('time_out_ms', '0')) / self.default_timeout_ms() 167 162 168 def wdiff_available(self): 163 169 if self._wdiff_available is None: … … 1109 1115 return self._config.default_configuration() 1110 1116 1111 def process_kill_time(self):1112 """ Returns the amount of time in seconds to wait before killing the process.1113 1114 Within server_process.stop there is a time delta before the test is explictly1115 killed. By changing this the time can be extended in case the process needs1116 more time to cleanly exit on its own.1117 """1118 return 3.01119 1120 1117 # 1121 1118 # PROTECTED ROUTINES -
trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py
r125726 r125812 174 174 return 10 * 1000 175 175 176 def driver_stop_timeout(self): 177 # DRT doesn't respond to closing stdin, so we might as well stop the driver immediately. 178 return 0.0 179 176 180 def default_child_processes(self): 177 181 return len(self._get_devices()) … … 660 664 self._read_stderr_process = None 661 665 662 # Stop and kill server_process because our pipe reading/writing processes won't quit663 # by itself on close of the pipes.664 if self._server_process:665 self._server_process.stop(kill_directly=True)666 self._server_process = None667 666 super(ChromiumAndroidDriver, self).stop() 668 667 669 668 if self._forwarder_process: 670 self._forwarder_process. stop(kill_directly=True)669 self._forwarder_process.kill() 671 670 self._forwarder_process = None 672 671 -
trunk/Tools/Scripts/webkitpy/layout_tests/port/driver.py
r125316 r125812 137 137 self.stop() 138 138 139 def run_test(self, driver_input ):139 def run_test(self, driver_input, stop_when_done): 140 140 """Run a single test and return the results. 141 141 … … 159 159 image, actual_image_hash = self._read_optional_image_block(deadline) # The second (optional) block is image data. 160 160 161 # We may not have read all of the output if an error (crash) occured. 162 # Since some platforms output the stacktrace over error, we should 163 # dump any buffered error into self.error_from_test. 164 # FIXME: We may need to also read stderr until the process dies? 165 self.error_from_test += self._server_process.pop_all_buffered_stderr() 161 crashed = self.has_crashed() 162 timed_out = self._server_process.timed_out 163 164 if stop_when_done or crashed or timed_out: 165 # We call stop() even if we crashed or timed out in order to get any remaining stdout/stderr output. 166 # In the timeout case, we kill the hung process as well. 167 out, err = self._server_process.stop(self._port.driver_stop_timeout() if stop_when_done else 0.0) 168 text += out 169 self.error_from_test += err 170 self._server_process = None 166 171 167 172 crash_log = None 168 if self.has_crashed():173 if crashed: 169 174 self.error_from_test, crash_log = self._get_crash_log(text, self.error_from_test, newer_than=start_time) 170 175 … … 176 181 crash_log += ' Process failed to become responsive before timing out.' 177 182 178 timeout = self._server_process.timed_out179 if timeout:180 # DRT doesn't have a built in timer to abort the test, so we might as well181 # kill the process directly and not wait for it to shut down cleanly (since it may not).182 self._server_process.kill()183 184 183 return DriverOutput(text, image, actual_image_hash, audio, 185 crash= self.has_crashed(), test_time=time.time() - test_begin_time,186 timeout=time out, error=self.error_from_test,184 crash=crashed, test_time=time.time() - test_begin_time, 185 timeout=timed_out, error=self.error_from_test, 187 186 crashed_process_name=self._crashed_process_name, 188 187 crashed_pid=self._crashed_pid, crash_log=crash_log) … … 274 273 def stop(self): 275 274 if self._server_process: 276 self._server_process.stop( )275 self._server_process.stop(self._port.driver_stop_timeout()) 277 276 self._server_process = None 278 277 … … 477 476 return self._driver.uri_to_test(uri) 478 477 479 def run_test(self, driver_input ):478 def run_test(self, driver_input, stop_when_done): 480 479 base = self._port.lookup_virtual_test_base(driver_input.test_name) 481 480 if base: … … 483 482 virtual_driver_input.test_name = base 484 483 virtual_driver_input.args = self._port.lookup_virtual_test_args(driver_input.test_name) 485 return self.run_test(virtual_driver_input )484 return self.run_test(virtual_driver_input, stop_when_done) 486 485 487 486 pixel_tests_needed = driver_input.should_run_pixel_test … … 490 489 self._running_drivers[cmd_line_key] = self._make_driver(pixel_tests_needed) 491 490 492 return self._running_drivers[cmd_line_key].run_test(driver_input )491 return self._running_drivers[cmd_line_key].run_test(driver_input, stop_when_done) 493 492 494 493 def start(self): -
trunk/Tools/Scripts/webkitpy/layout_tests/port/driver_unittest.py
r124610 r125812 183 183 return self.crashed 184 184 185 def stop(self ):185 def stop(self, timeout): 186 186 pass 187 187 -
trunk/Tools/Scripts/webkitpy/layout_tests/port/server_process.py
r123893 r125812 141 141 self._proc.stdin.write(bytes) 142 142 except IOError, e: 143 self.stop( )143 self.stop(0.0) 144 144 # stop() calls _reset(), so we have to set crashed to True after calling stop(). 145 145 self._crashed = True … … 219 219 select_fds = (out_fd, err_fd) 220 220 try: 221 read_fds, _, _ = select.select(select_fds, [], select_fds, deadline - time.time())221 read_fds, _, _ = select.select(select_fds, [], select_fds, max(deadline - time.time(), 0)) 222 222 except select.error, e: 223 223 # We can ignore EINVAL since it's likely the process just crashed and we'll … … 308 308 self._start() 309 309 310 def stop(self, kill_directly=False):310 def stop(self, timeout_secs=3.0): 311 311 if not self._proc: 312 return 313 314 # Only bother to check for leaks if the process is still running.312 return (None, None) 313 314 # Only bother to check for leaks or stderr if the process is still running. 315 315 if self.poll() is None: 316 316 self._port.check_for_leaks(self.name(), self.pid()) 317 317 318 now = time.time() 318 319 self._proc.stdin.close() 319 self._proc.stdout.close() 320 if self._proc.stderr: 321 self._proc.stderr.close() 322 323 if kill_directly: 324 self.kill() 320 if not timeout_secs: 321 self._kill() 325 322 elif not self._host.platform.is_win(): 326 # Closing stdin/stdout/stderr hangs sometimes on OS X, 327 # and anyway we don't want to hang the harness if DumpRenderTree 328 # is buggy, so we wait a couple seconds to give DumpRenderTree a 329 # chance to clean up, but then force-kill the process if necessary. 330 timeout = time.time() + self._port.process_kill_time() 331 while self._proc.poll() is None and time.time() < timeout: 323 # FIXME: Why aren't we calling this on win? 324 deadline = now + timeout_secs 325 while self._proc.poll() is None and time.time() < deadline: 332 326 time.sleep(0.01) 333 327 if self._proc.poll() is None: 334 328 _log.warning('stopping %s timed out, killing it' % self._name) 335 self. kill()329 self._kill() 336 330 _log.warning('killed') 331 332 # read any remaining data on the pipes and return it. 333 if self._use_win32_apis: 334 self._wait_for_data_and_update_buffers_using_win32_apis(now) 335 else: 336 self._wait_for_data_and_update_buffers_using_select(now) 337 out, err = self._output, self._error 337 338 self._reset() 339 return (out, err) 338 340 339 341 def kill(self): 340 if self._proc: 341 self._host.executive.kill_process(self._proc.pid) 342 if self._proc.poll() is not None: 343 self._proc.wait() 344 self._reset() 342 self.stop(0.0) 343 344 def _kill(self): 345 self._host.executive.kill_process(self._proc.pid) 346 if self._proc.poll() is not None: 347 self._proc.wait() 345 348 346 349 def replace_outputs(self, stdout, stderr): -
trunk/Tools/Scripts/webkitpy/layout_tests/port/server_process_unittest.py
r122932 r125812 42 42 def __init__(self): 43 43 self.host = MockSystemHost() 44 self.host.executive.kill_process = lambda x: None 45 self.host.executive.kill_process = lambda x: None 44 46 45 47 def results_directory(self): … … 77 79 def poll(self): 78 80 return 1 81 82 def wait(self): 83 return 0 79 84 80 85 … … 115 120 self.assertEquals(line.strip(), "stderr") 116 121 117 proc.stop( )122 proc.stop(0) 118 123 119 124 def test_broken_pipe(self): -
trunk/Tools/Scripts/webkitpy/layout_tests/port/test.py
r124958 r125812 526 526 return [self._port._path_to_driver()] + [pixel_tests_flag] + self._port.get_option('additional_drt_flag', []) + per_test_args 527 527 528 def run_test(self, test_input ):528 def run_test(self, test_input, stop_when_done): 529 529 start_time = time.time() 530 530 test_name = test_input.test_name … … 564 564 crash_log = crash_logs.find_newest_log(crashed_process_name, None) or '' 565 565 566 if stop_when_done: 567 self.stop() 568 566 569 return DriverOutput(actual_text, test.actual_image, test.actual_checksum, audio, 567 570 crash=test.crash or test.web_process_crash, crashed_process_name=crashed_process_name, -
trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
r124967 r125812 148 148 self._current_test_batch = None 149 149 150 def run_test(self, test_input ):150 def run_test(self, test_input, stop_when_done): 151 151 if self._current_test_batch is None: 152 152 self._current_test_batch = [] … … 160 160 if include_reference_html or not Port.is_reference_html_file(filesystem, dirname, filename): 161 161 self._current_test_batch.append(test_name) 162 return TestDriver.run_test(self, test_input )162 return TestDriver.run_test(self, test_input, stop_when_done) 163 163 164 164 class RecordingTestPort(TestPort): -
trunk/Tools/Scripts/webkitpy/performance_tests/perftest.py
r125691 r125812 75 75 76 76 def run_single(self, driver, path_or_url, time_out_ms, should_run_pixel_test=False): 77 return driver.run_test(DriverInput(path_or_url, time_out_ms, image_hash=None, should_run_pixel_test=should_run_pixel_test) )77 return driver.run_test(DriverInput(path_or_url, time_out_ms, image_hash=None, should_run_pixel_test=should_run_pixel_test), stop_when_done=False) 78 78 79 79 def run_failed(self, output): -
trunk/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py
r125188 r125812 100 100 self._index = 0 101 101 102 def run_test(self, input ):102 def run_test(self, input, stop_when_done): 103 103 value = self._values[self._index] 104 104 self._index += 1 … … 142 142 143 143 class ReplayTestDriver(TestDriver): 144 def run_test(self, text_input ):145 return custom_run_test(text_input ) if custom_run_test else None144 def run_test(self, text_input, stop_when_done): 145 return custom_run_test(text_input, stop_when_done) if custom_run_test else None 146 146 147 147 self._custom_driver_class = ReplayTestDriver … … 175 175 loaded_pages = [] 176 176 177 def run_test(test_input ):177 def run_test(test_input, stop_when_done): 178 178 if test_input.test_name != "about:blank": 179 179 self.assertEqual(test_input.test_name, 'http://some-test/') … … 244 244 loaded_pages = [] 245 245 246 def run_test(test_input ):246 def run_test(test_input, stop_when_done): 247 247 loaded_pages.append(test_input) 248 248 self._add_file(port, '/path/some-dir', 'some-test.wpr', 'wpr content') … … 271 271 output_capture.capture_output() 272 272 273 def run_test(test_input ):273 def run_test(test_input, stop_when_done): 274 274 self._add_file(port, '/path/some-dir', 'some-test.wpr', 'wpr content') 275 275 return DriverOutput('actual text', 'actual image', 'actual checksum', -
trunk/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py
r125691 r125812 50 50 51 51 class TestDriver: 52 def run_test(self, driver_input ):52 def run_test(self, driver_input, stop_when_done): 53 53 text = '' 54 54 timeout = False
Note: See TracChangeset
for help on using the changeset viewer.