Skip to content

Commit 4822ab7

Browse files
committed
add test for close called in error_recieved
1 parent 0db5dd3 commit 4822ab7

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

Lib/test/test_asyncio/test_events.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,46 @@ def connection_lost(self, exc):
18091809
loop.run_until_complete(asyncio.wait_for(protocol.lost, 10))
18101810
self.assertTrue(protocol.errors)
18111811

1812+
def test_datagram_write_error_close_from_callback(self):
1813+
# See https://github.com/python/cpython/issues/156920: an
1814+
# error_received() callback that closes the transport while data
1815+
# is still queued behind the failing write must still result in
1816+
# connection_lost() being called eventually, instead of leaving
1817+
# the transport (and its buffered data) hanging forever.
1818+
loop = self.loop
1819+
1820+
class Protocol(asyncio.DatagramProtocol):
1821+
def connection_made(self, transport):
1822+
self.transport = transport
1823+
self.errors = []
1824+
self.lost = loop.create_future()
1825+
1826+
def error_received(self, exc):
1827+
self.errors.append(exc)
1828+
self.transport.close()
1829+
1830+
def connection_lost(self, exc):
1831+
if not self.lost.done():
1832+
self.lost.set_result(exc)
1833+
1834+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
1835+
sock.setblocking(False)
1836+
sock.bind(('127.0.0.1', 0))
1837+
transport, protocol = loop.run_until_complete(
1838+
loop.create_datagram_endpoint(Protocol, sock=sock))
1839+
addr = sock.getsockname()
1840+
1841+
# queue an oversized (failing) datagram followed by one that
1842+
# would otherwise succeed, so the buffer is still non-empty when
1843+
# error_received() closes the transport.
1844+
oversized = b'\x00' * 70000
1845+
transport.sendto(oversized, addr)
1846+
transport.sendto(b'queued', addr)
1847+
1848+
loop.run_until_complete(asyncio.wait_for(protocol.lost, 10))
1849+
self.assertTrue(protocol.errors)
1850+
self.assertIsInstance(protocol.errors[0], OSError)
1851+
18121852
def test_datagram_recvfrom_connection_reset_recovers(self):
18131853
# gh-127057: a UDP socket that sent a datagram to an address that
18141854
# wasn't listening can raise ConnectionResetError on a later

0 commit comments

Comments
 (0)