summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_asyncio/test_proactor_events.py
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2018-02-25 16:32:14 (GMT)
committerGitHub <noreply@github.com>2018-02-25 16:32:14 (GMT)
commita19fb3c6aaa7632410d1d9dcb395d7101d124da4 (patch)
tree476902dc75526cc8bb22c41cf213416384c36805 /Lib/test/test_asyncio/test_proactor_events.py
parent5fb632e83136399bad9427ee23ec8b771695290a (diff)
downloadcpython-a19fb3c6aaa7632410d1d9dcb395d7101d124da4.zip
cpython-a19fb3c6aaa7632410d1d9dcb395d7101d124da4.tar.gz
cpython-a19fb3c6aaa7632410d1d9dcb395d7101d124da4.tar.bz2
bpo-32622: Native sendfile on windows (#5565)
* Support sendfile on Windows Proactor event loop naively.
Diffstat (limited to 'Lib/test/test_asyncio/test_proactor_events.py')
-rw-r--r--Lib/test/test_asyncio/test_proactor_events.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py
index f627dfc..98e6989 100644
--- a/Lib/test/test_asyncio/test_proactor_events.py
+++ b/Lib/test/test_asyncio/test_proactor_events.py
@@ -1,14 +1,18 @@
"""Tests for proactor_events.py"""
+import io
import socket
import unittest
+import sys
from unittest import mock
import asyncio
+from asyncio import events
from asyncio.proactor_events import BaseProactorEventLoop
from asyncio.proactor_events import _ProactorSocketTransport
from asyncio.proactor_events import _ProactorWritePipeTransport
from asyncio.proactor_events import _ProactorDuplexPipeTransport
+from test import support
from test.test_asyncio import utils as test_utils
@@ -775,5 +779,117 @@ class BaseProactorEventLoopTests(test_utils.TestCase):
self.assertFalse(future2.cancel.called)
+@unittest.skipIf(sys.platform != 'win32',
+ 'Proactor is supported on Windows only')
+class ProactorEventLoopUnixSockSendfileTests(test_utils.TestCase):
+ DATA = b"12345abcde" * 16 * 1024 # 160 KiB
+
+ class MyProto(asyncio.Protocol):
+
+ def __init__(self, loop):
+ self.started = False
+ self.closed = False
+ self.data = bytearray()
+ self.fut = loop.create_future()
+ self.transport = None
+
+ def connection_made(self, transport):
+ self.started = True
+ self.transport = transport
+
+ def data_received(self, data):
+ self.data.extend(data)
+
+ def connection_lost(self, exc):
+ self.closed = True
+ self.fut.set_result(None)
+
+ async def wait_closed(self):
+ await self.fut
+
+ @classmethod
+ def setUpClass(cls):
+ with open(support.TESTFN, 'wb') as fp:
+ fp.write(cls.DATA)
+ super().setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ support.unlink(support.TESTFN)
+ super().tearDownClass()
+
+ def setUp(self):
+ self.loop = asyncio.ProactorEventLoop()
+ self.set_event_loop(self.loop)
+ self.addCleanup(self.loop.close)
+ self.file = open(support.TESTFN, 'rb')
+ self.addCleanup(self.file.close)
+ super().setUp()
+
+ def make_socket(self, cleanup=True):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.setblocking(False)
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024)
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024)
+ if cleanup:
+ self.addCleanup(sock.close)
+ return sock
+
+ def run_loop(self, coro):
+ return self.loop.run_until_complete(coro)
+
+ def prepare(self):
+ sock = self.make_socket()
+ proto = self.MyProto(self.loop)
+ port = support.find_unused_port()
+ srv_sock = self.make_socket(cleanup=False)
+ srv_sock.bind(('127.0.0.1', port))
+ server = self.run_loop(self.loop.create_server(
+ lambda: proto, sock=srv_sock))
+ self.run_loop(self.loop.sock_connect(sock, srv_sock.getsockname()))
+
+ def cleanup():
+ if proto.transport is not None:
+ # can be None if the task was cancelled before
+ # connection_made callback
+ proto.transport.close()
+ self.run_loop(proto.wait_closed())
+
+ server.close()
+ self.run_loop(server.wait_closed())
+
+ self.addCleanup(cleanup)
+
+ return sock, proto
+
+ def test_sock_sendfile_not_a_file(self):
+ sock, proto = self.prepare()
+ f = object()
+ with self.assertRaisesRegex(events.SendfileNotAvailableError,
+ "not a regular file"):
+ self.run_loop(self.loop._sock_sendfile_native(sock, f,
+ 0, None))
+ self.assertEqual(self.file.tell(), 0)
+
+ def test_sock_sendfile_iobuffer(self):
+ sock, proto = self.prepare()
+ f = io.BytesIO()
+ with self.assertRaisesRegex(events.SendfileNotAvailableError,
+ "not a regular file"):
+ self.run_loop(self.loop._sock_sendfile_native(sock, f,
+ 0, None))
+ self.assertEqual(self.file.tell(), 0)
+
+ def test_sock_sendfile_not_regular_file(self):
+ sock, proto = self.prepare()
+ f = mock.Mock()
+ f.fileno.return_value = -1
+ with self.assertRaisesRegex(events.SendfileNotAvailableError,
+ "not a regular file"):
+ self.run_loop(self.loop._sock_sendfile_native(sock, f,
+ 0, None))
+ self.assertEqual(self.file.tell(), 0)
+
+
if __name__ == '__main__':
unittest.main()