bpo-30064: Properly skip unstable loop.sock_connect() racing test (GH… · python/cpython@6637bd4

@@ -202,6 +202,14 @@ async def recv_until():

202202

# ProactorEventLoop could deliver hello

203203

self.assertTrue(data.endswith(b'world'))

204204205+

# After the first connect attempt before the listener is ready,

206+

# the socket needs time to "recover" to make the next connect call.

207+

# On Linux, a second retry will do. On Windows, the waiting time is

208+

# unpredictable; and on FreeBSD the socket may never come back

209+

# because it's a loopback address. Here we'll just retry for a few

210+

# times, and have to skip the test if it's not working. See also:

211+

# https://stackoverflow.com/a/54437602/3316267

212+

# https://lists.freebsd.org/pipermail/freebsd-current/2005-May/049876.html

205213

async def _basetest_sock_connect_racing(self, listener, sock):

206214

listener.bind(('127.0.0.1', 0))

207215

addr = listener.getsockname()

@@ -212,30 +220,26 @@ async def _basetest_sock_connect_racing(self, listener, sock):

212220

task.cancel()

213221214222

listener.listen(1)

215-

i = 0

216-

while True:

223+224+

skip_reason = "Max retries reached"

225+

for i in range(128):

217226

try:

218227

await self.loop.sock_connect(sock, addr)

219-

break

220-

except ConnectionRefusedError: # on Linux we need another retry

221-

await self.loop.sock_connect(sock, addr)

222-

break

223-

except OSError as e: # on Windows we need more retries

224-

# A connect request was made on an already connected socket

225-

if getattr(e, 'winerror', 0) == 10056:

226-

break

228+

except ConnectionRefusedError as e:

229+

skip_reason = e

230+

except OSError as e:

231+

skip_reason = e

227232228-

# https://stackoverflow.com/a/54437602/3316267

233+

# Retry only for this error:

234+

# [WinError 10022] An invalid argument was supplied

229235

if getattr(e, 'winerror', 0) != 10022:

230-

raise

231-

i += 1

232-

if i >= 128:

233-

raise # too many retries

234-

# avoid touching event loop to maintain race condition

235-

time.sleep(0.01)

236-237-

# FIXME: https://bugs.python.org/issue30064#msg370143

238-

@unittest.skipIf(True, "unstable test")

236+

break

237+

else:

238+

# success

239+

return

240+241+

self.skipTest(skip_reason)

242+239243

def test_sock_client_racing(self):

240244

with test_utils.run_test_server() as httpd:

241245

sock = socket.socket()

@@ -251,6 +255,8 @@ def test_sock_client_racing(self):

251255

with listener, sock:

252256

self.loop.run_until_complete(asyncio.wait_for(

253257

self._basetest_sock_send_racing(listener, sock), 10))

258+259+

def test_sock_client_connect_racing(self):

254260

listener = socket.socket()

255261

sock = socket.socket()

256262

with listener, sock: