Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1817)

Unified Diff: Tools/Scripts/webkitpy/layout_tests/port/driver.py

Issue 148153009: DOM-object leak detection at run_webkit_tests.py (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Bug fix: unit test Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Tools/Scripts/webkitpy/layout_tests/port/driver.py
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/driver.py b/Tools/Scripts/webkitpy/layout_tests/port/driver.py
index e7a439d04baa9cbc547e81bcd3f8a5360751853a..fd44a53e7f034f5a436922c8cea7e97bc8760213 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/driver.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/driver.py
@@ -60,7 +60,7 @@ class DriverOutput(object):
def __init__(self, text, image, image_hash, audio, crash=False,
test_time=0, measurements=None, timeout=False, error='', crashed_process_name='??',
- crashed_pid=None, crash_log=None, pid=None):
+ crashed_pid=None, crash_log=None, leak=False, leak_log=None, pid=None):
# FIXME: Args could be renamed to better clarify what they do.
self.text = text
self.image = image # May be empty-string if the test crashes.
@@ -71,6 +71,8 @@ class DriverOutput(object):
self.crashed_process_name = crashed_process_name
self.crashed_pid = crashed_pid
self.crash_log = crash_log
+ self.leak = leak
+ self.leak_log = leak_log
self.test_time = test_time
self.measurements = measurements
self.timeout = timeout
@@ -102,17 +104,22 @@ class Driver(object):
self._no_timeout = no_timeout
self._driver_tempdir = None
- # WebKitTestRunner can report back subprocess crashes by printing
+ # content_shell can report back subprocess crashes by printing
# "#CRASHED - PROCESSNAME". Since those can happen at any time
# and ServerProcess won't be aware of them (since the actual tool
# didn't crash, just a subprocess) we record the crashed subprocess name here.
self._crashed_process_name = None
self._crashed_pid = None
- # WebKitTestRunner can report back subprocesses that became unresponsive
+ # content_shell can report back subprocesses that became unresponsive
# This could mean they crashed.
self._subprocess_was_unresponsive = False
+ # content_shell can report back subprocess DOM-object leaks by printing
+ # "#LEAK". This leak detection is enabled only when the flag
+ # --enable-leak-detection is passed to content_shell.
+ self._leaked = False
+
# stderr reading is scoped on a per-test (not per-block) basis, so we store the accumulated
# stderr output, as well as if we've seen #EOF on this driver instance.
# FIXME: We should probably remove _read_first_block and _read_optional_image_block and
@@ -158,8 +165,9 @@ class Driver(object):
crashed = self.has_crashed()
timed_out = self._server_process.timed_out
pid = self._server_process.pid()
+ leaked = self._leaked
- if stop_when_done or crashed or timed_out:
+ if stop_when_done or crashed or timed_out or leaked:
# We call stop() even if we crashed or timed out in order to get any remaining stdout/stderr output.
# In the timeout case, we kill the hung process as well.
out, err = self._server_process.stop(self._port.driver_stop_timeout() if stop_when_done else 0.0)
@@ -170,6 +178,7 @@ class Driver(object):
self._server_process = None
crash_log = None
+ leak_log = None
if crashed:
self.error_from_test, crash_log = self._get_crash_log(text, self.error_from_test, newer_than=start_time)
@@ -184,16 +193,23 @@ class Driver(object):
# Print stdout and stderr to the placeholder crash log; we want as much context as possible.
if self.error_from_test:
crash_log += '\nstdout:\n%s\nstderr:\n%s\n' % (text, self.error_from_test)
+ elif leaked:
+ self.error_from_test, leak_log = self._get_leak_log(text, self.error_from_test, newer_than=start_time)
return DriverOutput(text, image, actual_image_hash, audio,
crash=crashed, test_time=time.time() - test_begin_time, measurements=self._measurements,
timeout=timed_out, error=self.error_from_test,
crashed_process_name=self._crashed_process_name,
- crashed_pid=self._crashed_pid, crash_log=crash_log, pid=pid)
+ crashed_pid=self._crashed_pid, crash_log=crash_log,
+ leak=leaked, leak_log=leak_log,
+ pid=pid)
def _get_crash_log(self, stdout, stderr, newer_than):
return self._port._get_crash_log(self._crashed_process_name, self._crashed_pid, stdout, stderr, newer_than)
+ def _get_leak_log(self, stdout, stderr, newer_than):
+ return self._port._get_leak_log(self._crashed_process_name, self._crashed_pid, stdout, stderr, newer_than)
+
# FIXME: Seems this could just be inlined into callers.
@classmethod
def _command_wrapper(cls, wrapper_option):
@@ -268,6 +284,7 @@ class Driver(object):
environment = self._setup_environ_for_driver(environment)
self._crashed_process_name = None
self._crashed_pid = None
+ self._leaked = False
cmd_line = self.cmd_line(pixel_tests, per_test_args)
self._server_process = self._port._server_process_constructor(self._port, server_name, cmd_line, environment, logging=self._port.get_option("driver_logging"))
self._server_process.start()
@@ -320,6 +337,8 @@ class Driver(object):
cmd.append('--no-timeout')
cmd.extend(self._port.get_option('additional_drt_flag', []))
cmd.extend(self._port.additional_drt_flag())
+ if self._port.get_option('enable_leak_detection'):
+ cmd.append('--enable-leak-detection')
cmd.extend(per_test_args)
cmd.append('-')
return cmd
@@ -348,6 +367,11 @@ class Driver(object):
return True
return self.has_crashed()
+ def _check_for_leak(self, error_line):
+ if error_line.startswith("#LEAK - "):
+ self._leaked = True
+ return self._leaked
+
def _command_from_driver_input(self, driver_input):
# FIXME: performance tests pass in full URLs instead of test names.
if driver_input.test_name.startswith('http://') or driver_input.test_name.startswith('https://') or driver_input.test_name == ('about:blank'):
@@ -461,6 +485,7 @@ class Driver(object):
if err_line:
if self._check_for_driver_crash(err_line):
break
+ self._check_for_leak(err_line)
self.error_from_test += err_line
block.decode_content()
« no previous file with comments | « Tools/Scripts/webkitpy/layout_tests/port/base.py ('k') | Tools/Scripts/webkitpy/layout_tests/port/driver_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698