| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import os | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | 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') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | import _winapi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import asyncio | 
					
						
							| 
									
										
										
										
											2013-10-30 14:44:05 -07:00
										 |  |  | from asyncio import _overlapped | 
					
						
							| 
									
										
										
										
											2014-06-18 03:25:23 +02:00
										 |  |  | from asyncio import test_utils | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | from asyncio import windows_events | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							|  |  |  |         a, b = self.loop._socketpair() | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         trans = self.loop._make_socket_transport(a, asyncio.Protocol()) | 
					
						
							| 
									
										
										
										
											2015-05-11 14:48:38 -04:00
										 |  |  |         f = asyncio.ensure_future(self.loop.sock_recv(b, 100)) | 
					
						
							| 
									
										
										
										
											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') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _test_pipe(self): | 
					
						
							|  |  |  |         ADDRESS = r'\\.\pipe\_test_pipe-%s' % os.getpid() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(FileNotFoundError): | 
					
						
							|  |  |  |             yield from self.loop.create_pipe_connection( | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |                 asyncio.Protocol, ADDRESS) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         [server] = yield from self.loop.start_serving_pipe( | 
					
						
							|  |  |  |             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) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             trans, proto = yield from 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): | 
					
						
							|  |  |  |             response = yield from r.readline() | 
					
						
							|  |  |  |             self.assertEqual(response, 'LOWER-{}\n'.format(i).encode()) | 
					
						
							|  |  |  |             w.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(FileNotFoundError): | 
					
						
							|  |  |  |             yield from 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 | 
					
						
							|  |  |  |         with mock.patch.object(_overlapped, 'ConnectPipe', side_effect=exc) as connect: | 
					
						
							|  |  |  |             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
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main() |