| 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 f140f6751bf2795f785922cd3b98e2ed47543dc6..a7d9b54ef6ce6f9b75643d6bd7164e9819d6d6f1 100644
|
| --- a/Tools/Scripts/webkitpy/layout_tests/port/driver.py
|
| +++ b/Tools/Scripts/webkitpy/layout_tests/port/driver.py
|
| @@ -46,6 +46,7 @@ DRIVER_START_TIMEOUT_SECS = 30
|
|
|
|
|
| class DriverInput(object):
|
| +
|
| def __init__(self, test_name, timeout, image_hash, should_run_pixel_test, args):
|
| self.test_name = test_name
|
| self.timeout = timeout # in ms
|
| @@ -55,12 +56,13 @@ class DriverInput(object):
|
|
|
|
|
| class DriverOutput(object):
|
| +
|
| """Groups information about a output from driver for easy passing
|
| and post-processing of data."""
|
|
|
| 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, leak=False, leak_log=None, pid=None):
|
| + test_time=0, measurements=None, timeout=False, error='', crashed_process_name='??',
|
| + 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.
|
| @@ -88,6 +90,7 @@ class DeviceFailure(Exception):
|
|
|
|
|
| class Driver(object):
|
| +
|
| """object for running test(s) using content_shell or other driver."""
|
|
|
| def __init__(self, port, worker_number, pixel_tests, no_timeout=False):
|
| @@ -130,10 +133,10 @@ class Driver(object):
|
| self._current_cmd_line = None
|
|
|
| self._measurements = {}
|
| - if self._port.get_option("profile"):
|
| - profiler_name = self._port.get_option("profiler")
|
| + if self._port.get_option('profile'):
|
| + profiler_name = self._port.get_option('profiler')
|
| self._profiler = ProfilerFactory.create_profiler(self._port.host,
|
| - self._port._path_to_driver(), self._port.results_directory(), profiler_name)
|
| + self._port._path_to_driver(), self._port.results_directory(), profiler_name)
|
| else:
|
| self._profiler = None
|
|
|
| @@ -171,9 +174,10 @@ class Driver(object):
|
| if not crashed:
|
| sanitizer = self._port._output_contains_sanitizer_messages(self.error_from_test)
|
| if sanitizer:
|
| - self.error_from_test = 'OUTPUT CONTAINS "' + sanitizer + '", so we are treating this test as if it crashed, even though it did not.\n\n' + self.error_from_test
|
| + self.error_from_test = 'OUTPUT CONTAINS "' + sanitizer + \
|
| + '", so we are treating this test as if it crashed, even though it did not.\n\n' + self.error_from_test
|
| crashed = True
|
| - self._crashed_process_name = "unknown process name"
|
| + self._crashed_process_name = 'unknown process name'
|
| self._crashed_pid = 0
|
|
|
| if stop_when_done or crashed or timed_out or leaked:
|
| @@ -192,7 +196,7 @@ class Driver(object):
|
|
|
| # If we don't find a crash log use a placeholder error message instead.
|
| if not crash_log:
|
| - pid_str = str(self._crashed_pid) if self._crashed_pid else "unknown pid"
|
| + pid_str = str(self._crashed_pid) if self._crashed_pid else 'unknown pid'
|
| crash_log = 'No crash log found for %s:%s.\n' % (self._crashed_process_name, pid_str)
|
| # If we were unresponsive append a message informing there may not have been a crash.
|
| if self._subprocess_was_unresponsive:
|
| @@ -203,12 +207,12 @@ class Driver(object):
|
| crash_log += '\nstdout:\n%s\nstderr:\n%s\n' % (text, self.error_from_test)
|
|
|
| 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,
|
| - leak=leaked, leak_log=self._leak_log,
|
| - pid=pid)
|
| + 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,
|
| + leak=leaked, leak_log=self._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)
|
| @@ -220,8 +224,8 @@ class Driver(object):
|
| # used by e.g. tools/valgrind/valgrind_tests.py.
|
| return shlex.split(wrapper_option) if wrapper_option else []
|
|
|
| - HTTP_DIR = "http/tests/"
|
| - HTTP_LOCAL_DIR = "http/tests/local/"
|
| + HTTP_DIR = 'http/tests/'
|
| + HTTP_LOCAL_DIR = 'http/tests/local/'
|
|
|
| def is_http_test(self, test_name):
|
| return test_name.startswith(self.HTTP_DIR) and not test_name.startswith(self.HTTP_LOCAL_DIR)
|
| @@ -238,9 +242,9 @@ class Driver(object):
|
|
|
| relative_path = test_name[len(self.HTTP_DIR):]
|
|
|
| - if "/https/" in test_name:
|
| - return "https://127.0.0.1:8443/" + relative_path
|
| - return "http://127.0.0.1:8000/" + relative_path
|
| + if '/https/' in test_name:
|
| + return 'https://127.0.0.1:8443/' + relative_path
|
| + return 'http://127.0.0.1:8000/' + relative_path
|
|
|
| def uri_to_test(self, uri):
|
| """Return the base layout test name for a given URI.
|
| @@ -250,14 +254,14 @@ class Driver(object):
|
| "fast/html/keygen.html".
|
|
|
| """
|
| - if uri.startswith("file:///"):
|
| + if uri.startswith('file:///'):
|
| prefix = path.abspath_to_uri(self._port.host.platform, self._port.layout_tests_dir())
|
| if not prefix.endswith('/'):
|
| prefix += '/'
|
| return uri[len(prefix):]
|
| - if uri.startswith("http://"):
|
| + if uri.startswith('http://'):
|
| return uri.replace('http://127.0.0.1:8000/', self.HTTP_DIR)
|
| - if uri.startswith("https://"):
|
| + if uri.startswith('https://'):
|
| return uri.replace('https://127.0.0.1:8443/', self.HTTP_DIR)
|
| raise NotImplementedError('unknown url type: %s' % uri)
|
|
|
| @@ -294,14 +298,19 @@ class Driver(object):
|
| self._leaked = False
|
| self._leak_log = None
|
| 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 = self._port._server_process_constructor(
|
| + self._port,
|
| + server_name,
|
| + cmd_line,
|
| + environment,
|
| + logging=self._port.get_option('driver_logging'))
|
| self._server_process.start()
|
| self._current_cmd_line = cmd_line
|
|
|
| if wait_for_ready:
|
| deadline = time.time() + DRIVER_START_TIMEOUT_SECS
|
| if not self._wait_for_server_process_output(self._server_process, deadline, '#READY'):
|
| - _log.error("content_shell took too long to startup.")
|
| + _log.error('content_shell took too long to startup.')
|
|
|
| def _wait_for_server_process_output(self, server_process, deadline, text):
|
| output = ''
|
| @@ -352,13 +361,13 @@ class Driver(object):
|
| return cmd
|
|
|
| def _check_for_driver_crash(self, error_line):
|
| - if error_line == "#CRASHED\n":
|
| + if error_line == '#CRASHED\n':
|
| # This is used on Windows to report that the process has crashed
|
| # See http://trac.webkit.org/changeset/65537.
|
| self._crashed_process_name = self._server_process.name()
|
| self._crashed_pid = self._server_process.pid()
|
| - elif (error_line.startswith("#CRASHED - ")
|
| - or error_line.startswith("#PROCESS UNRESPONSIVE - ")):
|
| + elif (error_line.startswith('#CRASHED - ')
|
| + or error_line.startswith('#PROCESS UNRESPONSIVE - ')):
|
| # WebKitTestRunner uses this to report that the WebProcess subprocess crashed.
|
| match = re.match('#(?:CRASHED|PROCESS UNRESPONSIVE) - (\S+)', error_line)
|
| self._crashed_process_name = match.group(1) if match else 'WebProcess'
|
| @@ -367,7 +376,7 @@ class Driver(object):
|
| self._crashed_pid = pid
|
| # FIXME: delete this after we're sure this code is working :)
|
| _log.debug('%s crash, pid = %s, error_line = %s' % (self._crashed_process_name, str(pid), error_line))
|
| - if error_line.startswith("#PROCESS UNRESPONSIVE - "):
|
| + if error_line.startswith('#PROCESS UNRESPONSIVE - '):
|
| self._subprocess_was_unresponsive = True
|
| self._port.sample_process(self._crashed_process_name, self._crashed_pid)
|
| # We want to show this since it's not a regular crash and probably we don't have a crash log.
|
| @@ -376,7 +385,7 @@ class Driver(object):
|
| return self.has_crashed()
|
|
|
| def _check_for_leak(self, error_line):
|
| - if error_line.startswith("#LEAK - "):
|
| + if error_line.startswith('#LEAK - '):
|
| self._leaked = True
|
| match = re.match('#LEAK - (\S+) pid (\d+) (.+)\n', error_line)
|
| self._leak_log = match.group(3)
|
| @@ -384,7 +393,8 @@ class Driver(object):
|
|
|
| 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'):
|
| + if driver_input.test_name.startswith(
|
| + 'http://') or driver_input.test_name.startswith('https://') or driver_input.test_name == ('about:blank'):
|
| command = driver_input.test_name
|
| elif self.is_http_test(driver_input.test_name):
|
| command = self.test_to_uri(driver_input.test_name)
|
| @@ -402,7 +412,7 @@ class Driver(object):
|
| command += "'--pixel-test"
|
| if driver_input.image_hash:
|
| command += "'" + driver_input.image_hash
|
| - return command + "\n"
|
| + return command + '\n'
|
|
|
| def _read_first_block(self, deadline):
|
| # returns (text_content, audio_content)
|
| @@ -433,22 +443,22 @@ class Driver(object):
|
|
|
| def _process_stdout_line(self, block, line):
|
| if (self._read_header(block, line, 'Content-Type: ', 'content_type')
|
| - or self._read_header(block, line, 'Content-Transfer-Encoding: ', 'encoding')
|
| - or self._read_header(block, line, 'Content-Length: ', '_content_length', int)
|
| - or self._read_header(block, line, 'ActualHash: ', 'content_hash')
|
| - or self._read_header(block, line, 'DumpMalloc: ', 'malloc')
|
| - or self._read_header(block, line, 'DumpJSHeap: ', 'js_heap')
|
| - or self._read_header(block, line, 'StdinPath', 'stdin_path')):
|
| + or self._read_header(block, line, 'Content-Transfer-Encoding: ', 'encoding')
|
| + or self._read_header(block, line, 'Content-Length: ', '_content_length', int)
|
| + or self._read_header(block, line, 'ActualHash: ', 'content_hash')
|
| + or self._read_header(block, line, 'DumpMalloc: ', 'malloc')
|
| + or self._read_header(block, line, 'DumpJSHeap: ', 'js_heap')
|
| + or self._read_header(block, line, 'StdinPath', 'stdin_path')):
|
| return
|
| # Note, we're not reading ExpectedHash: here, but we could.
|
| # If the line wasn't a header, we just append it to the content.
|
| block.content += line
|
|
|
| def _strip_eof(self, line):
|
| - if line and line.endswith("#EOF\n"):
|
| + if line and line.endswith('#EOF\n'):
|
| return line[:-5], True
|
| - if line and line.endswith("#EOF\r\n"):
|
| - _log.error("Got a CRLF-terminated #EOF - this is a driver bug.")
|
| + if line and line.endswith('#EOF\r\n'):
|
| + _log.error('Got a CRLF-terminated #EOF - this is a driver bug.')
|
| return line[:-6], True
|
| return line, False
|
|
|
| @@ -480,8 +490,9 @@ class Driver(object):
|
| err_line, self.err_seen_eof = self._strip_eof(err_line)
|
|
|
| if out_line:
|
| - if out_line[-1] != "\n":
|
| - _log.error("Last character read from DRT stdout line was not a newline! This indicates either a NRWT or DRT bug.")
|
| + if out_line[-1] != '\n':
|
| + _log.error(
|
| + 'Last character read from DRT stdout line was not a newline! This indicates either a NRWT or DRT bug.')
|
| content_length_before_header_check = block._content_length
|
| self._process_stdout_line(block, out_line)
|
| # FIXME: Unlike HTTP, DRT dumps the content right after printing a Content-Length header.
|
| @@ -490,7 +501,7 @@ class Driver(object):
|
| if block._content_length > 0:
|
| block.content = self._server_process.read_stdout(deadline, block._content_length)
|
| else:
|
| - _log.error("Received content of type %s with Content-Length of 0! This indicates a bug in %s.",
|
| + _log.error('Received content of type %s with Content-Length of 0! This indicates a bug in %s.',
|
| block.content_type, self._server_process.name())
|
|
|
| if err_line:
|
| @@ -505,6 +516,7 @@ class Driver(object):
|
|
|
|
|
| class ContentBlock(object):
|
| +
|
| def __init__(self):
|
| self.content_type = None
|
| self.encoding = None
|
|
|