[Python-checkins] bpo-30064: Properly skip unstable loop.sock_connect() racing test (GH-20494)

Fantix King webhook-mailer at python.org
Thu May 28 17:56:51 EDT 2020


https://github.com/python/cpython/commit/dc4eee9e266267498a6b783a0abccc23c06f2b87
commit: dc4eee9e266267498a6b783a0abccc23c06f2b87
branch: master
author: Fantix King <fantix.king at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-05-28T14:56:42-07:00
summary:

bpo-30064: Properly skip unstable loop.sock_connect() racing test (GH-20494)

files:
M Lib/test/test_asyncio/test_sock_lowlevel.py

diff --git a/Lib/test/test_asyncio/test_sock_lowlevel.py b/Lib/test/test_asyncio/test_sock_lowlevel.py
index e0583c0419564..2c8ce6b657c14 100644
--- a/Lib/test/test_asyncio/test_sock_lowlevel.py
+++ b/Lib/test/test_asyncio/test_sock_lowlevel.py
@@ -202,6 +202,14 @@ async def recv_until():
             # ProactorEventLoop could deliver hello
             self.assertTrue(data.endswith(b'world'))
 
+    # After the first connect attempt before the listener is ready,
+    # the socket needs time to "recover" to make the next connect call.
+    # On Linux, a second retry will do. On Windows, the waiting time is
+    # unpredictable; and on FreeBSD the socket may never come back
+    # because it's a loopback address. Here we'll just retry for a few
+    # times, and have to skip the test if it's not working. See also:
+    # https://stackoverflow.com/a/54437602/3316267
+    # https://lists.freebsd.org/pipermail/freebsd-current/2005-May/049876.html
     async def _basetest_sock_connect_racing(self, listener, sock):
         listener.bind(('127.0.0.1', 0))
         addr = listener.getsockname()
@@ -212,30 +220,26 @@ async def _basetest_sock_connect_racing(self, listener, sock):
         task.cancel()
 
         listener.listen(1)
-        i = 0
-        while True:
+
+        skip_reason = "Max retries reached"
+        for i in range(128):
             try:
                 await self.loop.sock_connect(sock, addr)
-                break
-            except ConnectionRefusedError:  # on Linux we need another retry
-                await self.loop.sock_connect(sock, addr)
-                break
-            except OSError as e:  # on Windows we need more retries
-                # A connect request was made on an already connected socket
-                if getattr(e, 'winerror', 0) == 10056:
-                    break
+            except ConnectionRefusedError as e:
+                skip_reason = e
+            except OSError as e:
+                skip_reason = e
 
-                # https://stackoverflow.com/a/54437602/3316267
+                # Retry only for this error:
+                # [WinError 10022] An invalid argument was supplied
                 if getattr(e, 'winerror', 0) != 10022:
-                    raise
-                i += 1
-                if i >= 128:
-                    raise  # too many retries
-                # avoid touching event loop to maintain race condition
-                time.sleep(0.01)
-
-    # FIXME: https://bugs.python.org/issue30064#msg370143
-    @unittest.skipIf(True, "unstable test")
+                    break
+            else:
+                # success
+                return
+
+        self.skipTest(skip_reason)
+
     def test_sock_client_racing(self):
         with test_utils.run_test_server() as httpd:
             sock = socket.socket()
@@ -251,6 +255,8 @@ def test_sock_client_racing(self):
         with listener, sock:
             self.loop.run_until_complete(asyncio.wait_for(
                 self._basetest_sock_send_racing(listener, sock), 10))
+
+    def test_sock_client_connect_racing(self):
         listener = socket.socket()
         sock = socket.socket()
         with listener, sock:



More information about the Python-checkins mailing list