|
5 | 5 | import threading |
6 | 6 | import unittest |
7 | 7 |
|
| 8 | +from test import support |
8 | 9 | from test.support import socket_helper |
9 | 10 | from test.test_asyncio import utils as test_utils |
10 | 11 | from test.test_asyncio import functional as func_tests |
@@ -187,6 +188,37 @@ async def serve(rd, wr): |
187 | 188 | loop.call_soon(wr.close) |
188 | 189 | await srv.wait_closed() |
189 | 190 |
|
| 191 | + async def test_close_before_transport_created(self): |
| 192 | + # gh-109564: Closing the server after a connection was accepted, |
| 193 | + # but before its transport was created, must drop the connection |
| 194 | + # quietly. |
| 195 | + connected = False |
| 196 | + |
| 197 | + class Proto(asyncio.Protocol): |
| 198 | + def connection_made(self, transport): |
| 199 | + nonlocal connected |
| 200 | + connected = True |
| 201 | + |
| 202 | + def factory(): |
| 203 | + srv.close() |
| 204 | + return Proto() |
| 205 | + |
| 206 | + errors = [] |
| 207 | + loop = asyncio.get_running_loop() |
| 208 | + loop.set_exception_handler(lambda loop, ctx: errors.append(ctx)) |
| 209 | + srv = await loop.create_server(factory, socket_helper.HOSTv4, 0) |
| 210 | + self.addCleanup(srv.close) |
| 211 | + |
| 212 | + addr = srv.sockets[0].getsockname() |
| 213 | + (rd, wr) = await asyncio.open_connection(addr[0], addr[1]) |
| 214 | + self.addCleanup(wr.close) |
| 215 | + async with asyncio.timeout(support.SHORT_TIMEOUT): |
| 216 | + self.assertEqual(await rd.read(), b'') |
| 217 | + await srv.wait_closed() |
| 218 | + |
| 219 | + self.assertFalse(connected) |
| 220 | + self.assertEqual(errors, []) |
| 221 | + |
190 | 222 | async def test_close_clients(self): |
191 | 223 | async def serve(rd, wr): |
192 | 224 | try: |
|
0 commit comments