iOS 12 Simulator Release WK2 frequently timing out while running layout tests
authorjbedard@apple.com <jbedard@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Apr 2019 16:14:43 +0000 (16:14 +0000)
committerjbedard@apple.com <jbedard@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Apr 2019 16:14:43 +0000 (16:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196694
<rdar://problem/48388734>

Rubber-stamped by Aakash Jain.

* Scripts/webkitpy/port/image_diff.py:
(ImageDiffer.diff_image): If the ImageDiff process has data, kill it before running again.
* Scripts/webkitpy/port/server_process.py:
(ServerProcess.has_available_stdout): Check if stdout has data in it.
(ServerProcess._wait_for_data_and_update_buffers_using_select):
(ServerProcess._wait_for_data_and_update_buffers_using_win32_apis):
* Scripts/webkitpy/port/server_process_mock.py:
(MockServerProcess.has_available_stdout):
* Scripts/webkitpy/port/server_process_unittest.py:
(TestServerProcess.serial_test_basic):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244080 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/Scripts/webkitpy/port/image_diff.py
Tools/Scripts/webkitpy/port/server_process.py
Tools/Scripts/webkitpy/port/server_process_mock.py
Tools/Scripts/webkitpy/port/server_process_unittest.py

index 569dfaf..ae46bbf 100644 (file)
@@ -1,3 +1,22 @@
+2019-04-09  Jonathan Bedard  <jbedard@apple.com>
+
+        iOS 12 Simulator Release WK2 frequently timing out while running layout tests
+        https://bugs.webkit.org/show_bug.cgi?id=196694
+        <rdar://problem/48388734>
+
+        Rubber-stamped by Aakash Jain.
+
+        * Scripts/webkitpy/port/image_diff.py:
+        (ImageDiffer.diff_image): If the ImageDiff process has data, kill it before running again.
+        * Scripts/webkitpy/port/server_process.py:
+        (ServerProcess.has_available_stdout): Check if stdout has data in it.
+        (ServerProcess._wait_for_data_and_update_buffers_using_select):
+        (ServerProcess._wait_for_data_and_update_buffers_using_win32_apis):
+        * Scripts/webkitpy/port/server_process_mock.py:
+        (MockServerProcess.has_available_stdout):
+        * Scripts/webkitpy/port/server_process_unittest.py:
+        (TestServerProcess.serial_test_basic):
+
 2019-04-09  Jer Noble  <jer.noble@apple.com>
 
         Test for: 196095 Inband Text Track cues interspersed with Data cues can display out of order.
index 5004548..7713dda 100644 (file)
@@ -47,7 +47,7 @@ class ImageDiffer(object):
         self._process = None
 
     def diff_image(self, expected_contents, actual_contents, tolerance):
-        if tolerance != self._tolerance:
+        if tolerance != self._tolerance or (self._process and self._process.has_available_stdout()):
             self.stop()
         try:
             assert(expected_contents)
index 684d3cc..65f47a7 100644 (file)
@@ -203,6 +203,14 @@ class ServerProcess(object):
     def read_stdout_line(self, deadline):
         return self._read(deadline, self._pop_stdout_line_if_ready)
 
+    def has_available_stdout(self):
+        if not self.has_crashed() and self._use_win32_apis:
+            self._wait_for_data_and_update_buffers_using_win32_apis(0)
+        elif not self.has_crashed():
+            self._wait_for_data_and_update_buffers_using_select(0)
+
+        return bool(self._output)
+
     def read_stderr_line(self, deadline):
         return self._read(deadline, self._pop_stderr_line_if_ready)
 
@@ -256,7 +264,7 @@ class ServerProcess(object):
         return output
 
     def _wait_for_data_and_update_buffers_using_select(self, deadline, stopping=False):
-        if self._proc.stdout.closed or self._proc.stderr.closed:
+        if not self._proc or self._proc.stdout.closed or self._proc.stderr.closed:
             # If the process crashed and is using FIFOs, like Chromium Android, the
             # stdout and stderr pipes will be closed.
             return
@@ -300,12 +308,16 @@ class ServerProcess(object):
             pass
 
     def _wait_for_data_and_update_buffers_using_win32_apis(self, deadline):
+        if not self._proc:
+            return
+
         # See http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/
         # and http://docs.activestate.com/activepython/2.6/pywin32/modules.html
         # for documentation on all of these win32-specific modules.
         out_fh = msvcrt.get_osfhandle(self._proc.stdout.fileno())
         err_fh = msvcrt.get_osfhandle(self._proc.stderr.fileno())
-        while time.time() < deadline:
+        checking = True
+        while checking:
             output = self._non_blocking_read_win32(out_fh)
             error = self._non_blocking_read_win32(err_fh)
             if output or error:
@@ -317,6 +329,7 @@ class ServerProcess(object):
             if self._proc.poll() is not None:
                 return
             time.sleep(0.01)
+            checking = time.time() < deadline
 
     def _non_blocking_read_win32(self, handle):
         try:
index fb31c8e..b24ca68 100644 (file)
@@ -54,6 +54,11 @@ class MockServerProcess(object):
             return None
         return self.lines.pop(0) + "\n"
 
+    def has_available_stdout(self):
+        if self.has_crashed():
+            return False
+        return bool(self.lines)
+
     def read_stdout(self, deadline, size):
         if self.has_crashed():
             return None
index 5d802bf..ec7c25c 100644 (file)
@@ -101,7 +101,7 @@ class FakeServerProcess(server_process.ServerProcess):
 class TestServerProcess(unittest.TestCase):
     def serial_test_basic(self):
         # Give -u switch to force stdout and stderr to be unbuffered for Windows
-        cmd = [sys.executable, '-uc', 'import sys; print "stdout"; print >>sys.stderr, "stderr"; sys.stdin.readline();']
+        cmd = [sys.executable, '-uc', 'import sys; print "stdout"; print "again"; print >>sys.stderr, "stderr"; sys.stdin.readline();']
         host = SystemHost()
         factory = PortFactory(host)
         port = factory.get()
@@ -120,9 +120,15 @@ class TestServerProcess(unittest.TestCase):
         line = proc.read_stdout_line(now + 1.0)
         self.assertEqual(line.strip(), "stdout")
 
+        self.assertTrue(proc.has_available_stdout())
+
         line = proc.read_stderr_line(now + 1.0)
         self.assertEqual(line.strip(), "stderr")
 
+        line = proc.read_stdout_line(now + 1.0)
+        self.assertEqual(line.strip(), "again")
+        self.assertFalse(proc.has_available_stdout())
+
         proc.write('End\n')
         time.sleep(0.1)  # Give process a moment to close.
         self.assertEqual(proc.poll(), 0)