| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2018-12-18 13:56:17 -08:00
										 |  |  | import signal | 
					
						
							| 
									
										
										
										
											2017-11-28 11:15:26 +01:00
										 |  |  | import socket | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2018-12-18 13:56:17 -08:00
										 |  |  | import subprocess | 
					
						
							|  |  |  | import time | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2015-01-26 15:04:03 +01:00
										 |  |  | from unittest import mock | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | if sys.platform != 'win32': | 
					
						
							|  |  |  |     raise unittest.SkipTest('Windows only') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 15:19:56 +01:00
										 |  |  | import _overlapped | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | import _winapi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import asyncio | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | from asyncio import windows_events | 
					
						
							| 
									
										
										
										
											2017-12-11 10:04:40 -05:00
										 |  |  | from test.test_asyncio import utils as test_utils | 
					
						
							| 
									
										
										
										
											2018-12-18 13:56:17 -08:00
										 |  |  | from test.support.script_helper import spawn_python | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 20:34:09 -07:00
										 |  |  | def tearDownModule(): | 
					
						
							|  |  |  |     asyncio.set_event_loop_policy(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | class UpperProto(asyncio.Protocol): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.buf = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connection_made(self, trans): | 
					
						
							|  |  |  |         self.trans = trans | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def data_received(self, data): | 
					
						
							|  |  |  |         self.buf.append(data) | 
					
						
							|  |  |  |         if b'\n' in data: | 
					
						
							|  |  |  |             self.trans.write(b''.join(self.buf).upper()) | 
					
						
							|  |  |  |             self.trans.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-18 13:56:17 -08:00
										 |  |  | class ProactorLoopCtrlC(test_utils.TestCase): | 
					
						
							|  |  |  |     def test_ctrl_c(self): | 
					
						
							|  |  |  |         from .test_ctrl_c_in_proactor_loop_helper import __file__ as f | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # ctrl-c will be sent to all processes that share the same console | 
					
						
							|  |  |  |         # in order to isolate the effect of raising ctrl-c we'll create | 
					
						
							|  |  |  |         # a process with a new console | 
					
						
							|  |  |  |         flags = subprocess.CREATE_NEW_CONSOLE | 
					
						
							|  |  |  |         with spawn_python(f, creationflags=flags) as p: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 exit_code = p.wait(timeout=5) | 
					
						
							|  |  |  |                 self.assertEqual(exit_code, 255) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 p.kill() | 
					
						
							|  |  |  |                 raise | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  | class ProactorTests(test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |         super().setUp() | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         self.loop = asyncio.ProactorEventLoop() | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |         self.set_event_loop(self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_close(self): | 
					
						
							| 
									
										
										
										
											2017-11-28 11:15:26 +01:00
										 |  |  |         a, b = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         trans = self.loop._make_socket_transport(a, asyncio.Protocol()) | 
					
						
							| 
									
										
										
										
											2017-12-14 20:53:26 -05:00
										 |  |  |         f = asyncio.ensure_future(self.loop.sock_recv(b, 100), loop=self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         trans.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertEqual(f.result(), b'') | 
					
						
							| 
									
										
										
										
											2014-01-11 00:16:50 +01:00
										 |  |  |         b.close() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_double_bind(self): | 
					
						
							|  |  |  |         ADDRESS = r'\\.\pipe\test_double_bind-%s' % os.getpid() | 
					
						
							|  |  |  |         server1 = windows_events.PipeServer(ADDRESS) | 
					
						
							|  |  |  |         with self.assertRaises(PermissionError): | 
					
						
							| 
									
										
										
										
											2014-02-26 11:07:42 +01:00
										 |  |  |             windows_events.PipeServer(ADDRESS) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         server1.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pipe(self): | 
					
						
							|  |  |  |         res = self.loop.run_until_complete(self._test_pipe()) | 
					
						
							|  |  |  |         self.assertEqual(res, 'done') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def _test_pipe(self): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         ADDRESS = r'\\.\pipe\_test_pipe-%s' % os.getpid() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(FileNotFoundError): | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             await self.loop.create_pipe_connection( | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |                 asyncio.Protocol, ADDRESS) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         [server] = await self.loop.start_serving_pipe( | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             UpperProto, ADDRESS) | 
					
						
							|  |  |  |         self.assertIsInstance(server, windows_events.PipeServer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         clients = [] | 
					
						
							|  |  |  |         for i in range(5): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             stream_reader = asyncio.StreamReader(loop=self.loop) | 
					
						
							| 
									
										
										
										
											2015-01-13 16:13:06 +01:00
										 |  |  |             protocol = asyncio.StreamReaderProtocol(stream_reader, | 
					
						
							|  |  |  |                                                     loop=self.loop) | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             trans, proto = await self.loop.create_pipe_connection( | 
					
						
							| 
									
										
										
										
											2013-11-01 14:20:55 -07:00
										 |  |  |                 lambda: protocol, ADDRESS) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             self.assertIsInstance(trans, asyncio.Transport) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             self.assertEqual(protocol, proto) | 
					
						
							|  |  |  |             clients.append((stream_reader, trans)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for i, (r, w) in enumerate(clients): | 
					
						
							|  |  |  |             w.write('lower-{}\n'.format(i).encode()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for i, (r, w) in enumerate(clients): | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             response = await r.readline() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             self.assertEqual(response, 'LOWER-{}\n'.format(i).encode()) | 
					
						
							|  |  |  |             w.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(FileNotFoundError): | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             await self.loop.create_pipe_connection( | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |                 asyncio.Protocol, ADDRESS) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return 'done' | 
					
						
							| 
									
										
										
										
											2013-10-20 21:02:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-26 15:04:03 +01:00
										 |  |  |     def test_connect_pipe_cancel(self): | 
					
						
							|  |  |  |         exc = OSError() | 
					
						
							|  |  |  |         exc.winerror = _overlapped.ERROR_PIPE_BUSY | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         with mock.patch.object(_overlapped, 'ConnectPipe', | 
					
						
							|  |  |  |                                side_effect=exc) as connect: | 
					
						
							| 
									
										
										
										
											2015-01-26 15:04:03 +01:00
										 |  |  |             coro = self.loop._proactor.connect_pipe('pipe_address') | 
					
						
							|  |  |  |             task = self.loop.create_task(coro) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # check that it's possible to cancel connect_pipe() | 
					
						
							|  |  |  |             task.cancel() | 
					
						
							|  |  |  |             with self.assertRaises(asyncio.CancelledError): | 
					
						
							|  |  |  |                 self.loop.run_until_complete(task) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |     def test_wait_for_handle(self): | 
					
						
							|  |  |  |         event = _overlapped.CreateEvent(None, True, False, None) | 
					
						
							|  |  |  |         self.addCleanup(_winapi.CloseHandle, event) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:22 +02:00
										 |  |  |         # Wait for unset event with 0.5s timeout; | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         # result should be False at timeout | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         fut = self.loop._proactor.wait_for_handle(event, 0.5) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         start = self.loop.time() | 
					
						
							| 
									
										
										
										
											2014-12-19 17:10:44 +01:00
										 |  |  |         done = self.loop.run_until_complete(fut) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         elapsed = self.loop.time() - start | 
					
						
							| 
									
										
										
										
											2014-12-19 17:10:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(done, False) | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         self.assertFalse(fut.result()) | 
					
						
							| 
									
										
										
										
											2017-08-11 01:23:22 +02:00
										 |  |  |         # bpo-31008: Tolerate only 450 ms (at least 500 ms expected), | 
					
						
							|  |  |  |         # because of bad clock resolution on Windows | 
					
						
							|  |  |  |         self.assertTrue(0.45 <= elapsed <= 0.9, elapsed) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         _overlapped.SetEvent(event) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-01 18:28:43 +02:00
										 |  |  |         # Wait for set event; | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         # result should be True immediately | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         fut = self.loop._proactor.wait_for_handle(event, 10) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         start = self.loop.time() | 
					
						
							| 
									
										
										
										
											2014-12-19 17:10:44 +01:00
										 |  |  |         done = self.loop.run_until_complete(fut) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         elapsed = self.loop.time() - start | 
					
						
							| 
									
										
										
										
											2014-12-19 17:10:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(done, True) | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         self.assertTrue(fut.result()) | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:22 +02:00
										 |  |  |         self.assertTrue(0 <= elapsed < 0.3, elapsed) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 23:13:50 +02:00
										 |  |  |         # asyncio issue #195: cancelling a done _WaitHandleFuture | 
					
						
							|  |  |  |         # must not crash | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         fut.cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_wait_for_handle_cancel(self): | 
					
						
							|  |  |  |         event = _overlapped.CreateEvent(None, True, False, None) | 
					
						
							|  |  |  |         self.addCleanup(_winapi.CloseHandle, event) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Wait for unset event with a cancelled future; | 
					
						
							|  |  |  |         # CancelledError should be raised immediately | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         fut = self.loop._proactor.wait_for_handle(event, 10) | 
					
						
							|  |  |  |         fut.cancel() | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         start = self.loop.time() | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         with self.assertRaises(asyncio.CancelledError): | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |             self.loop.run_until_complete(fut) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  |         elapsed = self.loop.time() - start | 
					
						
							| 
									
										
										
										
											2013-12-13 02:45:18 +01:00
										 |  |  |         self.assertTrue(0 <= elapsed < 0.1, elapsed) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-09 23:13:50 +02:00
										 |  |  |         # asyncio issue #195: cancelling a _WaitHandleFuture twice | 
					
						
							|  |  |  |         # must not crash | 
					
						
							| 
									
										
										
										
											2014-07-25 00:54:53 +02:00
										 |  |  |         fut = self.loop._proactor.wait_for_handle(event) | 
					
						
							|  |  |  |         fut.cancel() | 
					
						
							|  |  |  |         fut.cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 21:02:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-07 20:44:57 -04:00
										 |  |  | class WinPolicyTests(test_utils.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_selector_win_policy(self): | 
					
						
							|  |  |  |         async def main(): | 
					
						
							|  |  |  |             self.assertIsInstance( | 
					
						
							|  |  |  |                 asyncio.get_running_loop(), | 
					
						
							|  |  |  |                 asyncio.SelectorEventLoop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         old_policy = asyncio.get_event_loop_policy() | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             asyncio.set_event_loop_policy( | 
					
						
							|  |  |  |                 asyncio.WindowsSelectorEventLoopPolicy()) | 
					
						
							|  |  |  |             asyncio.run(main()) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             asyncio.set_event_loop_policy(old_policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_proactor_win_policy(self): | 
					
						
							|  |  |  |         async def main(): | 
					
						
							|  |  |  |             self.assertIsInstance( | 
					
						
							|  |  |  |                 asyncio.get_running_loop(), | 
					
						
							|  |  |  |                 asyncio.ProactorEventLoop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         old_policy = asyncio.get_event_loop_policy() | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             asyncio.set_event_loop_policy( | 
					
						
							|  |  |  |                 asyncio.WindowsProactorEventLoopPolicy()) | 
					
						
							|  |  |  |             asyncio.run(main()) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             asyncio.set_event_loop_policy(old_policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-20 21:02:53 +02:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main() |