| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | """Tests for events.py.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 20:07:11 -05:00
										 |  |  | import concurrent.futures | 
					
						
							| 
									
										
										
										
											2025-03-24 12:38:33 +00:00
										 |  |  | import contextlib | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import functools | 
					
						
							|  |  |  | import io | 
					
						
							| 
									
										
										
										
											2023-02-02 15:50:35 -08:00
										 |  |  | import multiprocessing | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  | import platform | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import signal | 
					
						
							|  |  |  | import socket | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     import ssl | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     ssl = None | 
					
						
							|  |  |  | import subprocess | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import threading | 
					
						
							|  |  |  | import time | 
					
						
							| 
									
										
										
										
											2021-07-01 16:13:59 +03:00
										 |  |  | import types | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import errno | 
					
						
							|  |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2014-02-26 10:25:02 +01:00
										 |  |  | from unittest import mock | 
					
						
							| 
									
										
										
										
											2014-04-27 10:44:22 -07:00
										 |  |  | import weakref | 
					
						
							| 
									
										
										
										
											2020-12-17 18:04:47 +08:00
										 |  |  | if sys.platform not in ('win32', 'vxworks'): | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |     import tty | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | import asyncio | 
					
						
							| 
									
										
										
										
											2016-10-05 19:32:49 -04:00
										 |  |  | from asyncio import coroutines | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | from asyncio import events | 
					
						
							| 
									
										
										
										
											2014-01-25 22:22:18 +01:00
										 |  |  | from asyncio import selector_events | 
					
						
							| 
									
										
										
										
											2023-09-12 03:31:15 +02:00
										 |  |  | from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests | 
					
						
							| 
									
										
										
										
											2017-12-11 10:04:40 -05:00
										 |  |  | from test.test_asyncio import utils as test_utils | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  | from test import support | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  | from test.support import socket_helper | 
					
						
							| 
									
										
										
										
											2020-05-28 06:10:27 +08:00
										 |  |  | from test.support import threading_helper | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  | from test.support import ALWAYS_EQ, LARGEST, SMALLEST | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 20:34:09 -07:00
										 |  |  | def tearDownModule(): | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |     asyncio._set_event_loop_policy(None) | 
					
						
							| 
									
										
										
										
											2018-06-01 20:34:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-14 01:35:56 +02:00
										 |  |  | def broken_unix_getsockname(): | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |     """Return True if the platform is Mac OS 10.4 or older.""" | 
					
						
							| 
									
										
										
										
											2018-09-14 01:35:56 +02:00
										 |  |  |     if sys.platform.startswith("aix"): | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  |     elif sys.platform != 'darwin': | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |         return False | 
					
						
							|  |  |  |     version = platform.mac_ver()[0] | 
					
						
							|  |  |  |     version = tuple(map(int, version.split('.'))) | 
					
						
							|  |  |  |     return version < (10, 5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 20:07:11 -05:00
										 |  |  | def _test_get_event_loop_new_process__sub_proc(): | 
					
						
							|  |  |  |     async def doit(): | 
					
						
							|  |  |  |         return 'hello' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-24 12:38:33 +00:00
										 |  |  |     with contextlib.closing(asyncio.new_event_loop()) as loop: | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |         asyncio.set_event_loop(loop) | 
					
						
							| 
									
										
										
										
											2025-03-24 12:38:33 +00:00
										 |  |  |         return loop.run_until_complete(doit()) | 
					
						
							| 
									
										
										
										
											2017-03-02 20:07:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-23 12:44:29 -05:00
										 |  |  | class CoroLike: | 
					
						
							|  |  |  |     def send(self, v): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def throw(self, *exc): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def close(self): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __await__(self): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | class MyBaseProto(asyncio.Protocol): | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |     connected = None | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     done = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, loop=None): | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         self.transport = None | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'INITIAL' | 
					
						
							|  |  |  |         self.nbytes = 0 | 
					
						
							|  |  |  |         if loop is not None: | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |             self.connected = loop.create_future() | 
					
						
							|  |  |  |             self.done = loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |     def _assert_state(self, *expected): | 
					
						
							|  |  |  |         if self.state not in expected: | 
					
						
							|  |  |  |             raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def connection_made(self, transport): | 
					
						
							|  |  |  |         self.transport = transport | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIAL') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CONNECTED' | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         if self.connected: | 
					
						
							|  |  |  |             self.connected.set_result(None) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def data_received(self, data): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.nbytes += len(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def eof_received(self): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'EOF' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connection_lost(self, exc): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED', 'EOF') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CLOSED' | 
					
						
							|  |  |  |         if self.done: | 
					
						
							|  |  |  |             self.done.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | class MyProto(MyBaseProto): | 
					
						
							|  |  |  |     def connection_made(self, transport): | 
					
						
							|  |  |  |         super().connection_made(transport) | 
					
						
							|  |  |  |         transport.write(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | class MyDatagramProto(asyncio.DatagramProtocol): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     done = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, loop=None): | 
					
						
							|  |  |  |         self.state = 'INITIAL' | 
					
						
							|  |  |  |         self.nbytes = 0 | 
					
						
							|  |  |  |         if loop is not None: | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |             self.done = loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |     def _assert_state(self, expected): | 
					
						
							|  |  |  |         if self.state != expected: | 
					
						
							|  |  |  |             raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def connection_made(self, transport): | 
					
						
							|  |  |  |         self.transport = transport | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIAL') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'INITIALIZED' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def datagram_received(self, data, addr): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIALIZED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.nbytes += len(data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-15 16:51:48 -08:00
										 |  |  |     def error_received(self, exc): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIALIZED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def connection_lost(self, exc): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIALIZED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CLOSED' | 
					
						
							|  |  |  |         if self.done: | 
					
						
							|  |  |  |             self.done.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | class MyReadPipeProto(asyncio.Protocol): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     done = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, loop=None): | 
					
						
							|  |  |  |         self.state = ['INITIAL'] | 
					
						
							|  |  |  |         self.nbytes = 0 | 
					
						
							|  |  |  |         self.transport = None | 
					
						
							|  |  |  |         if loop is not None: | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |             self.done = loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |     def _assert_state(self, expected): | 
					
						
							|  |  |  |         if self.state != expected: | 
					
						
							|  |  |  |             raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def connection_made(self, transport): | 
					
						
							|  |  |  |         self.transport = transport | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state(['INITIAL']) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state.append('CONNECTED') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def data_received(self, data): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state(['INITIAL', 'CONNECTED']) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.nbytes += len(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def eof_received(self): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state(['INITIAL', 'CONNECTED']) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state.append('EOF') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connection_lost(self, exc): | 
					
						
							| 
									
										
										
										
											2014-01-10 13:30:04 -08:00
										 |  |  |         if 'EOF' not in self.state: | 
					
						
							|  |  |  |             self.state.append('EOF')  # It is okay if EOF is missed. | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state(['INITIAL', 'CONNECTED', 'EOF']) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state.append('CLOSED') | 
					
						
							|  |  |  |         if self.done: | 
					
						
							|  |  |  |             self.done.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | class MyWritePipeProto(asyncio.BaseProtocol): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     done = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, loop=None): | 
					
						
							|  |  |  |         self.state = 'INITIAL' | 
					
						
							|  |  |  |         self.transport = None | 
					
						
							|  |  |  |         if loop is not None: | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |             self.done = loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |     def _assert_state(self, expected): | 
					
						
							|  |  |  |         if self.state != expected: | 
					
						
							|  |  |  |             raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def connection_made(self, transport): | 
					
						
							|  |  |  |         self.transport = transport | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIAL') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CONNECTED' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connection_lost(self, exc): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CLOSED' | 
					
						
							|  |  |  |         if self.done: | 
					
						
							|  |  |  |             self.done.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | class MySubprocessProtocol(asyncio.SubprocessProtocol): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, loop): | 
					
						
							|  |  |  |         self.state = 'INITIAL' | 
					
						
							|  |  |  |         self.transport = None | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |         self.connected = loop.create_future() | 
					
						
							|  |  |  |         self.completed = loop.create_future() | 
					
						
							|  |  |  |         self.disconnects = {fd: loop.create_future() for fd in range(3)} | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.data = {1: b'', 2: b''} | 
					
						
							|  |  |  |         self.returncode = None | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         self.got_data = {1: asyncio.Event(), | 
					
						
							|  |  |  |                          2: asyncio.Event()} | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |     def _assert_state(self, expected): | 
					
						
							|  |  |  |         if self.state != expected: | 
					
						
							|  |  |  |             raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def connection_made(self, transport): | 
					
						
							|  |  |  |         self.transport = transport | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('INITIAL') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CONNECTED' | 
					
						
							|  |  |  |         self.connected.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connection_lost(self, exc): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.state = 'CLOSED' | 
					
						
							|  |  |  |         self.completed.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def pipe_data_received(self, fd, data): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.data[fd] += data | 
					
						
							|  |  |  |         self.got_data[fd].set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def pipe_connection_lost(self, fd, exc): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         if exc: | 
					
						
							|  |  |  |             self.disconnects[fd].set_exception(exc) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.disconnects[fd].set_result(exc) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def process_exited(self): | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |         self._assert_state('CONNECTED') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.returncode = self.transport.get_returncode() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EventLoopTestsMixin: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         super().setUp() | 
					
						
							|  |  |  |         self.loop = self.create_event_loop() | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |         self.set_event_loop(self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         # just in case if we have transport close callbacks | 
					
						
							| 
									
										
										
										
											2014-12-04 23:07:47 +01:00
										 |  |  |         if not self.loop.is_closed(): | 
					
						
							|  |  |  |             test_utils.run_briefly(self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-02 00:25:39 +02:00
										 |  |  |         self.doCleanups() | 
					
						
							|  |  |  |         support.gc_collect() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         super().tearDown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_run_until_complete_nesting(self): | 
					
						
							| 
									
										
										
										
											2019-05-16 17:52:10 +03:00
										 |  |  |         async def coro1(): | 
					
						
							|  |  |  |             await asyncio.sleep(0) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 17:52:10 +03:00
										 |  |  |         async def coro2(): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             self.assertTrue(self.loop.is_running()) | 
					
						
							|  |  |  |             self.loop.run_until_complete(coro1()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-07 15:23:01 +02:00
										 |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |             RuntimeWarning, | 
					
						
							|  |  |  |             r"coroutine \S+ was never awaited" | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             self.assertRaises( | 
					
						
							|  |  |  |                 RuntimeError, self.loop.run_until_complete, coro2()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Note: because of the default Windows timing granularity of | 
					
						
							|  |  |  |     # 15.6 msec, we use fairly long sleep times here (~100 msec). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_run_until_complete(self): | 
					
						
							| 
									
										
										
										
											2023-09-29 13:49:30 +02:00
										 |  |  |         delay = 0.100 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         t0 = self.loop.time() | 
					
						
							| 
									
										
										
										
											2023-09-29 13:49:30 +02:00
										 |  |  |         self.loop.run_until_complete(asyncio.sleep(delay)) | 
					
						
							|  |  |  |         dt = self.loop.time() - t0 | 
					
						
							|  |  |  |         self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_run_until_complete_stopped(self): | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         async def cb(): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             self.loop.stop() | 
					
						
							| 
									
										
										
										
											2018-10-02 13:53:06 -04:00
										 |  |  |             await asyncio.sleep(0.1) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         task = cb() | 
					
						
							|  |  |  |         self.assertRaises(RuntimeError, | 
					
						
							|  |  |  |                           self.loop.run_until_complete, task) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_call_later(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.call_later(0.1, callback, 'hello world') | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         self.assertEqual(results, ['hello world']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_call_soon(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def callback(arg1, arg2): | 
					
						
							|  |  |  |             results.append((arg1, arg2)) | 
					
						
							|  |  |  |             self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.call_soon(callback, 'hello', 'world') | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         self.assertEqual(results, [('hello', 'world')]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_call_soon_threadsafe(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  |         lock = threading.Lock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             if len(results) >= 2: | 
					
						
							|  |  |  |                 self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def run_in_thread(): | 
					
						
							|  |  |  |             self.loop.call_soon_threadsafe(callback, 'hello') | 
					
						
							|  |  |  |             lock.release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         lock.acquire() | 
					
						
							|  |  |  |         t = threading.Thread(target=run_in_thread) | 
					
						
							|  |  |  |         t.start() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with lock: | 
					
						
							|  |  |  |             self.loop.call_soon(callback, 'world') | 
					
						
							|  |  |  |             self.loop.run_forever() | 
					
						
							|  |  |  |         t.join() | 
					
						
							|  |  |  |         self.assertEqual(results, ['hello', 'world']) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 18:05:11 +05:30
										 |  |  |     def test_call_soon_threadsafe_handle_block_check_cancelled(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         callback_started = threading.Event() | 
					
						
							|  |  |  |         callback_finished = threading.Event() | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             callback_started.set() | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |             callback_finished.set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def run_in_thread(): | 
					
						
							|  |  |  |             handle = self.loop.call_soon_threadsafe(callback, 'hello') | 
					
						
							|  |  |  |             self.assertIsInstance(handle, events._ThreadSafeHandle) | 
					
						
							|  |  |  |             callback_started.wait() | 
					
						
							|  |  |  |             # callback started so it should block checking for cancellation | 
					
						
							|  |  |  |             # until it finishes | 
					
						
							|  |  |  |             self.assertFalse(handle.cancelled()) | 
					
						
							|  |  |  |             self.assertTrue(callback_finished.is_set()) | 
					
						
							|  |  |  |             self.loop.call_soon_threadsafe(self.loop.stop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         t = threading.Thread(target=run_in_thread) | 
					
						
							|  |  |  |         t.start() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         t.join() | 
					
						
							|  |  |  |         self.assertEqual(results, ['hello']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_call_soon_threadsafe_handle_block_cancellation(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         callback_started = threading.Event() | 
					
						
							|  |  |  |         callback_finished = threading.Event() | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             callback_started.set() | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             time.sleep(1) | 
					
						
							|  |  |  |             callback_finished.set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def run_in_thread(): | 
					
						
							|  |  |  |             handle = self.loop.call_soon_threadsafe(callback, 'hello') | 
					
						
							|  |  |  |             self.assertIsInstance(handle, events._ThreadSafeHandle) | 
					
						
							|  |  |  |             callback_started.wait() | 
					
						
							|  |  |  |             # callback started so it cannot be cancelled from other thread until | 
					
						
							|  |  |  |             # it finishes | 
					
						
							|  |  |  |             handle.cancel() | 
					
						
							|  |  |  |             self.assertTrue(callback_finished.is_set()) | 
					
						
							|  |  |  |             self.loop.call_soon_threadsafe(self.loop.stop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         t = threading.Thread(target=run_in_thread) | 
					
						
							|  |  |  |         t.start() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         t.join() | 
					
						
							|  |  |  |         self.assertEqual(results, ['hello']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_call_soon_threadsafe_handle_cancel_same_thread(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  |         callback_started = threading.Event() | 
					
						
							|  |  |  |         callback_finished = threading.Event() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fut = concurrent.futures.Future() | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             callback_started.set() | 
					
						
							|  |  |  |             handle = fut.result() | 
					
						
							|  |  |  |             handle.cancel() | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             callback_finished.set() | 
					
						
							|  |  |  |             self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def run_in_thread(): | 
					
						
							|  |  |  |             handle = self.loop.call_soon_threadsafe(callback, 'hello') | 
					
						
							|  |  |  |             fut.set_result(handle) | 
					
						
							|  |  |  |             self.assertIsInstance(handle, events._ThreadSafeHandle) | 
					
						
							|  |  |  |             callback_started.wait() | 
					
						
							|  |  |  |             # callback cancels itself from same thread so it has no effect | 
					
						
							|  |  |  |             # it runs to completion | 
					
						
							|  |  |  |             self.assertTrue(handle.cancelled()) | 
					
						
							|  |  |  |             self.assertTrue(callback_finished.is_set()) | 
					
						
							|  |  |  |             self.loop.call_soon_threadsafe(self.loop.stop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         t = threading.Thread(target=run_in_thread) | 
					
						
							|  |  |  |         t.start() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         t.join() | 
					
						
							|  |  |  |         self.assertEqual(results, ['hello']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_call_soon_threadsafe_handle_cancel_other_thread(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  |         ev = threading.Event() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         callback_finished = threading.Event() | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             callback_finished.set() | 
					
						
							|  |  |  |             self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def run_in_thread(): | 
					
						
							|  |  |  |             handle = self.loop.call_soon_threadsafe(callback, 'hello') | 
					
						
							|  |  |  |             # handle can be cancelled from other thread if not started yet | 
					
						
							|  |  |  |             self.assertIsInstance(handle, events._ThreadSafeHandle) | 
					
						
							|  |  |  |             handle.cancel() | 
					
						
							|  |  |  |             self.assertTrue(handle.cancelled()) | 
					
						
							|  |  |  |             self.assertFalse(callback_finished.is_set()) | 
					
						
							|  |  |  |             ev.set() | 
					
						
							|  |  |  |             self.loop.call_soon_threadsafe(self.loop.stop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # block the main loop until the callback is added and cancelled in the | 
					
						
							|  |  |  |         # other thread | 
					
						
							|  |  |  |         self.loop.call_soon(ev.wait) | 
					
						
							|  |  |  |         t = threading.Thread(target=run_in_thread) | 
					
						
							|  |  |  |         t.start() | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         t.join() | 
					
						
							|  |  |  |         self.assertEqual(results, []) | 
					
						
							|  |  |  |         self.assertFalse(callback_finished.is_set()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_call_soon_threadsafe_same_thread(self): | 
					
						
							|  |  |  |         results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def callback(arg): | 
					
						
							|  |  |  |             results.append(arg) | 
					
						
							|  |  |  |             if len(results) >= 2: | 
					
						
							|  |  |  |                 self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.call_soon_threadsafe(callback, 'hello') | 
					
						
							|  |  |  |         self.loop.call_soon(callback, 'world') | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         self.assertEqual(results, ['hello', 'world']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_run_in_executor(self): | 
					
						
							|  |  |  |         def run(arg): | 
					
						
							|  |  |  |             return (arg, threading.get_ident()) | 
					
						
							|  |  |  |         f2 = self.loop.run_in_executor(None, run, 'yo') | 
					
						
							|  |  |  |         res, thread_id = self.loop.run_until_complete(f2) | 
					
						
							|  |  |  |         self.assertEqual(res, 'yo') | 
					
						
							|  |  |  |         self.assertNotEqual(thread_id, threading.get_ident()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 17:10:20 -04:00
										 |  |  |     def test_run_in_executor_cancel(self): | 
					
						
							|  |  |  |         called = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def patched_call_soon(*args): | 
					
						
							|  |  |  |             nonlocal called | 
					
						
							|  |  |  |             called = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def run(): | 
					
						
							|  |  |  |             time.sleep(0.05) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f2 = self.loop.run_in_executor(None, run) | 
					
						
							|  |  |  |         f2.cancel() | 
					
						
							| 
									
										
										
										
											2020-04-01 22:46:44 -04:00
										 |  |  |         self.loop.run_until_complete( | 
					
						
							|  |  |  |                 self.loop.shutdown_default_executor()) | 
					
						
							| 
									
										
										
										
											2018-05-28 17:10:20 -04:00
										 |  |  |         self.loop.close() | 
					
						
							|  |  |  |         self.loop.call_soon = patched_call_soon | 
					
						
							|  |  |  |         self.loop.call_soon_threadsafe = patched_call_soon | 
					
						
							|  |  |  |         time.sleep(0.4) | 
					
						
							|  |  |  |         self.assertFalse(called) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_reader_callback(self): | 
					
						
							| 
									
										
										
										
											2017-11-28 21:33:20 +01:00
										 |  |  |         r, w = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         r.setblocking(False) | 
					
						
							|  |  |  |         bytes_read = bytearray() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def reader(): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 data = r.recv(1024) | 
					
						
							|  |  |  |             except BlockingIOError: | 
					
						
							|  |  |  |                 # Spurious readiness notifications are possible | 
					
						
							|  |  |  |                 # at least on Linux -- see man select. | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             if data: | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |                 bytes_read.extend(data) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.assertTrue(self.loop.remove_reader(r.fileno())) | 
					
						
							|  |  |  |                 r.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.add_reader(r.fileno(), reader) | 
					
						
							|  |  |  |         self.loop.call_soon(w.send, b'abc') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: len(bytes_read) >= 3) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.call_soon(w.send, b'def') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: len(bytes_read) >= 6) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.call_soon(w.close) | 
					
						
							|  |  |  |         self.loop.call_soon(self.loop.stop) | 
					
						
							|  |  |  |         self.loop.run_forever() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.assertEqual(bytes_read, b'abcdef') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_writer_callback(self): | 
					
						
							| 
									
										
										
										
											2017-11-28 21:33:20 +01:00
										 |  |  |         r, w = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         w.setblocking(False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         def writer(data): | 
					
						
							|  |  |  |             w.send(data) | 
					
						
							|  |  |  |             self.loop.stop() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         data = b'x' * 1024 | 
					
						
							|  |  |  |         self.loop.add_writer(w.fileno(), writer, data) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.run_forever() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertTrue(self.loop.remove_writer(w.fileno())) | 
					
						
							|  |  |  |         self.assertFalse(self.loop.remove_writer(w.fileno())) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         w.close() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         read = r.recv(len(data) * 2) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         r.close() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.assertEqual(read, data) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipUnless(hasattr(signal, 'SIGKILL'), 'No SIGKILL') | 
					
						
							|  |  |  |     def test_add_signal_handler(self): | 
					
						
							|  |  |  |         caught = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def my_handler(): | 
					
						
							|  |  |  |             nonlocal caught | 
					
						
							|  |  |  |             caught += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check error behavior first. | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             TypeError, self.loop.add_signal_handler, 'boom', my_handler) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             TypeError, self.loop.remove_signal_handler, 'boom') | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, self.loop.add_signal_handler, signal.NSIG+1, | 
					
						
							|  |  |  |             my_handler) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, self.loop.remove_signal_handler, signal.NSIG+1) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, self.loop.add_signal_handler, 0, my_handler) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, self.loop.remove_signal_handler, 0) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, self.loop.add_signal_handler, -1, my_handler) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, self.loop.remove_signal_handler, -1) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             RuntimeError, self.loop.add_signal_handler, signal.SIGKILL, | 
					
						
							|  |  |  |             my_handler) | 
					
						
							|  |  |  |         # Removing SIGKILL doesn't raise, since we don't call signal(). | 
					
						
							|  |  |  |         self.assertFalse(self.loop.remove_signal_handler(signal.SIGKILL)) | 
					
						
							|  |  |  |         # Now set a handler and handle it. | 
					
						
							|  |  |  |         self.loop.add_signal_handler(signal.SIGINT, my_handler) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         os.kill(os.getpid(), signal.SIGINT) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: caught) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         # Removing it should restore the default handler. | 
					
						
							|  |  |  |         self.assertTrue(self.loop.remove_signal_handler(signal.SIGINT)) | 
					
						
							|  |  |  |         self.assertEqual(signal.getsignal(signal.SIGINT), | 
					
						
							|  |  |  |                          signal.default_int_handler) | 
					
						
							|  |  |  |         # Removing again returns False. | 
					
						
							|  |  |  |         self.assertFalse(self.loop.remove_signal_handler(signal.SIGINT)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipUnless(hasattr(signal, 'SIGALRM'), 'No SIGALRM') | 
					
						
							| 
									
										
										
										
											2020-12-17 18:04:47 +08:00
										 |  |  |     @unittest.skipUnless(hasattr(signal, 'setitimer'), | 
					
						
							|  |  |  |                          'need signal.setitimer()') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_signal_handling_while_selecting(self): | 
					
						
							|  |  |  |         # Test with a signal actually arriving during a select() call. | 
					
						
							|  |  |  |         caught = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def my_handler(): | 
					
						
							|  |  |  |             nonlocal caught | 
					
						
							|  |  |  |             caught += 1 | 
					
						
							|  |  |  |             self.loop.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.add_signal_handler(signal.SIGALRM, my_handler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         signal.setitimer(signal.ITIMER_REAL, 0.01, 0)  # Send SIGALRM once. | 
					
						
							| 
									
										
										
										
											2018-12-29 01:40:21 +00:00
										 |  |  |         self.loop.call_later(60, self.loop.stop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         self.assertEqual(caught, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipUnless(hasattr(signal, 'SIGALRM'), 'No SIGALRM') | 
					
						
							| 
									
										
										
										
											2020-12-17 18:04:47 +08:00
										 |  |  |     @unittest.skipUnless(hasattr(signal, 'setitimer'), | 
					
						
							|  |  |  |                          'need signal.setitimer()') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_signal_handling_args(self): | 
					
						
							|  |  |  |         some_args = (42,) | 
					
						
							|  |  |  |         caught = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def my_handler(*args): | 
					
						
							|  |  |  |             nonlocal caught | 
					
						
							|  |  |  |             caught += 1 | 
					
						
							|  |  |  |             self.assertEqual(args, some_args) | 
					
						
							| 
									
										
										
										
											2018-12-29 01:40:21 +00:00
										 |  |  |             self.loop.stop() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.loop.add_signal_handler(signal.SIGALRM, my_handler, *some_args) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-18 15:15:56 -07:00
										 |  |  |         signal.setitimer(signal.ITIMER_REAL, 0.1, 0)  # Send SIGALRM once. | 
					
						
							| 
									
										
										
										
											2018-12-29 01:40:21 +00:00
										 |  |  |         self.loop.call_later(60, self.loop.stop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  |         self.assertEqual(caught, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 18:32:03 +01:00
										 |  |  |     def _basetest_create_connection(self, connection_fut, check_sockname=True): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         tr, pr = self.loop.run_until_complete(connection_fut) | 
					
						
							|  |  |  |         self.assertIsInstance(tr, asyncio.Transport) | 
					
						
							|  |  |  |         self.assertIsInstance(pr, asyncio.Protocol) | 
					
						
							| 
									
										
										
										
											2014-07-08 23:57:31 +02:00
										 |  |  |         self.assertIs(pr.transport, tr) | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |         if check_sockname: | 
					
						
							|  |  |  |             self.assertIsNotNone(tr.get_extra_info('sockname')) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         self.loop.run_until_complete(pr.done) | 
					
						
							|  |  |  |         self.assertGreater(pr.nbytes, 0) | 
					
						
							|  |  |  |         tr.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_create_connection(self): | 
					
						
							|  |  |  |         with test_utils.run_test_server() as httpd: | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |             conn_fut = self.loop.create_connection( | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |                 lambda: MyProto(loop=self.loop), *httpd.address) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |             self._basetest_create_connection(conn_fut) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @socket_helper.skip_unless_bind_unix_socket | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def test_create_unix_connection(self): | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |         # Issue #20682: On Mac OS X Tiger, getsockname() returns a | 
					
						
							|  |  |  |         # zero-length address for UNIX socket. | 
					
						
							| 
									
										
										
										
											2018-09-14 01:35:56 +02:00
										 |  |  |         check_sockname = not broken_unix_getsockname() | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         with test_utils.run_test_unix_server() as httpd: | 
					
						
							|  |  |  |             conn_fut = self.loop.create_unix_connection( | 
					
						
							|  |  |  |                 lambda: MyProto(loop=self.loop), httpd.address) | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |             self._basetest_create_connection(conn_fut, check_sockname) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |     def check_ssl_extra_info(self, client, check_sockname=True, | 
					
						
							|  |  |  |                              peername=None, peercert={}): | 
					
						
							|  |  |  |         if check_sockname: | 
					
						
							|  |  |  |             self.assertIsNotNone(client.get_extra_info('sockname')) | 
					
						
							|  |  |  |         if peername: | 
					
						
							|  |  |  |             self.assertEqual(peername, | 
					
						
							|  |  |  |                              client.get_extra_info('peername')) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.assertIsNotNone(client.get_extra_info('peername')) | 
					
						
							|  |  |  |         self.assertEqual(peercert, | 
					
						
							|  |  |  |                          client.get_extra_info('peercert')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # test SSL cipher | 
					
						
							|  |  |  |         cipher = client.get_extra_info('cipher') | 
					
						
							|  |  |  |         self.assertIsInstance(cipher, tuple) | 
					
						
							|  |  |  |         self.assertEqual(len(cipher), 3, cipher) | 
					
						
							|  |  |  |         self.assertIsInstance(cipher[0], str) | 
					
						
							|  |  |  |         self.assertIsInstance(cipher[1], str) | 
					
						
							|  |  |  |         self.assertIsInstance(cipher[2], int) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # test SSL object | 
					
						
							|  |  |  |         sslobj = client.get_extra_info('ssl_object') | 
					
						
							|  |  |  |         self.assertIsNotNone(sslobj) | 
					
						
							|  |  |  |         self.assertEqual(sslobj.compression(), | 
					
						
							|  |  |  |                          client.get_extra_info('compression')) | 
					
						
							|  |  |  |         self.assertEqual(sslobj.cipher(), | 
					
						
							|  |  |  |                          client.get_extra_info('cipher')) | 
					
						
							|  |  |  |         self.assertEqual(sslobj.getpeercert(), | 
					
						
							|  |  |  |                          client.get_extra_info('peercert')) | 
					
						
							| 
									
										
										
										
											2015-09-21 22:20:19 +02:00
										 |  |  |         self.assertEqual(sslobj.compression(), | 
					
						
							|  |  |  |                          client.get_extra_info('compression')) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |     def _basetest_create_ssl_connection(self, connection_fut, | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |                                         check_sockname=True, | 
					
						
							|  |  |  |                                         peername=None): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         tr, pr = self.loop.run_until_complete(connection_fut) | 
					
						
							|  |  |  |         self.assertIsInstance(tr, asyncio.Transport) | 
					
						
							|  |  |  |         self.assertIsInstance(pr, asyncio.Protocol) | 
					
						
							|  |  |  |         self.assertTrue('ssl' in tr.__class__.__name__.lower()) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |         self.check_ssl_extra_info(tr, check_sockname, peername) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         self.loop.run_until_complete(pr.done) | 
					
						
							|  |  |  |         self.assertGreater(pr.nbytes, 0) | 
					
						
							|  |  |  |         tr.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  |     def _test_create_ssl_connection(self, httpd, create_connection, | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |                                     check_sockname=True, peername=None): | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  |         conn_fut = create_connection(ssl=test_utils.dummy_ssl_context()) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |         self._basetest_create_ssl_connection(conn_fut, check_sockname, | 
					
						
							|  |  |  |                                              peername) | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 14:16:31 +01:00
										 |  |  |         # ssl.Purpose was introduced in Python 3.4 | 
					
						
							|  |  |  |         if hasattr(ssl, 'Purpose'): | 
					
						
							|  |  |  |             def _dummy_ssl_create_context(purpose=ssl.Purpose.SERVER_AUTH, *, | 
					
						
							|  |  |  |                                           cafile=None, capath=None, | 
					
						
							|  |  |  |                                           cadata=None): | 
					
						
							|  |  |  |                 """
 | 
					
						
							|  |  |  |                 A ssl.create_default_context() replacement that doesn't enable | 
					
						
							|  |  |  |                 cert validation. | 
					
						
							|  |  |  |                 """
 | 
					
						
							|  |  |  |                 self.assertEqual(purpose, ssl.Purpose.SERVER_AUTH) | 
					
						
							|  |  |  |                 return test_utils.dummy_ssl_context() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # With ssl=True, ssl.create_default_context() should be called | 
					
						
							|  |  |  |             with mock.patch('ssl.create_default_context', | 
					
						
							|  |  |  |                             side_effect=_dummy_ssl_create_context) as m: | 
					
						
							|  |  |  |                 conn_fut = create_connection(ssl=True) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |                 self._basetest_create_ssl_connection(conn_fut, check_sockname, | 
					
						
							|  |  |  |                                                      peername) | 
					
						
							| 
									
										
										
										
											2014-11-20 14:16:31 +01:00
										 |  |  |                 self.assertEqual(m.call_count, 1) | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # With the real ssl.create_default_context(), certificate | 
					
						
							|  |  |  |         # validation will fail | 
					
						
							|  |  |  |         with self.assertRaises(ssl.SSLError) as cm: | 
					
						
							|  |  |  |             conn_fut = create_connection(ssl=True) | 
					
						
							| 
									
										
										
										
											2014-11-20 14:19:23 +01:00
										 |  |  |             # Ignore the "SSL handshake failed" log in debug mode | 
					
						
							|  |  |  |             with test_utils.disable_logger(): | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |                 self._basetest_create_ssl_connection(conn_fut, check_sockname, | 
					
						
							|  |  |  |                                                      peername) | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(cm.exception.reason, 'CERTIFICATE_VERIFY_FAILED') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_create_ssl_connection(self): | 
					
						
							|  |  |  |         with test_utils.run_test_server(use_ssl=True) as httpd: | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  |             create_connection = functools.partial( | 
					
						
							|  |  |  |                 self.loop.create_connection, | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |                 lambda: MyProto(loop=self.loop), | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  |                 *httpd.address) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |             self._test_create_ssl_connection(httpd, create_connection, | 
					
						
							|  |  |  |                                              peername=httpd.address) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @socket_helper.skip_unless_bind_unix_socket | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_create_ssl_unix_connection(self): | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  |         # Issue #20682: On Mac OS X Tiger, getsockname() returns a | 
					
						
							|  |  |  |         # zero-length address for UNIX socket. | 
					
						
							| 
									
										
										
										
											2018-09-14 01:35:56 +02:00
										 |  |  |         check_sockname = not broken_unix_getsockname() | 
					
						
							| 
									
										
										
										
											2014-02-19 18:10:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         with test_utils.run_test_unix_server(use_ssl=True) as httpd: | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  |             create_connection = functools.partial( | 
					
						
							|  |  |  |                 self.loop.create_unix_connection, | 
					
						
							|  |  |  |                 lambda: MyProto(loop=self.loop), httpd.address, | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |                 server_hostname='127.0.0.1') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 16:58:21 +02:00
										 |  |  |             self._test_create_ssl_connection(httpd, create_connection, | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |                                              check_sockname, | 
					
						
							|  |  |  |                                              peername=httpd.address) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_create_connection_local_addr(self): | 
					
						
							|  |  |  |         with test_utils.run_test_server() as httpd: | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |             port = socket_helper.find_unused_port() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             f = self.loop.create_connection( | 
					
						
							|  |  |  |                 lambda: MyProto(loop=self.loop), | 
					
						
							|  |  |  |                 *httpd.address, local_addr=(httpd.address[0], port)) | 
					
						
							|  |  |  |             tr, pr = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |             expected = pr.transport.get_extra_info('sockname')[1] | 
					
						
							|  |  |  |             self.assertEqual(port, expected) | 
					
						
							|  |  |  |             tr.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 01:58:03 +02:00
										 |  |  |     @socket_helper.skip_if_tcp_blackhole | 
					
						
							| 
									
										
										
										
											2023-01-04 13:30:26 +05:30
										 |  |  |     def test_create_connection_local_addr_skip_different_family(self): | 
					
						
							|  |  |  |         # See https://github.com/python/cpython/issues/86508 | 
					
						
							|  |  |  |         port1 = socket_helper.find_unused_port() | 
					
						
							|  |  |  |         port2 = socket_helper.find_unused_port() | 
					
						
							|  |  |  |         getaddrinfo_orig = self.loop.getaddrinfo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         async def getaddrinfo(host, port, *args, **kwargs): | 
					
						
							|  |  |  |             if port == port2: | 
					
						
							|  |  |  |                 return [(socket.AF_INET6, socket.SOCK_STREAM, 0, '', ('::1', 0, 0, 0)), | 
					
						
							|  |  |  |                         (socket.AF_INET, socket.SOCK_STREAM, 0, '', ('127.0.0.1', 0))] | 
					
						
							|  |  |  |             return await getaddrinfo_orig(host, port, *args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.getaddrinfo = getaddrinfo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f = self.loop.create_connection( | 
					
						
							|  |  |  |             lambda: MyProto(loop=self.loop), | 
					
						
							|  |  |  |             'localhost', port1, local_addr=('localhost', port2)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(OSError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(f) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 01:58:03 +02:00
										 |  |  |     @socket_helper.skip_if_tcp_blackhole | 
					
						
							| 
									
										
										
										
											2023-01-04 13:30:26 +05:30
										 |  |  |     def test_create_connection_local_addr_nomatch_family(self): | 
					
						
							|  |  |  |         # See https://github.com/python/cpython/issues/86508 | 
					
						
							|  |  |  |         port1 = socket_helper.find_unused_port() | 
					
						
							|  |  |  |         port2 = socket_helper.find_unused_port() | 
					
						
							|  |  |  |         getaddrinfo_orig = self.loop.getaddrinfo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         async def getaddrinfo(host, port, *args, **kwargs): | 
					
						
							|  |  |  |             if port == port2: | 
					
						
							|  |  |  |                 return [(socket.AF_INET6, socket.SOCK_STREAM, 0, '', ('::1', 0, 0, 0))] | 
					
						
							|  |  |  |             return await getaddrinfo_orig(host, port, *args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.getaddrinfo = getaddrinfo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f = self.loop.create_connection( | 
					
						
							|  |  |  |             lambda: MyProto(loop=self.loop), | 
					
						
							|  |  |  |             'localhost', port1, local_addr=('localhost', port2)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(OSError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(f) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_create_connection_local_addr_in_use(self): | 
					
						
							|  |  |  |         with test_utils.run_test_server() as httpd: | 
					
						
							|  |  |  |             f = self.loop.create_connection( | 
					
						
							|  |  |  |                 lambda: MyProto(loop=self.loop), | 
					
						
							|  |  |  |                 *httpd.address, local_addr=httpd.address) | 
					
						
							|  |  |  |             with self.assertRaises(OSError) as cm: | 
					
						
							|  |  |  |                 self.loop.run_until_complete(f) | 
					
						
							|  |  |  |             self.assertEqual(cm.exception.errno, errno.EADDRINUSE) | 
					
						
							|  |  |  |             self.assertIn(str(httpd.address), cm.exception.strerror) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |     def test_connect_accepted_socket(self, server_ssl=None, client_ssl=None): | 
					
						
							|  |  |  |         loop = self.loop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MyProto(MyBaseProto): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def connection_lost(self, exc): | 
					
						
							|  |  |  |                 super().connection_lost(exc) | 
					
						
							|  |  |  |                 loop.call_soon(loop.stop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def data_received(self, data): | 
					
						
							|  |  |  |                 super().data_received(data) | 
					
						
							|  |  |  |                 self.transport.write(expected_response) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-09 00:34:02 +02:00
										 |  |  |         lsock = socket.create_server(('127.0.0.1', 0), backlog=1) | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |         addr = lsock.getsockname() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         message = b'test data' | 
					
						
							| 
									
										
										
										
											2016-08-31 09:08:41 -07:00
										 |  |  |         response = None | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |         expected_response = b'roger' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def client(): | 
					
						
							| 
									
										
										
										
											2016-08-31 09:08:41 -07:00
										 |  |  |             nonlocal response | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 csock = socket.socket() | 
					
						
							|  |  |  |                 if client_ssl is not None: | 
					
						
							|  |  |  |                     csock = client_ssl.wrap_socket(csock) | 
					
						
							|  |  |  |                 csock.connect(addr) | 
					
						
							|  |  |  |                 csock.sendall(message) | 
					
						
							|  |  |  |                 response = csock.recv(99) | 
					
						
							|  |  |  |                 csock.close() | 
					
						
							|  |  |  |             except Exception as exc: | 
					
						
							|  |  |  |                 print( | 
					
						
							|  |  |  |                     "Failure in client thread in test_connect_accepted_socket", | 
					
						
							|  |  |  |                     exc) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         thread = threading.Thread(target=client, daemon=True) | 
					
						
							|  |  |  |         thread.start() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         conn, _ = lsock.accept() | 
					
						
							|  |  |  |         proto = MyProto(loop=loop) | 
					
						
							|  |  |  |         proto.loop = loop | 
					
						
							| 
									
										
										
										
											2016-11-09 15:47:00 -05:00
										 |  |  |         loop.run_until_complete( | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |             loop.connect_accepted_socket( | 
					
						
							| 
									
										
										
										
											2016-11-09 15:47:00 -05:00
										 |  |  |                 (lambda: proto), conn, ssl=server_ssl)) | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |         loop.run_forever() | 
					
						
							| 
									
										
										
										
											2016-09-09 14:26:31 -07:00
										 |  |  |         proto.transport.close() | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |         lsock.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-28 06:10:27 +08:00
										 |  |  |         threading_helper.join_thread(thread) | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  |         self.assertFalse(thread.is_alive()) | 
					
						
							|  |  |  |         self.assertEqual(proto.state, 'CLOSED') | 
					
						
							|  |  |  |         self.assertEqual(proto.nbytes, len(message)) | 
					
						
							|  |  |  |         self.assertEqual(response, expected_response) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_ssl_connect_accepted_socket(self): | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |         server_context = test_utils.simple_server_sslcontext() | 
					
						
							|  |  |  |         client_context = test_utils.simple_client_sslcontext() | 
					
						
							| 
									
										
										
										
											2016-07-12 18:23:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.test_connect_accepted_socket(server_context, client_context) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 20:24:43 +02:00
										 |  |  |     def test_connect_accepted_socket_ssl_timeout_for_plain_socket(self): | 
					
						
							|  |  |  |         sock = socket.socket() | 
					
						
							|  |  |  |         self.addCleanup(sock.close) | 
					
						
							|  |  |  |         coro = self.loop.connect_accepted_socket( | 
					
						
							| 
									
										
										
										
											2019-12-10 20:32:59 +01:00
										 |  |  |             MyProto, sock, ssl_handshake_timeout=support.LOOPBACK_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2017-12-20 20:24:43 +02:00
										 |  |  |         with self.assertRaisesRegex( | 
					
						
							|  |  |  |                 ValueError, | 
					
						
							|  |  |  |                 'ssl_handshake_timeout is only meaningful with ssl'): | 
					
						
							|  |  |  |             self.loop.run_until_complete(coro) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |     @mock.patch('asyncio.base_events.socket') | 
					
						
							|  |  |  |     def create_server_multiple_hosts(self, family, hosts, mock_sock): | 
					
						
							| 
									
										
										
										
											2019-05-16 17:52:10 +03:00
										 |  |  |         async def getaddrinfo(host, port, *args, **kw): | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |             if family == socket.AF_INET: | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |                 return [(family, socket.SOCK_STREAM, 6, '', (host, port))] | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |                 return [(family, socket.SOCK_STREAM, 6, '', (host, port, 0, 0))] | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def getaddrinfo_task(*args, **kwds): | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |             return self.loop.create_task(getaddrinfo(*args, **kwds)) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |         unique_hosts = set(hosts) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |         if family == socket.AF_INET: | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |             mock_sock.socket().getsockbyname.side_effect = [ | 
					
						
							|  |  |  |                 (host, 80) for host in unique_hosts] | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |             mock_sock.socket().getsockbyname.side_effect = [ | 
					
						
							|  |  |  |                 (host, 80, 0, 0) for host in unique_hosts] | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |         self.loop.getaddrinfo = getaddrinfo_task | 
					
						
							|  |  |  |         self.loop._start_serving = mock.Mock() | 
					
						
							| 
									
										
										
										
											2015-09-21 22:28:44 +02:00
										 |  |  |         self.loop._stop_serving = mock.Mock() | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  |         f = self.loop.create_server(lambda: MyProto(self.loop), hosts, 80) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.addCleanup(server.close) | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |         server_hosts = {sock.getsockbyname()[0] for sock in server.sockets} | 
					
						
							|  |  |  |         self.assertEqual(server_hosts, unique_hosts) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_create_server_multiple_hosts_ipv4(self): | 
					
						
							|  |  |  |         self.create_server_multiple_hosts(socket.AF_INET, | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |                                           ['1.2.3.4', '5.6.7.8', '1.2.3.4']) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_create_server_multiple_hosts_ipv6(self): | 
					
						
							| 
									
										
										
										
											2016-03-02 11:17:01 -05:00
										 |  |  |         self.create_server_multiple_hosts(socket.AF_INET6, | 
					
						
							|  |  |  |                                           ['::1', '::2', '::1']) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_create_server(self): | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         proto = MyProto(self.loop) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertEqual(len(server.sockets), 1) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         host, port = sock.getsockname() | 
					
						
							|  |  |  |         self.assertEqual(host, '0.0.0.0') | 
					
						
							|  |  |  |         client = socket.socket() | 
					
						
							|  |  |  |         client.connect(('127.0.0.1', port)) | 
					
						
							| 
									
										
										
										
											2013-10-20 01:51:25 +02:00
										 |  |  |         client.sendall(b'xxx') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes > 0) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(3, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							|  |  |  |         self.assertIsNotNone(proto.transport.get_extra_info('sockname')) | 
					
						
							|  |  |  |         self.assertEqual('127.0.0.1', | 
					
						
							|  |  |  |                          proto.transport.get_extra_info('peername')[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the client socket must be closed after to avoid ECONNRESET upon | 
					
						
							|  |  |  |         # recv()/send() on the serving socket | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close server | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 10:07:55 +05:30
										 |  |  |     def test_create_server_trsock(self): | 
					
						
							|  |  |  |         proto = MyProto(self.loop) | 
					
						
							|  |  |  |         f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertEqual(len(server.sockets), 1) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         self.assertIsInstance(sock, asyncio.trsock.TransportSocket) | 
					
						
							|  |  |  |         host, port = sock.getsockname() | 
					
						
							|  |  |  |         self.assertEqual(host, '0.0.0.0') | 
					
						
							|  |  |  |         dup = sock.dup() | 
					
						
							|  |  |  |         self.addCleanup(dup.close) | 
					
						
							|  |  |  |         self.assertIsInstance(dup, socket.socket) | 
					
						
							|  |  |  |         self.assertFalse(sock.get_inheritable()) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             sock.settimeout(1) | 
					
						
							|  |  |  |         sock.settimeout(0) | 
					
						
							|  |  |  |         self.assertEqual(sock.gettimeout(), 0) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             sock.setblocking(True) | 
					
						
							|  |  |  |         sock.setblocking(False) | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  |     @unittest.skipUnless(hasattr(socket, 'SO_REUSEPORT'), 'No SO_REUSEPORT') | 
					
						
							|  |  |  |     def test_create_server_reuse_port(self): | 
					
						
							|  |  |  |         proto = MyProto(self.loop) | 
					
						
							|  |  |  |         f = self.loop.create_server( | 
					
						
							|  |  |  |             lambda: proto, '0.0.0.0', 0) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertEqual(len(server.sockets), 1) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         self.assertFalse( | 
					
						
							|  |  |  |             sock.getsockopt( | 
					
						
							|  |  |  |                 socket.SOL_SOCKET, socket.SO_REUSEPORT)) | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test_utils.run_briefly(self.loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         proto = MyProto(self.loop) | 
					
						
							|  |  |  |         f = self.loop.create_server( | 
					
						
							|  |  |  |             lambda: proto, '0.0.0.0', 0, reuse_port=True) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertEqual(len(server.sockets), 1) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         self.assertTrue( | 
					
						
							|  |  |  |             sock.getsockopt( | 
					
						
							|  |  |  |                 socket.SOL_SOCKET, socket.SO_REUSEPORT)) | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def _make_unix_server(self, factory, **kwargs): | 
					
						
							|  |  |  |         path = test_utils.gen_unix_socket_path() | 
					
						
							|  |  |  |         self.addCleanup(lambda: os.path.exists(path) and os.unlink(path)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f = self.loop.create_unix_server(factory, path, **kwargs) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return server, path | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @socket_helper.skip_unless_bind_unix_socket | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def test_create_unix_server(self): | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         server, path = self._make_unix_server(lambda: proto) | 
					
						
							|  |  |  |         self.assertEqual(len(server.sockets), 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         client = socket.socket(socket.AF_UNIX) | 
					
						
							|  |  |  |         client.connect(path) | 
					
						
							|  |  |  |         client.sendall(b'xxx') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes > 0) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         self.assertEqual(3, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the client socket must be closed after to avoid ECONNRESET upon | 
					
						
							|  |  |  |         # recv()/send() on the serving socket | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close server | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-07 11:18:54 +02:00
										 |  |  |     @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') | 
					
						
							|  |  |  |     def test_create_unix_server_path_socket_error(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         sock = socket.socket() | 
					
						
							|  |  |  |         with sock: | 
					
						
							|  |  |  |             f = self.loop.create_unix_server(lambda: proto, '/test', sock=sock) | 
					
						
							|  |  |  |             with self.assertRaisesRegex(ValueError, | 
					
						
							|  |  |  |                                         'path and sock can not be specified ' | 
					
						
							|  |  |  |                                         'at the same time'): | 
					
						
							| 
									
										
										
										
											2014-07-11 11:58:33 +02:00
										 |  |  |                 self.loop.run_until_complete(f) | 
					
						
							| 
									
										
										
										
											2014-04-07 11:18:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def _create_ssl_context(self, certfile, keyfile=None): | 
					
						
							| 
									
										
										
										
											2017-09-15 20:27:30 +02:00
										 |  |  |         sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         sslcontext.options |= ssl.OP_NO_SSLv2 | 
					
						
							|  |  |  |         sslcontext.load_cert_chain(certfile, keyfile) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         return sslcontext | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def _make_ssl_server(self, factory, certfile, keyfile=None): | 
					
						
							|  |  |  |         sslcontext = self._create_ssl_context(certfile, keyfile) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         f = self.loop.create_server(factory, '127.0.0.1', 0, ssl=sslcontext) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         host, port = sock.getsockname() | 
					
						
							|  |  |  |         self.assertEqual(host, '127.0.0.1') | 
					
						
							|  |  |  |         return server, host, port | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def _make_ssl_unix_server(self, factory, certfile, keyfile=None): | 
					
						
							|  |  |  |         sslcontext = self._create_ssl_context(certfile, keyfile) | 
					
						
							|  |  |  |         return self._make_unix_server(factory, ssl=sslcontext) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_create_server_ssl(self): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, host, port = self._make_ssl_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.ONLYCERT, test_utils.ONLYKEY) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         f_c = self.loop.create_connection(MyBaseProto, host, port, | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |                                           ssl=test_utils.dummy_ssl_context()) | 
					
						
							|  |  |  |         client, pr = self.loop.run_until_complete(f_c) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         client.write(b'xxx') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes > 0) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(3, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |         self.check_ssl_extra_info(client, peername=(host, port)) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the client socket must be closed after to avoid ECONNRESET upon | 
					
						
							|  |  |  |         # recv()/send() on the serving socket | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # stop serving | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @socket_helper.skip_unless_bind_unix_socket | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def test_create_unix_server_ssl(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, path = self._make_ssl_unix_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.ONLYCERT, test_utils.ONLYKEY) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         f_c = self.loop.create_unix_connection( | 
					
						
							|  |  |  |             MyBaseProto, path, ssl=test_utils.dummy_ssl_context(), | 
					
						
							|  |  |  |             server_hostname='') | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         client, pr = self.loop.run_until_complete(f_c) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         client.write(b'xxx') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes > 0) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         self.assertEqual(3, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # the client socket must be closed after to avoid ECONNRESET upon | 
					
						
							|  |  |  |         # recv()/send() on the serving socket | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # stop serving | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_create_server_ssl_verify_failed(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, host, port = self._make_ssl_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.SIGNED_CERTFILE) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 20:27:30 +02:00
										 |  |  |         sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         sslcontext_client.options |= ssl.OP_NO_SSLv2 | 
					
						
							|  |  |  |         sslcontext_client.verify_mode = ssl.CERT_REQUIRED | 
					
						
							|  |  |  |         if hasattr(sslcontext_client, 'check_hostname'): | 
					
						
							|  |  |  |             sslcontext_client.check_hostname = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         # no CA loaded | 
					
						
							|  |  |  |         f_c = self.loop.create_connection(MyProto, host, port, | 
					
						
							|  |  |  |                                           ssl=sslcontext_client) | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  |         with mock.patch.object(self.loop, 'call_exception_handler'): | 
					
						
							|  |  |  |             with test_utils.disable_logger(): | 
					
						
							|  |  |  |                 with self.assertRaisesRegex(ssl.SSLError, | 
					
						
							| 
									
										
										
										
											2016-05-13 15:42:39 -04:00
										 |  |  |                                             '(?i)certificate.verify.failed'): | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  |                     self.loop.run_until_complete(f_c) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # execute the loop to log the connection error | 
					
						
							|  |  |  |             test_utils.run_briefly(self.loop) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         self.assertIsNone(proto.transport) | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @socket_helper.skip_unless_bind_unix_socket | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def test_create_unix_server_ssl_verify_failed(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, path = self._make_ssl_unix_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.SIGNED_CERTFILE) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 20:27:30 +02:00
										 |  |  |         sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         sslcontext_client.options |= ssl.OP_NO_SSLv2 | 
					
						
							|  |  |  |         sslcontext_client.verify_mode = ssl.CERT_REQUIRED | 
					
						
							|  |  |  |         if hasattr(sslcontext_client, 'check_hostname'): | 
					
						
							|  |  |  |             sslcontext_client.check_hostname = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no CA loaded | 
					
						
							|  |  |  |         f_c = self.loop.create_unix_connection(MyProto, path, | 
					
						
							|  |  |  |                                                ssl=sslcontext_client, | 
					
						
							|  |  |  |                                                server_hostname='invalid') | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  |         with mock.patch.object(self.loop, 'call_exception_handler'): | 
					
						
							|  |  |  |             with test_utils.disable_logger(): | 
					
						
							|  |  |  |                 with self.assertRaisesRegex(ssl.SSLError, | 
					
						
							| 
									
										
										
										
											2016-05-13 15:42:39 -04:00
										 |  |  |                                             '(?i)certificate.verify.failed'): | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  |                     self.loop.run_until_complete(f_c) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # execute the loop to log the connection error | 
					
						
							|  |  |  |             test_utils.run_briefly(self.loop) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         self.assertIsNone(proto.transport) | 
					
						
							|  |  |  |         server.close() | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_create_server_ssl_match_failed(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, host, port = self._make_ssl_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.SIGNED_CERTFILE) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 20:27:30 +02:00
										 |  |  |         sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         sslcontext_client.options |= ssl.OP_NO_SSLv2 | 
					
						
							|  |  |  |         sslcontext_client.verify_mode = ssl.CERT_REQUIRED | 
					
						
							|  |  |  |         sslcontext_client.load_verify_locations( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             cafile=test_utils.SIGNING_CA) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         if hasattr(sslcontext_client, 'check_hostname'): | 
					
						
							|  |  |  |             sslcontext_client.check_hostname = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # incorrect server_hostname | 
					
						
							|  |  |  |         f_c = self.loop.create_connection(MyProto, host, port, | 
					
						
							|  |  |  |                                           ssl=sslcontext_client) | 
					
						
							| 
									
										
										
										
											2024-03-21 14:16:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Allow for flexible libssl error messages. | 
					
						
							|  |  |  |         regex = re.compile(r"""(
 | 
					
						
							|  |  |  |             IP address mismatch, certificate is not valid for '127.0.0.1'   # OpenSSL | 
					
						
							|  |  |  |             | | 
					
						
							|  |  |  |             CERTIFICATE_VERIFY_FAILED                                       # AWS-LC | 
					
						
							|  |  |  |         )""", re.X)
 | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  |         with mock.patch.object(self.loop, 'call_exception_handler'): | 
					
						
							|  |  |  |             with test_utils.disable_logger(): | 
					
						
							| 
									
										
										
										
											2024-03-21 14:16:36 -05:00
										 |  |  |                 with self.assertRaisesRegex(ssl.CertificateError, regex): | 
					
						
							| 
									
										
										
										
											2015-01-29 14:15:19 +01:00
										 |  |  |                     self.loop.run_until_complete(f_c) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							| 
									
										
										
										
											2018-01-27 15:51:38 +01:00
										 |  |  |         # transport is None because TLS ALERT aborted the handshake | 
					
						
							|  |  |  |         self.assertIsNone(proto.transport) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @socket_helper.skip_unless_bind_unix_socket | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     def test_create_unix_server_ssl_verified(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, path = self._make_ssl_unix_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.SIGNED_CERTFILE) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 20:27:30 +02:00
										 |  |  |         sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         sslcontext_client.options |= ssl.OP_NO_SSLv2 | 
					
						
							|  |  |  |         sslcontext_client.verify_mode = ssl.CERT_REQUIRED | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |         sslcontext_client.load_verify_locations(cafile=test_utils.SIGNING_CA) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         if hasattr(sslcontext_client, 'check_hostname'): | 
					
						
							|  |  |  |             sslcontext_client.check_hostname = True | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         # Connection succeeds with correct CA and server hostname. | 
					
						
							|  |  |  |         f_c = self.loop.create_unix_connection(MyProto, path, | 
					
						
							|  |  |  |                                                ssl=sslcontext_client, | 
					
						
							|  |  |  |                                                server_hostname='localhost') | 
					
						
							|  |  |  |         client, pr = self.loop.run_until_complete(f_c) | 
					
						
							| 
									
										
										
										
											2020-10-19 20:18:57 -05:00
										 |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  |         server.close() | 
					
						
							| 
									
										
										
										
											2015-01-14 00:19:09 +01:00
										 |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |     @unittest.skipIf(ssl is None, 'No ssl module') | 
					
						
							|  |  |  |     def test_create_server_ssl_verified(self): | 
					
						
							|  |  |  |         proto = MyProto(loop=self.loop) | 
					
						
							|  |  |  |         server, host, port = self._make_ssl_server( | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |             lambda: proto, test_utils.SIGNED_CERTFILE) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 20:27:30 +02:00
										 |  |  |         sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         sslcontext_client.options |= ssl.OP_NO_SSLv2 | 
					
						
							|  |  |  |         sslcontext_client.verify_mode = ssl.CERT_REQUIRED | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |         sslcontext_client.load_verify_locations(cafile=test_utils.SIGNING_CA) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         if hasattr(sslcontext_client, 'check_hostname'): | 
					
						
							|  |  |  |             sslcontext_client.check_hostname = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Connection succeeds with correct CA and server hostname. | 
					
						
							|  |  |  |         f_c = self.loop.create_connection(MyProto, host, port, | 
					
						
							|  |  |  |                                           ssl=sslcontext_client, | 
					
						
							|  |  |  |                                           server_hostname='localhost') | 
					
						
							|  |  |  |         client, pr = self.loop.run_until_complete(f_c) | 
					
						
							| 
									
										
										
										
											2020-10-19 20:18:57 -05:00
										 |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |         # extra info is available | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |         self.check_ssl_extra_info(client, peername=(host, port), | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |                                   peercert=test_utils.PEERCERT) | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-06 00:23:13 +01:00
										 |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  |         server.close() | 
					
						
							| 
									
										
										
										
											2015-01-14 00:19:09 +01:00
										 |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_create_server_sock(self): | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |         proto = self.loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class TestMyProto(MyProto): | 
					
						
							|  |  |  |             def connection_made(self, transport): | 
					
						
							|  |  |  |                 super().connection_made(transport) | 
					
						
							|  |  |  |                 proto.set_result(self) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-09 00:34:02 +02:00
										 |  |  |         sock_ob = socket.create_server(('0.0.0.0', 0)) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         f = self.loop.create_server(TestMyProto, sock=sock_ob) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							| 
									
										
										
										
											2019-05-27 15:57:20 +02:00
										 |  |  |         self.assertEqual(sock.fileno(), sock_ob.fileno()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         host, port = sock.getsockname() | 
					
						
							|  |  |  |         self.assertEqual(host, '0.0.0.0') | 
					
						
							|  |  |  |         client = socket.socket() | 
					
						
							|  |  |  |         client.connect(('127.0.0.1', port)) | 
					
						
							|  |  |  |         client.send(b'xxx') | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_create_server_addr_in_use(self): | 
					
						
							| 
									
										
										
										
											2019-04-09 00:34:02 +02:00
										 |  |  |         sock_ob = socket.create_server(('0.0.0.0', 0)) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         f = self.loop.create_server(MyProto, sock=sock_ob) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         host, port = sock.getsockname() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f = self.loop.create_server(MyProto, host=host, port=port) | 
					
						
							|  |  |  |         with self.assertRaises(OSError) as cm: | 
					
						
							|  |  |  |             self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertEqual(cm.exception.errno, errno.EADDRINUSE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |     @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 not supported or enabled') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_create_server_dual_stack(self): | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |         f_proto = self.loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class TestMyProto(MyProto): | 
					
						
							|  |  |  |             def connection_made(self, transport): | 
					
						
							|  |  |  |                 super().connection_made(transport) | 
					
						
							|  |  |  |                 f_proto.set_result(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try_count = 0 | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2020-04-25 10:06:29 +03:00
										 |  |  |                 port = socket_helper.find_unused_port() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |                 f = self.loop.create_server(TestMyProto, host=None, port=port) | 
					
						
							|  |  |  |                 server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |             except OSError as ex: | 
					
						
							|  |  |  |                 if ex.errno == errno.EADDRINUSE: | 
					
						
							|  |  |  |                     try_count += 1 | 
					
						
							|  |  |  |                     self.assertGreaterEqual(5, try_count) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     raise | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         client = socket.socket() | 
					
						
							|  |  |  |         client.connect(('127.0.0.1', port)) | 
					
						
							|  |  |  |         client.send(b'xxx') | 
					
						
							|  |  |  |         proto = self.loop.run_until_complete(f_proto) | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |         f_proto = self.loop.create_future() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         client = socket.socket(socket.AF_INET6) | 
					
						
							|  |  |  |         client.connect(('::1', port)) | 
					
						
							|  |  |  |         client.send(b'xxx') | 
					
						
							|  |  |  |         proto = self.loop.run_until_complete(f_proto) | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 01:58:03 +02:00
										 |  |  |     @socket_helper.skip_if_tcp_blackhole | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_server_close(self): | 
					
						
							|  |  |  |         f = self.loop.create_server(MyProto, '0.0.0.0', 0) | 
					
						
							|  |  |  |         server = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         sock = server.sockets[0] | 
					
						
							|  |  |  |         host, port = sock.getsockname() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         client = socket.socket() | 
					
						
							|  |  |  |         client.connect(('127.0.0.1', port)) | 
					
						
							|  |  |  |         client.send(b'xxx') | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         server.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         client = socket.socket() | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ConnectionRefusedError, client.connect, ('127.0.0.1', port)) | 
					
						
							|  |  |  |         client.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 08:21:30 +02:00
										 |  |  |     def _test_create_datagram_endpoint(self, local_addr, family): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         class TestMyDatagramProto(MyDatagramProto): | 
					
						
							|  |  |  |             def __init__(inner_self): | 
					
						
							|  |  |  |                 super().__init__(loop=self.loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def datagram_received(self, data, addr): | 
					
						
							|  |  |  |                 super().datagram_received(data, addr) | 
					
						
							|  |  |  |                 self.transport.sendto(b'resp:'+data, addr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         coro = self.loop.create_datagram_endpoint( | 
					
						
							| 
									
										
										
										
											2020-05-18 08:21:30 +02:00
										 |  |  |             TestMyDatagramProto, local_addr=local_addr, family=family) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         s_transport, server = self.loop.run_until_complete(coro) | 
					
						
							| 
									
										
										
										
											2020-05-18 08:21:30 +02:00
										 |  |  |         sockname = s_transport.get_extra_info('sockname') | 
					
						
							|  |  |  |         host, port = socket.getnameinfo( | 
					
						
							|  |  |  |             sockname, socket.NI_NUMERICHOST|socket.NI_NUMERICSERV) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 23:57:31 +02:00
										 |  |  |         self.assertIsInstance(s_transport, asyncio.Transport) | 
					
						
							|  |  |  |         self.assertIsInstance(server, TestMyDatagramProto) | 
					
						
							|  |  |  |         self.assertEqual('INITIALIZED', server.state) | 
					
						
							|  |  |  |         self.assertIs(server.transport, s_transport) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         coro = self.loop.create_datagram_endpoint( | 
					
						
							|  |  |  |             lambda: MyDatagramProto(loop=self.loop), | 
					
						
							|  |  |  |             remote_addr=(host, port)) | 
					
						
							|  |  |  |         transport, client = self.loop.run_until_complete(coro) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 23:57:31 +02:00
										 |  |  |         self.assertIsInstance(transport, asyncio.Transport) | 
					
						
							|  |  |  |         self.assertIsInstance(client, MyDatagramProto) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual('INITIALIZED', client.state) | 
					
						
							| 
									
										
										
										
											2014-07-08 23:57:31 +02:00
										 |  |  |         self.assertIs(client.transport, transport) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         transport.sendto(b'xxx') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: server.nbytes) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(3, server.nbytes) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: client.nbytes) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # received | 
					
						
							|  |  |  |         self.assertEqual(8, client.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							|  |  |  |         self.assertIsNotNone(transport.get_extra_info('sockname')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(client.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', client.state) | 
					
						
							|  |  |  |         server.transport.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 08:21:30 +02:00
										 |  |  |     def test_create_datagram_endpoint(self): | 
					
						
							|  |  |  |         self._test_create_datagram_endpoint(('127.0.0.1', 0), socket.AF_INET) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 00:56:47 -07:00
										 |  |  |     @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 not supported or enabled') | 
					
						
							| 
									
										
										
										
											2020-05-18 08:21:30 +02:00
										 |  |  |     def test_create_datagram_endpoint_ipv6(self): | 
					
						
							|  |  |  |         self._test_create_datagram_endpoint(('::1', 0), socket.AF_INET6) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  |     def test_create_datagram_endpoint_sock(self): | 
					
						
							|  |  |  |         sock = None | 
					
						
							|  |  |  |         local_address = ('127.0.0.1', 0) | 
					
						
							|  |  |  |         infos = self.loop.run_until_complete( | 
					
						
							|  |  |  |             self.loop.getaddrinfo( | 
					
						
							|  |  |  |                 *local_address, type=socket.SOCK_DGRAM)) | 
					
						
							|  |  |  |         for family, type, proto, cname, address in infos: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 sock = socket.socket(family=family, type=type, proto=proto) | 
					
						
							|  |  |  |                 sock.setblocking(False) | 
					
						
							|  |  |  |                 sock.bind(address) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-12-20 12:23:05 +02:00
										 |  |  |             self.fail('Can not create socket.') | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 15:47:00 -05:00
										 |  |  |         f = self.loop.create_datagram_endpoint( | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  |             lambda: MyDatagramProto(loop=self.loop), sock=sock) | 
					
						
							|  |  |  |         tr, pr = self.loop.run_until_complete(f) | 
					
						
							|  |  |  |         self.assertIsInstance(tr, asyncio.Transport) | 
					
						
							|  |  |  |         self.assertIsInstance(pr, MyDatagramProto) | 
					
						
							|  |  |  |         tr.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(pr.done) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-23 11:39:35 -04:00
										 |  |  |     def test_datagram_send_to_non_listening_address(self): | 
					
						
							|  |  |  |         # see: | 
					
						
							|  |  |  |         #   https://github.com/python/cpython/issues/91227 | 
					
						
							|  |  |  |         #   https://github.com/python/cpython/issues/88906 | 
					
						
							|  |  |  |         #   https://bugs.python.org/issue47071 | 
					
						
							|  |  |  |         #   https://bugs.python.org/issue44743 | 
					
						
							|  |  |  |         # The Proactor event loop would fail to receive datagram messages after | 
					
						
							|  |  |  |         # sending a message to an address that wasn't listening. | 
					
						
							|  |  |  |         loop = self.loop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Protocol(asyncio.DatagramProtocol): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             _received_datagram = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def datagram_received(self, data, addr): | 
					
						
							|  |  |  |                 self._received_datagram.set_result(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             async def wait_for_datagram_received(self): | 
					
						
							|  |  |  |                 self._received_datagram = loop.create_future() | 
					
						
							|  |  |  |                 result = await asyncio.wait_for(self._received_datagram, 10) | 
					
						
							|  |  |  |                 self._received_datagram = None | 
					
						
							|  |  |  |                 return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def create_socket(): | 
					
						
							|  |  |  |             sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | 
					
						
							|  |  |  |             sock.setblocking(False) | 
					
						
							|  |  |  |             sock.bind(('127.0.0.1', 0)) | 
					
						
							|  |  |  |             return sock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         socket_1 = create_socket() | 
					
						
							|  |  |  |         transport_1, protocol_1 = loop.run_until_complete( | 
					
						
							|  |  |  |             loop.create_datagram_endpoint(Protocol, sock=socket_1) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         addr_1 = socket_1.getsockname() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         socket_2 = create_socket() | 
					
						
							|  |  |  |         transport_2, protocol_2 = loop.run_until_complete( | 
					
						
							|  |  |  |             loop.create_datagram_endpoint(Protocol, sock=socket_2) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         addr_2 = socket_2.getsockname() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # creating and immediately closing this to try to get an address that | 
					
						
							|  |  |  |         # is not listening | 
					
						
							|  |  |  |         socket_3 = create_socket() | 
					
						
							|  |  |  |         transport_3, protocol_3 = loop.run_until_complete( | 
					
						
							|  |  |  |             loop.create_datagram_endpoint(Protocol, sock=socket_3) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         addr_3 = socket_3.getsockname() | 
					
						
							|  |  |  |         transport_3.abort() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transport_1.sendto(b'a', addr=addr_2) | 
					
						
							|  |  |  |         self.assertEqual(loop.run_until_complete( | 
					
						
							|  |  |  |             protocol_2.wait_for_datagram_received() | 
					
						
							|  |  |  |         ), b'a') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transport_2.sendto(b'b', addr=addr_1) | 
					
						
							|  |  |  |         self.assertEqual(loop.run_until_complete( | 
					
						
							|  |  |  |             protocol_1.wait_for_datagram_received() | 
					
						
							|  |  |  |         ), b'b') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # this should send to an address that isn't listening | 
					
						
							|  |  |  |         transport_1.sendto(b'c', addr=addr_3) | 
					
						
							|  |  |  |         loop.run_until_complete(asyncio.sleep(0)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # transport 1 should still be able to receive messages after sending to | 
					
						
							|  |  |  |         # an address that wasn't listening | 
					
						
							|  |  |  |         transport_2.sendto(b'd', addr=addr_1) | 
					
						
							|  |  |  |         self.assertEqual(loop.run_until_complete( | 
					
						
							|  |  |  |             protocol_1.wait_for_datagram_received() | 
					
						
							|  |  |  |         ), b'd') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transport_1.close() | 
					
						
							|  |  |  |         transport_2.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_internal_fds(self): | 
					
						
							|  |  |  |         loop = self.create_event_loop() | 
					
						
							| 
									
										
										
										
											2014-01-25 22:22:18 +01:00
										 |  |  |         if not isinstance(loop, selector_events.BaseSelectorEventLoop): | 
					
						
							| 
									
										
										
										
											2014-06-04 00:23:26 +02:00
										 |  |  |             loop.close() | 
					
						
							| 
									
										
										
										
											2013-12-08 00:44:27 -06:00
										 |  |  |             self.skipTest('loop is not a BaseSelectorEventLoop') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(1, loop._internal_fds) | 
					
						
							|  |  |  |         loop.close() | 
					
						
							|  |  |  |         self.assertEqual(0, loop._internal_fds) | 
					
						
							|  |  |  |         self.assertIsNone(loop._csock) | 
					
						
							|  |  |  |         self.assertIsNone(loop._ssock) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							|  |  |  |     def test_read_pipe(self): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         proto = MyReadPipeProto(loop=self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         rpipe, wpipe = os.pipe() | 
					
						
							|  |  |  |         pipeobj = io.open(rpipe, 'rb', 1024) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         async def connect(): | 
					
						
							|  |  |  |             t, p = await self.loop.connect_read_pipe( | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |                 lambda: proto, pipeobj) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             self.assertIs(p, proto) | 
					
						
							|  |  |  |             self.assertIs(t, proto.transport) | 
					
						
							|  |  |  |             self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) | 
					
						
							|  |  |  |             self.assertEqual(0, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_until_complete(connect()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.write(wpipe, b'1') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes >= 1) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(1, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.write(wpipe, b'2345') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) | 
					
						
							|  |  |  |         self.assertEqual(5, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.close(wpipe) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							|  |  |  |         self.assertIsNotNone(proto.transport.get_extra_info('pipe')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 16:04:43 -04:00
										 |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							|  |  |  |     def test_unclosed_pipe_transport(self): | 
					
						
							|  |  |  |         # This test reproduces the issue #314 on GitHub | 
					
						
							|  |  |  |         loop = self.create_event_loop() | 
					
						
							|  |  |  |         read_proto = MyReadPipeProto(loop=loop) | 
					
						
							|  |  |  |         write_proto = MyWritePipeProto(loop=loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rpipe, wpipe = os.pipe() | 
					
						
							|  |  |  |         rpipeobj = io.open(rpipe, 'rb', 1024) | 
					
						
							| 
									
										
										
										
											2021-04-04 09:01:23 +09:00
										 |  |  |         wpipeobj = io.open(wpipe, 'w', 1024, encoding="utf-8") | 
					
						
							| 
									
										
										
										
											2016-05-13 16:04:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         async def connect(): | 
					
						
							|  |  |  |             read_transport, _ = await loop.connect_read_pipe( | 
					
						
							| 
									
										
										
										
											2016-05-13 16:04:43 -04:00
										 |  |  |                 lambda: read_proto, rpipeobj) | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             write_transport, _ = await loop.connect_write_pipe( | 
					
						
							| 
									
										
										
										
											2016-05-13 16:04:43 -04:00
										 |  |  |                 lambda: write_proto, wpipeobj) | 
					
						
							|  |  |  |             return read_transport, write_transport | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Run and close the loop without closing the transports | 
					
						
							|  |  |  |         read_transport, write_transport = loop.run_until_complete(connect()) | 
					
						
							|  |  |  |         loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # These 'repr' calls used to raise an AttributeError | 
					
						
							|  |  |  |         # See Issue #314 on GitHub | 
					
						
							|  |  |  |         self.assertIn('open', repr(read_transport)) | 
					
						
							|  |  |  |         self.assertIn('open', repr(write_transport)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Clean up (avoid ResourceWarning) | 
					
						
							|  |  |  |         rpipeobj.close() | 
					
						
							|  |  |  |         wpipeobj.close() | 
					
						
							|  |  |  |         read_transport._pipe = None | 
					
						
							|  |  |  |         write_transport._pipe = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 13:30:04 -08:00
										 |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							| 
									
										
										
										
											2020-12-17 18:04:47 +08:00
										 |  |  |     @unittest.skipUnless(hasattr(os, 'openpty'), 'need os.openpty()') | 
					
						
							| 
									
										
										
										
											2014-01-10 13:30:04 -08:00
										 |  |  |     def test_read_pty_output(self): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         proto = MyReadPipeProto(loop=self.loop) | 
					
						
							| 
									
										
										
										
											2014-01-10 13:30:04 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         master, slave = os.openpty() | 
					
						
							|  |  |  |         master_read_obj = io.open(master, 'rb', 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         async def connect(): | 
					
						
							|  |  |  |             t, p = await self.loop.connect_read_pipe(lambda: proto, | 
					
						
							|  |  |  |                                                      master_read_obj) | 
					
						
							| 
									
										
										
										
											2014-01-10 13:30:04 -08:00
										 |  |  |             self.assertIs(p, proto) | 
					
						
							|  |  |  |             self.assertIs(t, proto.transport) | 
					
						
							|  |  |  |             self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) | 
					
						
							|  |  |  |             self.assertEqual(0, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_until_complete(connect()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.write(slave, b'1') | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes) | 
					
						
							|  |  |  |         self.assertEqual(1, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.write(slave, b'2345') | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) | 
					
						
							|  |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) | 
					
						
							|  |  |  |         self.assertEqual(5, proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.close(slave) | 
					
						
							| 
									
										
										
										
											2018-03-27 17:16:49 -04:00
										 |  |  |         proto.transport.close() | 
					
						
							| 
									
										
										
										
											2014-01-10 13:30:04 -08:00
										 |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							|  |  |  |         self.assertIsNotNone(proto.transport.get_extra_info('pipe')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							|  |  |  |     def test_write_pipe(self): | 
					
						
							|  |  |  |         rpipe, wpipe = os.pipe() | 
					
						
							|  |  |  |         pipeobj = io.open(wpipe, 'wb', 1024) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         proto = MyWritePipeProto(loop=self.loop) | 
					
						
							|  |  |  |         connect = self.loop.connect_write_pipe(lambda: proto, pipeobj) | 
					
						
							|  |  |  |         transport, p = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIs(p, proto) | 
					
						
							|  |  |  |         self.assertIs(transport, proto.transport) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         transport.write(b'1') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         data = bytearray() | 
					
						
							|  |  |  |         def reader(data): | 
					
						
							|  |  |  |             chunk = os.read(rpipe, 1024) | 
					
						
							|  |  |  |             data += chunk | 
					
						
							|  |  |  |             return len(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: reader(data) >= 1) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(b'1', data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transport.write(b'2345') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: reader(data) >= 5) | 
					
						
							|  |  |  |         self.assertEqual(b'12345', data) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.close(rpipe) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							|  |  |  |         self.assertIsNotNone(proto.transport.get_extra_info('pipe')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							|  |  |  |     def test_write_pipe_disconnect_on_close(self): | 
					
						
							| 
									
										
										
										
											2017-11-28 21:33:20 +01:00
										 |  |  |         rsock, wsock = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2014-08-25 23:20:52 +02:00
										 |  |  |         rsock.setblocking(False) | 
					
						
							| 
									
										
										
										
											2013-10-21 21:28:45 -07:00
										 |  |  |         pipeobj = io.open(wsock.detach(), 'wb', 1024) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         proto = MyWritePipeProto(loop=self.loop) | 
					
						
							|  |  |  |         connect = self.loop.connect_write_pipe(lambda: proto, pipeobj) | 
					
						
							|  |  |  |         transport, p = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIs(p, proto) | 
					
						
							|  |  |  |         self.assertIs(transport, proto.transport) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transport.write(b'1') | 
					
						
							| 
									
										
										
										
											2013-10-21 21:28:45 -07:00
										 |  |  |         data = self.loop.run_until_complete(self.loop.sock_recv(rsock, 1024)) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(b'1', data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-21 21:28:45 -07:00
										 |  |  |         rsock.close() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							| 
									
										
										
										
											2020-12-17 18:04:47 +08:00
										 |  |  |     @unittest.skipUnless(hasattr(os, 'openpty'), 'need os.openpty()') | 
					
						
							| 
									
										
										
										
											2014-02-03 00:32:13 +01:00
										 |  |  |     # select, poll and kqueue don't support character devices (PTY) on Mac OS X | 
					
						
							|  |  |  |     # older than 10.6 (Snow Leopard) | 
					
						
							|  |  |  |     @support.requires_mac_ver(10, 6) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |     def test_write_pty(self): | 
					
						
							|  |  |  |         master, slave = os.openpty() | 
					
						
							|  |  |  |         slave_write_obj = io.open(slave, 'wb', 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         proto = MyWritePipeProto(loop=self.loop) | 
					
						
							|  |  |  |         connect = self.loop.connect_write_pipe(lambda: proto, slave_write_obj) | 
					
						
							|  |  |  |         transport, p = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIs(p, proto) | 
					
						
							|  |  |  |         self.assertIs(transport, proto.transport) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         transport.write(b'1') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         data = bytearray() | 
					
						
							|  |  |  |         def reader(data): | 
					
						
							|  |  |  |             chunk = os.read(master, 1024) | 
					
						
							|  |  |  |             data += chunk | 
					
						
							|  |  |  |             return len(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: reader(data) >= 1, | 
					
						
							| 
									
										
										
										
											2019-12-11 11:30:03 +01:00
										 |  |  |                              timeout=support.SHORT_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         self.assertEqual(b'1', data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transport.write(b'2345') | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: reader(data) >= 5, | 
					
						
							| 
									
										
										
										
											2019-12-11 11:30:03 +01:00
										 |  |  |                              timeout=support.SHORT_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2014-03-06 01:00:36 +01:00
										 |  |  |         self.assertEqual(b'12345', data) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.close(master) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # extra info is available | 
					
						
							|  |  |  |         self.assertIsNotNone(proto.transport.get_extra_info('pipe')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # close connection | 
					
						
							|  |  |  |         proto.transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |     @unittest.skipUnless(sys.platform != 'win32', | 
					
						
							|  |  |  |                          "Don't support pipes for Windows") | 
					
						
							| 
									
										
										
										
											2020-12-17 18:04:47 +08:00
										 |  |  |     @unittest.skipUnless(hasattr(os, 'openpty'), 'need os.openpty()') | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |     # select, poll and kqueue don't support character devices (PTY) on Mac OS X | 
					
						
							|  |  |  |     # older than 10.6 (Snow Leopard) | 
					
						
							|  |  |  |     @support.requires_mac_ver(10, 6) | 
					
						
							|  |  |  |     def test_bidirectional_pty(self): | 
					
						
							|  |  |  |         master, read_slave = os.openpty() | 
					
						
							|  |  |  |         write_slave = os.dup(read_slave) | 
					
						
							|  |  |  |         tty.setraw(read_slave) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         slave_read_obj = io.open(read_slave, 'rb', 0) | 
					
						
							|  |  |  |         read_proto = MyReadPipeProto(loop=self.loop) | 
					
						
							|  |  |  |         read_connect = self.loop.connect_read_pipe(lambda: read_proto, | 
					
						
							|  |  |  |                                                    slave_read_obj) | 
					
						
							|  |  |  |         read_transport, p = self.loop.run_until_complete(read_connect) | 
					
						
							|  |  |  |         self.assertIs(p, read_proto) | 
					
						
							|  |  |  |         self.assertIs(read_transport, read_proto.transport) | 
					
						
							|  |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], read_proto.state) | 
					
						
							|  |  |  |         self.assertEqual(0, read_proto.nbytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         slave_write_obj = io.open(write_slave, 'wb', 0) | 
					
						
							|  |  |  |         write_proto = MyWritePipeProto(loop=self.loop) | 
					
						
							|  |  |  |         write_connect = self.loop.connect_write_pipe(lambda: write_proto, | 
					
						
							|  |  |  |                                                      slave_write_obj) | 
					
						
							|  |  |  |         write_transport, p = self.loop.run_until_complete(write_connect) | 
					
						
							|  |  |  |         self.assertIs(p, write_proto) | 
					
						
							|  |  |  |         self.assertIs(write_transport, write_proto.transport) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', write_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         data = bytearray() | 
					
						
							|  |  |  |         def reader(data): | 
					
						
							|  |  |  |             chunk = os.read(master, 1024) | 
					
						
							|  |  |  |             data += chunk | 
					
						
							|  |  |  |             return len(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         write_transport.write(b'1') | 
					
						
							| 
									
										
										
										
											2019-12-11 11:30:03 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: reader(data) >= 1, | 
					
						
							|  |  |  |                              timeout=support.SHORT_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |         self.assertEqual(b'1', data) | 
					
						
							|  |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], read_proto.state) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', write_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.write(master, b'a') | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: read_proto.nbytes >= 1, | 
					
						
							| 
									
										
										
										
											2019-12-11 11:30:03 +01:00
										 |  |  |                              timeout=support.SHORT_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], read_proto.state) | 
					
						
							|  |  |  |         self.assertEqual(1, read_proto.nbytes) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', write_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         write_transport.write(b'2345') | 
					
						
							| 
									
										
										
										
											2019-12-11 11:30:03 +01:00
										 |  |  |         test_utils.run_until(self.loop, lambda: reader(data) >= 5, | 
					
						
							|  |  |  |                              timeout=support.SHORT_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |         self.assertEqual(b'12345', data) | 
					
						
							|  |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], read_proto.state) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', write_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.write(master, b'bcde') | 
					
						
							|  |  |  |         test_utils.run_until(self.loop, lambda: read_proto.nbytes >= 5, | 
					
						
							| 
									
										
										
										
											2019-12-11 11:30:03 +01:00
										 |  |  |                              timeout=support.SHORT_TIMEOUT) | 
					
						
							| 
									
										
										
										
											2016-08-31 09:40:18 -07:00
										 |  |  |         self.assertEqual(['INITIAL', 'CONNECTED'], read_proto.state) | 
					
						
							|  |  |  |         self.assertEqual(5, read_proto.nbytes) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', write_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         os.close(master) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         read_transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(read_proto.done) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], read_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         write_transport.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(write_proto.done) | 
					
						
							|  |  |  |         self.assertEqual('CLOSED', write_proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_prompt_cancellation(self): | 
					
						
							| 
									
										
										
										
											2017-11-28 21:33:20 +01:00
										 |  |  |         r, w = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         r.setblocking(False) | 
					
						
							| 
									
										
										
										
											2017-12-14 20:53:26 -05:00
										 |  |  |         f = self.loop.create_task(self.loop.sock_recv(r, 1)) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         ov = getattr(f, 'ov', None) | 
					
						
							| 
									
										
										
										
											2013-11-14 23:10:51 +02:00
										 |  |  |         if ov is not None: | 
					
						
							|  |  |  |             self.assertTrue(ov.pending) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         async def main(): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 self.loop.call_soon(f.cancel) | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |                 await f | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             except asyncio.CancelledError: | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |                 res = 'cancelled' | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 res = None | 
					
						
							|  |  |  |             finally: | 
					
						
							|  |  |  |                 self.loop.stop() | 
					
						
							|  |  |  |             return res | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |         t = self.loop.create_task(main()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.run_forever() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(t.result(), 'cancelled') | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         self.assertRaises(asyncio.CancelledError, f.result) | 
					
						
							| 
									
										
										
										
											2013-11-14 23:10:51 +02:00
										 |  |  |         if ov is not None: | 
					
						
							|  |  |  |             self.assertFalse(ov.pending) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop._stop_serving(r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         r.close() | 
					
						
							|  |  |  |         w.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:01:33 +01:00
										 |  |  |     def test_timeout_rounding(self): | 
					
						
							|  |  |  |         def _run_once(): | 
					
						
							|  |  |  |             self.loop._run_once_counter += 1 | 
					
						
							|  |  |  |             orig_run_once() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         orig_run_once = self.loop._run_once | 
					
						
							|  |  |  |         self.loop._run_once_counter = 0 | 
					
						
							|  |  |  |         self.loop._run_once = _run_once | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         async def wait(): | 
					
						
							| 
									
										
										
										
											2018-10-02 13:53:06 -04:00
										 |  |  |             await asyncio.sleep(1e-2) | 
					
						
							|  |  |  |             await asyncio.sleep(1e-4) | 
					
						
							|  |  |  |             await asyncio.sleep(1e-6) | 
					
						
							|  |  |  |             await asyncio.sleep(1e-8) | 
					
						
							|  |  |  |             await asyncio.sleep(1e-10) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:01:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_until_complete(wait()) | 
					
						
							| 
									
										
										
										
											2014-02-10 23:42:32 +01:00
										 |  |  |         # The ideal number of call is 12, but on some platforms, the selector | 
					
						
							| 
									
										
										
										
											2014-02-07 23:34:58 +01:00
										 |  |  |         # may sleep at little bit less than timeout depending on the resolution | 
					
						
							| 
									
										
										
										
											2014-02-10 23:42:32 +01:00
										 |  |  |         # of the clock used by the kernel. Tolerate a few useless calls on | 
					
						
							|  |  |  |         # these platforms. | 
					
						
							|  |  |  |         self.assertLessEqual(self.loop._run_once_counter, 20, | 
					
						
							|  |  |  |             {'clock_resolution': self.loop._clock_resolution, | 
					
						
							| 
									
										
										
										
											2014-02-10 11:47:50 +01:00
										 |  |  |              'selector': self.loop._selector.__class__.__name__}) | 
					
						
							| 
									
										
										
										
											2014-02-03 23:59:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 00:52:53 +01:00
										 |  |  |     def test_remove_fds_after_closing(self): | 
					
						
							|  |  |  |         loop = self.create_event_loop() | 
					
						
							|  |  |  |         callback = lambda: None | 
					
						
							| 
									
										
										
										
											2017-11-28 21:33:20 +01:00
										 |  |  |         r, w = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2014-03-06 00:52:53 +01:00
										 |  |  |         self.addCleanup(r.close) | 
					
						
							|  |  |  |         self.addCleanup(w.close) | 
					
						
							|  |  |  |         loop.add_reader(r, callback) | 
					
						
							|  |  |  |         loop.add_writer(w, callback) | 
					
						
							|  |  |  |         loop.close() | 
					
						
							|  |  |  |         self.assertFalse(loop.remove_reader(r)) | 
					
						
							|  |  |  |         self.assertFalse(loop.remove_writer(w)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_add_fds_after_closing(self): | 
					
						
							|  |  |  |         loop = self.create_event_loop() | 
					
						
							|  |  |  |         callback = lambda: None | 
					
						
							| 
									
										
										
										
											2017-11-28 21:33:20 +01:00
										 |  |  |         r, w = socket.socketpair() | 
					
						
							| 
									
										
										
										
											2014-03-06 00:52:53 +01:00
										 |  |  |         self.addCleanup(r.close) | 
					
						
							|  |  |  |         self.addCleanup(w.close) | 
					
						
							|  |  |  |         loop.close() | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             loop.add_reader(r, callback) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             loop.add_writer(w, callback) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-23 01:02:37 +02:00
										 |  |  |     def test_close_running_event_loop(self): | 
					
						
							| 
									
										
										
										
											2019-05-16 17:52:10 +03:00
										 |  |  |         async def close_loop(loop): | 
					
						
							| 
									
										
										
										
											2014-06-23 01:02:37 +02:00
										 |  |  |             self.loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         coro = close_loop(self.loop) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(coro) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-04 23:07:47 +01:00
										 |  |  |     def test_close(self): | 
					
						
							|  |  |  |         self.loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 17:52:10 +03:00
										 |  |  |         async def test(): | 
					
						
							| 
									
										
										
										
											2014-12-04 23:07:47 +01:00
										 |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         func = lambda: False | 
					
						
							|  |  |  |         coro = test() | 
					
						
							|  |  |  |         self.addCleanup(coro.close) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # operation blocked when the loop is closed | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.run_forever() | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							| 
									
										
										
										
											2019-09-11 16:07:37 +03:00
										 |  |  |             fut = self.loop.create_future() | 
					
						
							| 
									
										
										
										
											2014-12-04 23:07:47 +01:00
										 |  |  |             self.loop.run_until_complete(fut) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.call_soon(func) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.call_soon_threadsafe(func) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.call_later(1.0, func) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.call_at(self.loop.time() + .0, func) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.create_task(coro) | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             self.loop.add_signal_handler(signal.SIGTERM, func) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-23 23:03:27 +02:00
										 |  |  |         # run_in_executor test is tricky: the method is a coroutine, | 
					
						
							|  |  |  |         # but run_until_complete cannot be called on closed loop. | 
					
						
							|  |  |  |         # Thus iterate once explicitly. | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             it = self.loop.run_in_executor(None, func).__await__() | 
					
						
							|  |  |  |             next(it) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class SubprocessTestsMixin: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def check_terminated(self, returncode): | 
					
						
							|  |  |  |         if sys.platform == 'win32': | 
					
						
							|  |  |  |             self.assertIsInstance(returncode, int) | 
					
						
							| 
									
										
										
										
											2013-11-02 16:38:58 +00:00
										 |  |  |             # expect 1 but sometimes get 0 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.assertEqual(-signal.SIGTERM, returncode) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def check_killed(self, returncode): | 
					
						
							|  |  |  |         if sys.platform == 'win32': | 
					
						
							|  |  |  |             self.assertIsInstance(returncode, int) | 
					
						
							| 
									
										
										
										
											2013-11-02 16:38:58 +00:00
										 |  |  |             # expect 1 but sometimes get 0 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.assertEqual(-signal.SIGKILL, returncode) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_exec(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         stdin = transp.get_pipe_transport(0) | 
					
						
							|  |  |  |         stdin.write(b'Python The Winner') | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.got_data[1].wait()) | 
					
						
							|  |  |  |         with test_utils.disable_logger(): | 
					
						
							|  |  |  |             transp.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.check_killed(proto.returncode) | 
					
						
							|  |  |  |         self.assertEqual(b'Python The Winner', proto.data[1]) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_interactive(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							|  |  |  |         self.assertEqual('CONNECTED', proto.state) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         stdin = transp.get_pipe_transport(0) | 
					
						
							|  |  |  |         stdin.write(b'Python ') | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.got_data[1].wait()) | 
					
						
							|  |  |  |         proto.got_data[1].clear() | 
					
						
							|  |  |  |         self.assertEqual(b'Python ', proto.data[1]) | 
					
						
							| 
									
										
										
										
											2015-01-30 00:05:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         stdin.write(b'The Winner') | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.got_data[1].wait()) | 
					
						
							|  |  |  |         self.assertEqual(b'Python The Winner', proto.data[1]) | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         with test_utils.disable_logger(): | 
					
						
							|  |  |  |             transp.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.check_killed(proto.returncode) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_shell(self): | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         connect = self.loop.subprocess_shell( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         'echo Python') | 
					
						
							|  |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp.get_pipe_transport(0).close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.assertEqual(0, proto.returncode) | 
					
						
							|  |  |  |         self.assertTrue(all(f.done() for f in proto.disconnects.values())) | 
					
						
							|  |  |  |         self.assertEqual(proto.data[1].rstrip(b'\r\n'), b'Python') | 
					
						
							|  |  |  |         self.assertEqual(proto.data[2], b'') | 
					
						
							|  |  |  |         transp.close() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_exitcode(self): | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_shell( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         'exit 7', stdin=None, stdout=None, stderr=None) | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.assertEqual(7, proto.returncode) | 
					
						
							| 
									
										
										
										
											2015-01-15 00:04:21 +01:00
										 |  |  |         transp.close() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_close_after_finish(self): | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_shell( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         'exit 7', stdin=None, stdout=None, stderr=None) | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertIsNone(transp.get_pipe_transport(0)) | 
					
						
							|  |  |  |         self.assertIsNone(transp.get_pipe_transport(1)) | 
					
						
							|  |  |  |         self.assertIsNone(transp.get_pipe_transport(2)) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.assertEqual(7, proto.returncode) | 
					
						
							|  |  |  |         self.assertIsNone(transp.close()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_kill(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp.kill() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.check_killed(proto.returncode) | 
					
						
							|  |  |  |         transp.close() | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |     def test_subprocess_terminate(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog) | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp.terminate() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.check_terminated(proto.returncode) | 
					
						
							|  |  |  |         transp.close() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |     @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_send_signal(self): | 
					
						
							| 
									
										
										
										
											2017-07-25 19:19:09 +02:00
										 |  |  |         # bpo-31034: Make sure that we get the default signal handler (killing | 
					
						
							|  |  |  |         # the process). The parent process may have decided to ignore SIGHUP, | 
					
						
							|  |  |  |         # and signal handlers are inherited. | 
					
						
							|  |  |  |         old_handler = signal.signal(signal.SIGHUP, signal.SIG_DFL) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             prog = os.path.join(os.path.dirname(__file__), 'echo.py') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                             functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                             sys.executable, prog) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |             transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |             self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |             self.loop.run_until_complete(proto.connected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             transp.send_signal(signal.SIGHUP) | 
					
						
							|  |  |  |             self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |             self.assertEqual(-signal.SIGHUP, proto.returncode) | 
					
						
							|  |  |  |             transp.close() | 
					
						
							| 
									
										
										
										
											2017-07-25 19:19:09 +02:00
										 |  |  |         finally: | 
					
						
							|  |  |  |             signal.signal(signal.SIGHUP, old_handler) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_stderr(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo2.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         stdin = transp.get_pipe_transport(0) | 
					
						
							|  |  |  |         stdin.write(b'test') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp.close() | 
					
						
							|  |  |  |         self.assertEqual(b'OUT:test', proto.data[1]) | 
					
						
							| 
									
										
										
										
											2025-01-20 13:32:39 +02:00
										 |  |  |         self.assertStartsWith(proto.data[2], b'ERR:test') | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         self.assertEqual(0, proto.returncode) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_stderr_redirect_to_stdout(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo2.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog, stderr=subprocess.STDOUT) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         stdin = transp.get_pipe_transport(0) | 
					
						
							|  |  |  |         self.assertIsNotNone(transp.get_pipe_transport(1)) | 
					
						
							|  |  |  |         self.assertIsNone(transp.get_pipe_transport(2)) | 
					
						
							| 
									
										
										
										
											2019-09-10 07:55:07 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         stdin.write(b'test') | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							| 
									
										
										
										
											2025-01-20 13:32:39 +02:00
										 |  |  |         self.assertStartsWith(proto.data[1], b'OUT:testERR:test') | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         self.assertEqual(b'', proto.data[2]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         transp.close() | 
					
						
							|  |  |  |         self.assertEqual(0, proto.returncode) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_subprocess_close_client_stream(self): | 
					
						
							|  |  |  |         prog = os.path.join(os.path.dirname(__file__), 'echo3.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         connect = self.loop.subprocess_exec( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         sys.executable, prog) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							|  |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.connected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         stdin = transp.get_pipe_transport(0) | 
					
						
							|  |  |  |         stdout = transp.get_pipe_transport(1) | 
					
						
							|  |  |  |         stdin.write(b'test') | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.got_data[1].wait()) | 
					
						
							|  |  |  |         self.assertEqual(b'OUT:test', proto.data[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         stdout.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.disconnects[1]) | 
					
						
							|  |  |  |         stdin.write(b'xxx') | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.got_data[2].wait()) | 
					
						
							|  |  |  |         if sys.platform != 'win32': | 
					
						
							|  |  |  |             self.assertEqual(b'ERR:BrokenPipeError', proto.data[2]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # After closing the read-end of a pipe, writing to the | 
					
						
							|  |  |  |             # write-end using os.write() fails with errno==EINVAL and | 
					
						
							|  |  |  |             # GetLastError()==ERROR_INVALID_NAME on Windows!?!  (Using | 
					
						
							|  |  |  |             # WriteFile() we get ERROR_BROKEN_PIPE as expected.) | 
					
						
							|  |  |  |             self.assertEqual(b'ERR:OSError', proto.data[2]) | 
					
						
							|  |  |  |         with test_utils.disable_logger(): | 
					
						
							|  |  |  |             transp.close() | 
					
						
							|  |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.check_killed(proto.returncode) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2013-10-20 20:31:43 +02:00
										 |  |  |     def test_subprocess_wait_no_same_group(self): | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         # start the new process in a new session | 
					
						
							|  |  |  |         connect = self.loop.subprocess_shell( | 
					
						
							|  |  |  |                         functools.partial(MySubprocessProtocol, self.loop), | 
					
						
							|  |  |  |                         'exit 7', stdin=None, stdout=None, stderr=None, | 
					
						
							|  |  |  |                         start_new_session=True) | 
					
						
							| 
									
										
										
										
											2021-08-21 23:09:08 +03:00
										 |  |  |         transp, proto = self.loop.run_until_complete(connect) | 
					
						
							| 
									
										
										
										
											2014-02-26 11:31:55 +01:00
										 |  |  |         self.assertIsInstance(proto, MySubprocessProtocol) | 
					
						
							| 
									
										
										
										
											2013-10-20 20:31:43 +02:00
										 |  |  |         self.loop.run_until_complete(proto.completed) | 
					
						
							|  |  |  |         self.assertEqual(7, proto.returncode) | 
					
						
							| 
									
										
										
										
											2021-08-21 23:09:08 +03:00
										 |  |  |         transp.close() | 
					
						
							| 
									
										
										
										
											2013-10-20 20:31:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2014-01-29 14:35:15 -08:00
										 |  |  |     def test_subprocess_exec_invalid_args(self): | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |         async def connect(**kwds): | 
					
						
							|  |  |  |             await self.loop.subprocess_exec( | 
					
						
							| 
									
										
										
										
											2014-01-29 14:35:15 -08:00
										 |  |  |                 asyncio.SubprocessProtocol, | 
					
						
							|  |  |  |                 'pwd', **kwds) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(universal_newlines=True)) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(bufsize=4096)) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(shell=True)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-05 08:04:57 +08:00
										 |  |  |     @support.requires_subprocess() | 
					
						
							| 
									
										
										
										
											2014-01-29 14:35:15 -08:00
										 |  |  |     def test_subprocess_shell_invalid_args(self): | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         async def connect(cmd=None, **kwds): | 
					
						
							| 
									
										
										
										
											2014-01-29 14:35:15 -08:00
										 |  |  |             if not cmd: | 
					
						
							|  |  |  |                 cmd = 'pwd' | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             await self.loop.subprocess_shell( | 
					
						
							| 
									
										
										
										
											2014-01-29 14:35:15 -08:00
										 |  |  |                 asyncio.SubprocessProtocol, | 
					
						
							|  |  |  |                 cmd, **kwds) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(['ls', '-l'])) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(universal_newlines=True)) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(bufsize=4096)) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             self.loop.run_until_complete(connect(shell=False)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | if sys.platform == 'win32': | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-27 21:22:47 +02:00
										 |  |  |     class SelectEventLoopTests(EventLoopTestsMixin, | 
					
						
							|  |  |  |                                test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def create_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             return asyncio.SelectorEventLoop() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |     class ProactorEventLoopTests(EventLoopTestsMixin, | 
					
						
							|  |  |  |                                  SubprocessTestsMixin, | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |                                  test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def create_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             return asyncio.ProactorEventLoop() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def test_reader_callback(self): | 
					
						
							|  |  |  |             raise unittest.SkipTest("IocpEventLoop does not have add_reader()") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def test_reader_callback_cancel(self): | 
					
						
							|  |  |  |             raise unittest.SkipTest("IocpEventLoop does not have add_reader()") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def test_writer_callback(self): | 
					
						
							|  |  |  |             raise unittest.SkipTest("IocpEventLoop does not have add_writer()") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def test_writer_callback_cancel(self): | 
					
						
							|  |  |  |             raise unittest.SkipTest("IocpEventLoop does not have add_writer()") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 00:52:53 +01:00
										 |  |  |         def test_remove_fds_after_closing(self): | 
					
						
							|  |  |  |             raise unittest.SkipTest("IocpEventLoop does not have add_reader()") | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | else: | 
					
						
							| 
									
										
										
										
											2017-11-28 15:19:56 +01:00
										 |  |  |     import selectors | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if hasattr(selectors, 'KqueueSelector'): | 
					
						
							| 
									
										
										
										
											2024-06-23 18:38:50 +05:30
										 |  |  |         class KqueueEventLoopTests(EventLoopTestsMixin, | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |                                    SubprocessTestsMixin, | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |                                    test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |             def create_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |                 return asyncio.SelectorEventLoop( | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |                     selectors.KqueueSelector()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             # kqueue doesn't support character devices (PTY) on Mac OS X older | 
					
						
							|  |  |  |             # than 10.9 (Maverick) | 
					
						
							|  |  |  |             @support.requires_mac_ver(10, 9) | 
					
						
							| 
									
										
										
										
											2014-02-18 01:30:03 +01:00
										 |  |  |             # Issue #20667: KqueueEventLoopTests.test_read_pty_output() | 
					
						
							| 
									
										
										
										
											2014-02-18 09:13:47 +01:00
										 |  |  |             # hangs on OpenBSD 5.5 | 
					
						
							|  |  |  |             @unittest.skipIf(sys.platform.startswith('openbsd'), | 
					
						
							|  |  |  |                              'test hangs on OpenBSD') | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             def test_read_pty_output(self): | 
					
						
							|  |  |  |                 super().test_read_pty_output() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # kqueue doesn't support character devices (PTY) on Mac OS X older | 
					
						
							|  |  |  |             # than 10.9 (Maverick) | 
					
						
							|  |  |  |             @support.requires_mac_ver(10, 9) | 
					
						
							|  |  |  |             def test_write_pty(self): | 
					
						
							|  |  |  |                 super().test_write_pty() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     if hasattr(selectors, 'EpollSelector'): | 
					
						
							| 
									
										
										
										
											2024-06-23 18:38:50 +05:30
										 |  |  |         class EPollEventLoopTests(EventLoopTestsMixin, | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |                                   SubprocessTestsMixin, | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |                                   test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |             def create_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |                 return asyncio.SelectorEventLoop(selectors.EpollSelector()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if hasattr(selectors, 'PollSelector'): | 
					
						
							| 
									
										
										
										
											2024-06-23 18:38:50 +05:30
										 |  |  |         class PollEventLoopTests(EventLoopTestsMixin, | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |                                  SubprocessTestsMixin, | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |                                  test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |             def create_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |                 return asyncio.SelectorEventLoop(selectors.PollSelector()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Should always exist. | 
					
						
							| 
									
										
										
										
											2024-06-23 18:38:50 +05:30
										 |  |  |     class SelectEventLoopTests(EventLoopTestsMixin, | 
					
						
							| 
									
										
										
										
											2013-10-30 14:52:03 -07:00
										 |  |  |                                SubprocessTestsMixin, | 
					
						
							| 
									
										
										
										
											2014-06-18 01:36:32 +02:00
										 |  |  |                                test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def create_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |             return asyncio.SelectorEventLoop(selectors.SelectSelector()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 15:58:15 -04:00
										 |  |  | def noop(*args, **kwargs): | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  | class HandleTests(test_utils.TestCase): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |         super().setUp() | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |         self.loop = mock.Mock() | 
					
						
							|  |  |  |         self.loop.get_debug.return_value = True | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_handle(self): | 
					
						
							|  |  |  |         def callback(*args): | 
					
						
							|  |  |  |             return args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         args = () | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         h = asyncio.Handle(callback, args, self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertIs(h._callback, callback) | 
					
						
							|  |  |  |         self.assertIs(h._args, args) | 
					
						
							| 
									
										
										
										
											2017-11-07 12:06:05 +03:00
										 |  |  |         self.assertFalse(h.cancelled()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         h.cancel() | 
					
						
							| 
									
										
										
										
											2017-11-07 12:06:05 +03:00
										 |  |  |         self.assertTrue(h.cancelled()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |     def test_callback_with_exception(self): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         def callback(): | 
					
						
							|  |  |  |             raise ValueError() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         self.loop = mock.Mock() | 
					
						
							|  |  |  |         self.loop.call_exception_handler = mock.Mock() | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         h = asyncio.Handle(callback, (), self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         h._run() | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         self.loop.call_exception_handler.assert_called_with({ | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |             'message': test_utils.MockPattern('Exception in callback.*'), | 
					
						
							| 
									
										
										
										
											2014-02-26 10:25:02 +01:00
										 |  |  |             'exception': mock.ANY, | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |             'handle': h, | 
					
						
							|  |  |  |             'source_traceback': h._source_traceback, | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 10:44:22 -07:00
										 |  |  |     def test_handle_weakref(self): | 
					
						
							|  |  |  |         wd = weakref.WeakValueDictionary() | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         h = asyncio.Handle(lambda: None, (), self.loop) | 
					
						
							| 
									
										
										
										
											2014-04-27 10:44:22 -07:00
										 |  |  |         wd['h'] = h  # Would fail without __weakref__ slot. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |     def test_handle_repr(self): | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         self.loop.get_debug.return_value = False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         # simple function | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         h = asyncio.Handle(noop, (1, 2), self.loop) | 
					
						
							|  |  |  |         filename, lineno = test_utils.get_function_source(noop) | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         self.assertEqual(repr(h), | 
					
						
							| 
									
										
										
										
											2024-02-28 02:39:08 +01:00
										 |  |  |                         '<Handle noop() at %s:%s>' | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |                         % (filename, lineno)) | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # cancelled handle | 
					
						
							|  |  |  |         h.cancel() | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |                         '<Handle cancelled>') | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # decorated function | 
					
						
							| 
									
										
										
										
											2021-07-01 16:13:59 +03:00
										 |  |  |         cb = types.coroutine(noop) | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         h = asyncio.Handle(cb, (), self.loop) | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |                         '<Handle noop() at %s:%s>' | 
					
						
							|  |  |  |                         % (filename, lineno)) | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # partial function | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         cb = functools.partial(noop, 1, 2) | 
					
						
							|  |  |  |         h = asyncio.Handle(cb, (3,), self.loop) | 
					
						
							| 
									
										
										
										
											2024-02-28 02:39:08 +01:00
										 |  |  |         regex = (r'^<Handle noop\(\)\(\) at %s:%s>$' | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |                  % (re.escape(filename), lineno)) | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         self.assertRegex(repr(h), regex) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 15:58:15 -04:00
										 |  |  |         # partial function with keyword args | 
					
						
							|  |  |  |         cb = functools.partial(noop, x=1) | 
					
						
							|  |  |  |         h = asyncio.Handle(cb, (2, 3), self.loop) | 
					
						
							| 
									
										
										
										
											2024-02-28 02:39:08 +01:00
										 |  |  |         regex = (r'^<Handle noop\(\)\(\) at %s:%s>$' | 
					
						
							| 
									
										
										
										
											2016-09-15 15:58:15 -04:00
										 |  |  |                  % (re.escape(filename), lineno)) | 
					
						
							|  |  |  |         self.assertRegex(repr(h), regex) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  |         # partial method | 
					
						
							| 
									
										
										
										
											2022-01-13 17:28:02 +03:00
										 |  |  |         method = HandleTests.test_handle_repr | 
					
						
							|  |  |  |         cb = functools.partialmethod(method) | 
					
						
							|  |  |  |         filename, lineno = test_utils.get_function_source(method) | 
					
						
							|  |  |  |         h = asyncio.Handle(cb, (), self.loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cb_regex = r'<function HandleTests.test_handle_repr .*>' | 
					
						
							| 
									
										
										
										
											2024-06-26 11:08:27 +02:00
										 |  |  |         cb_regex = fr'functools.partialmethod\({cb_regex}\)\(\)' | 
					
						
							| 
									
										
										
										
											2022-01-13 17:28:02 +03:00
										 |  |  |         regex = fr'^<Handle {cb_regex} at {re.escape(filename)}:{lineno}>$' | 
					
						
							|  |  |  |         self.assertRegex(repr(h), regex) | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |     def test_handle_repr_debug(self): | 
					
						
							|  |  |  |         self.loop.get_debug.return_value = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # simple function | 
					
						
							|  |  |  |         create_filename = __file__ | 
					
						
							|  |  |  |         create_lineno = sys._getframe().f_lineno + 1 | 
					
						
							|  |  |  |         h = asyncio.Handle(noop, (1, 2), self.loop) | 
					
						
							|  |  |  |         filename, lineno = test_utils.get_function_source(noop) | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							|  |  |  |                         '<Handle noop(1, 2) at %s:%s created at %s:%s>' | 
					
						
							|  |  |  |                         % (filename, lineno, create_filename, create_lineno)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # cancelled handle | 
					
						
							|  |  |  |         h.cancel() | 
					
						
							| 
									
										
										
										
											2014-09-25 12:07:56 -04:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             repr(h), | 
					
						
							|  |  |  |             '<Handle cancelled noop(1, 2) at %s:%s created at %s:%s>' | 
					
						
							|  |  |  |             % (filename, lineno, create_filename, create_lineno)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # double cancellation won't overwrite _repr | 
					
						
							|  |  |  |         h.cancel() | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             repr(h), | 
					
						
							|  |  |  |             '<Handle cancelled noop(1, 2) at %s:%s created at %s:%s>' | 
					
						
							|  |  |  |             % (filename, lineno, create_filename, create_lineno)) | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-28 02:39:08 +01:00
										 |  |  |         # partial function | 
					
						
							|  |  |  |         cb = functools.partial(noop, 1, 2) | 
					
						
							|  |  |  |         create_lineno = sys._getframe().f_lineno + 1 | 
					
						
							|  |  |  |         h = asyncio.Handle(cb, (3,), self.loop) | 
					
						
							|  |  |  |         regex = (r'^<Handle noop\(1, 2\)\(3\) at %s:%s created at %s:%s>$' | 
					
						
							|  |  |  |                  % (re.escape(filename), lineno, | 
					
						
							|  |  |  |                     re.escape(create_filename), create_lineno)) | 
					
						
							|  |  |  |         self.assertRegex(repr(h), regex) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # partial function with keyword args | 
					
						
							|  |  |  |         cb = functools.partial(noop, x=1) | 
					
						
							|  |  |  |         create_lineno = sys._getframe().f_lineno + 1 | 
					
						
							|  |  |  |         h = asyncio.Handle(cb, (2, 3), self.loop) | 
					
						
							|  |  |  |         regex = (r'^<Handle noop\(x=1\)\(2, 3\) at %s:%s created at %s:%s>$' | 
					
						
							|  |  |  |                  % (re.escape(filename), lineno, | 
					
						
							|  |  |  |                     re.escape(create_filename), create_lineno)) | 
					
						
							|  |  |  |         self.assertRegex(repr(h), regex) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |     def test_handle_source_traceback(self): | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |         loop = asyncio.new_event_loop() | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |         loop.set_debug(True) | 
					
						
							|  |  |  |         self.set_event_loop(loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def check_source_traceback(h): | 
					
						
							|  |  |  |             lineno = sys._getframe(1).f_lineno - 1 | 
					
						
							|  |  |  |             self.assertIsInstance(h._source_traceback, list) | 
					
						
							|  |  |  |             self.assertEqual(h._source_traceback[-1][:3], | 
					
						
							|  |  |  |                              (__file__, | 
					
						
							|  |  |  |                               lineno, | 
					
						
							|  |  |  |                               'test_handle_source_traceback')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # call_soon | 
					
						
							|  |  |  |         h = loop.call_soon(noop) | 
					
						
							|  |  |  |         check_source_traceback(h) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # call_soon_threadsafe | 
					
						
							|  |  |  |         h = loop.call_soon_threadsafe(noop) | 
					
						
							|  |  |  |         check_source_traceback(h) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # call_later | 
					
						
							|  |  |  |         h = loop.call_later(0, noop) | 
					
						
							|  |  |  |         check_source_traceback(h) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # call_at | 
					
						
							|  |  |  |         h = loop.call_later(0, noop) | 
					
						
							|  |  |  |         check_source_traceback(h) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 19:32:49 -04:00
										 |  |  |     def test_coroutine_like_object_debug_formatting(self): | 
					
						
							|  |  |  |         # Test that asyncio can format coroutines that are instances of | 
					
						
							|  |  |  |         # collections.abc.Coroutine, but lack cr_core or gi_code attributes | 
					
						
							|  |  |  |         # (such as ones compiled with Cython). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-23 12:44:29 -05:00
										 |  |  |         coro = CoroLike() | 
					
						
							| 
									
										
										
										
											2016-11-08 19:16:01 -05:00
										 |  |  |         coro.__name__ = 'AAA' | 
					
						
							| 
									
										
										
										
											2016-10-05 19:32:49 -04:00
										 |  |  |         self.assertTrue(asyncio.iscoroutine(coro)) | 
					
						
							|  |  |  |         self.assertEqual(coroutines._format_coroutine(coro), 'AAA()') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         coro.__qualname__ = 'BBB' | 
					
						
							|  |  |  |         self.assertEqual(coroutines._format_coroutine(coro), 'BBB()') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         coro.cr_running = True | 
					
						
							|  |  |  |         self.assertEqual(coroutines._format_coroutine(coro), 'BBB() running') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 16:27:34 -04:00
										 |  |  |         coro.__name__ = coro.__qualname__ = None | 
					
						
							|  |  |  |         self.assertEqual(coroutines._format_coroutine(coro), | 
					
						
							|  |  |  |                          '<CoroLike without __name__>() running') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-23 12:44:29 -05:00
										 |  |  |         coro = CoroLike() | 
					
						
							| 
									
										
										
										
											2018-05-28 16:27:34 -04:00
										 |  |  |         coro.__qualname__ = 'CoroLike' | 
					
						
							| 
									
										
										
										
											2016-11-08 19:16:01 -05:00
										 |  |  |         # Some coroutines might not have '__name__', such as | 
					
						
							|  |  |  |         # built-in async_gen.asend(). | 
					
						
							| 
									
										
										
										
											2017-12-23 12:44:29 -05:00
										 |  |  |         self.assertEqual(coroutines._format_coroutine(coro), 'CoroLike()') | 
					
						
							| 
									
										
										
										
											2016-11-08 19:16:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 16:27:34 -04:00
										 |  |  |         coro = CoroLike() | 
					
						
							|  |  |  |         coro.__qualname__ = 'AAA' | 
					
						
							|  |  |  |         coro.cr_code = None | 
					
						
							|  |  |  |         self.assertEqual(coroutines._format_coroutine(coro), 'AAA()') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | class TimerTests(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |         super().setUp() | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         self.loop = mock.Mock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_hash(self): | 
					
						
							|  |  |  |         when = time.monotonic() | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |         h = asyncio.TimerHandle(when, lambda: False, (), | 
					
						
							| 
									
										
										
										
											2014-02-26 10:25:02 +01:00
										 |  |  |                                 mock.Mock()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertEqual(hash(h), hash(when)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 19:59:32 +02:00
										 |  |  |     def test_when(self): | 
					
						
							|  |  |  |         when = time.monotonic() | 
					
						
							|  |  |  |         h = asyncio.TimerHandle(when, lambda: False, (), | 
					
						
							|  |  |  |                                 mock.Mock()) | 
					
						
							|  |  |  |         self.assertEqual(when, h.when()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_timer(self): | 
					
						
							|  |  |  |         def callback(*args): | 
					
						
							|  |  |  |             return args | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         args = (1, 2, 3) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         when = time.monotonic() | 
					
						
							| 
									
										
										
										
											2014-02-26 10:25:02 +01:00
										 |  |  |         h = asyncio.TimerHandle(when, callback, args, mock.Mock()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertIs(h._callback, callback) | 
					
						
							|  |  |  |         self.assertIs(h._args, args) | 
					
						
							| 
									
										
										
										
											2017-11-07 12:06:05 +03:00
										 |  |  |         self.assertFalse(h.cancelled()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         # cancel | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         h.cancel() | 
					
						
							| 
									
										
										
										
											2017-11-07 12:06:05 +03:00
										 |  |  |         self.assertTrue(h.cancelled()) | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         self.assertIsNone(h._callback) | 
					
						
							|  |  |  |         self.assertIsNone(h._args) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |     def test_timer_repr(self): | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         self.loop.get_debug.return_value = False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         # simple function | 
					
						
							|  |  |  |         h = asyncio.TimerHandle(123, noop, (), self.loop) | 
					
						
							|  |  |  |         src = test_utils.get_function_source(noop) | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							|  |  |  |                         '<TimerHandle when=123 noop() at %s:%s>' % src) | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         # cancelled handle | 
					
						
							|  |  |  |         h.cancel() | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |                         '<TimerHandle cancelled when=123>') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_timer_repr_debug(self): | 
					
						
							|  |  |  |         self.loop.get_debug.return_value = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # simple function | 
					
						
							|  |  |  |         create_filename = __file__ | 
					
						
							|  |  |  |         create_lineno = sys._getframe().f_lineno + 1 | 
					
						
							|  |  |  |         h = asyncio.TimerHandle(123, noop, (), self.loop) | 
					
						
							|  |  |  |         filename, lineno = test_utils.get_function_source(noop) | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							|  |  |  |                         '<TimerHandle when=123 noop() ' | 
					
						
							|  |  |  |                         'at %s:%s created at %s:%s>' | 
					
						
							|  |  |  |                         % (filename, lineno, create_filename, create_lineno)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # cancelled handle | 
					
						
							|  |  |  |         h.cancel() | 
					
						
							|  |  |  |         self.assertEqual(repr(h), | 
					
						
							| 
									
										
										
										
											2014-09-17 23:24:13 +02:00
										 |  |  |                         '<TimerHandle cancelled when=123 noop() ' | 
					
						
							|  |  |  |                         'at %s:%s created at %s:%s>' | 
					
						
							|  |  |  |                         % (filename, lineno, create_filename, create_lineno)) | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_timer_comparison(self): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         def callback(*args): | 
					
						
							|  |  |  |             return args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         when = time.monotonic() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         h1 = asyncio.TimerHandle(when, callback, (), self.loop) | 
					
						
							|  |  |  |         h2 = asyncio.TimerHandle(when, callback, (), self.loop) | 
					
						
							| 
									
										
										
										
											2025-03-28 19:25:13 +05:00
										 |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertLess(h1, h2) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertLess(h2, h1) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertGreater(h1, h2) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertGreater(h2, h1) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertNotEqual(h1, h2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertLessEqual(h1, h2) | 
					
						
							|  |  |  |         self.assertLessEqual(h2, h1) | 
					
						
							|  |  |  |         self.assertGreaterEqual(h1, h2) | 
					
						
							|  |  |  |         self.assertGreaterEqual(h2, h1) | 
					
						
							|  |  |  |         self.assertEqual(h1, h2) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         h2.cancel() | 
					
						
							| 
									
										
										
										
											2025-03-28 19:25:13 +05:00
										 |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertEqual(h1, h2) | 
					
						
							|  |  |  |         self.assertNotEqual(h1, h2) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         h1 = asyncio.TimerHandle(when, callback, (), self.loop) | 
					
						
							|  |  |  |         h2 = asyncio.TimerHandle(when + 10.0, callback, (), self.loop) | 
					
						
							| 
									
										
										
										
											2025-03-28 19:25:13 +05:00
										 |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertLess(h2, h1) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertLessEqual(h2, h1) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertGreater(h1, h2) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertGreaterEqual(h1, h2) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertEqual(h1, h2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertLess(h1, h2) | 
					
						
							|  |  |  |         self.assertGreater(h2, h1) | 
					
						
							|  |  |  |         self.assertLessEqual(h1, h2) | 
					
						
							|  |  |  |         self.assertGreaterEqual(h2, h1) | 
					
						
							|  |  |  |         self.assertNotEqual(h1, h2) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |         h3 = asyncio.Handle(callback, (), self.loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertIs(NotImplemented, h1.__eq__(h3)) | 
					
						
							|  |  |  |         self.assertIs(NotImplemented, h1.__ne__(h3)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             h1 < () | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             h1 > () | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             h1 <= () | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             h1 >= () | 
					
						
							| 
									
										
										
										
											2025-03-28 19:25:13 +05:00
										 |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertEqual(h1, ()) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertNotEqual(h1, ALWAYS_EQ) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertGreater(h1, LARGEST) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertGreaterEqual(h1, LARGEST) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertLess(h1, SMALLEST) | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             self.assertLessEqual(h1, SMALLEST) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual(h1, ()) | 
					
						
							|  |  |  |         self.assertEqual(h1, ALWAYS_EQ) | 
					
						
							|  |  |  |         self.assertLess(h1, LARGEST) | 
					
						
							|  |  |  |         self.assertLessEqual(h1, LARGEST) | 
					
						
							|  |  |  |         self.assertGreaterEqual(h1, SMALLEST) | 
					
						
							|  |  |  |         self.assertGreater(h1, SMALLEST) | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AbstractEventLoopTests(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_not_implemented(self): | 
					
						
							| 
									
										
										
										
											2014-02-26 10:25:02 +01:00
										 |  |  |         f = mock.Mock() | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         loop = asyncio.AbstractEventLoop() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.run_forever) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.run_until_complete, None) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.stop) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.is_running) | 
					
						
							| 
									
										
										
										
											2014-07-08 11:29:25 +02:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.is_closed) | 
					
						
							| 
									
										
										
										
											2013-11-01 14:19:04 -07:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.close) | 
					
						
							| 
									
										
										
										
											2014-07-08 11:29:25 +02:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.create_task, None) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.call_later, None, None) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.call_at, f, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.call_soon, None) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.time) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.call_soon_threadsafe, None) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.set_default_executor, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.add_reader, 1, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.remove_reader, 1) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.add_writer, 1, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.remove_writer, 1) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.add_signal_handler, 1, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.remove_signal_handler, 1) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.remove_signal_handler, 1) | 
					
						
							| 
									
										
										
										
											2014-07-08 11:29:25 +02:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.set_exception_handler, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.default_exception_handler, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.call_exception_handler, f) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.get_debug) | 
					
						
							|  |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             NotImplementedError, loop.set_debug, f) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     def test_not_implemented_async(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         async def inner(): | 
					
						
							|  |  |  |             f = mock.Mock() | 
					
						
							|  |  |  |             loop = asyncio.AbstractEventLoop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.run_in_executor(f, f) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.getaddrinfo('localhost', 8080) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.getnameinfo(('localhost', 8080)) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.create_connection(f) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.create_server(f) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.create_datagram_endpoint(f) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.sock_recv(f, 10) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.sock_recv_into(f, 10) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.sock_sendall(f, 10) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.sock_connect(f, f) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.sock_accept(f) | 
					
						
							| 
									
										
										
										
											2018-01-16 19:59:34 +02:00
										 |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							| 
									
										
										
										
											2018-01-27 21:22:47 +02:00
										 |  |  |                 await loop.sock_sendfile(f, f) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.sendfile(f, f) | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.connect_read_pipe(f, mock.sentinel.pipe) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.connect_write_pipe(f, mock.sentinel.pipe) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.subprocess_shell(f, mock.sentinel) | 
					
						
							|  |  |  |             with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |                 await loop.subprocess_exec(f) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         loop = asyncio.new_event_loop() | 
					
						
							|  |  |  |         loop.run_until_complete(inner()) | 
					
						
							|  |  |  |         loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class PolicyTests(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |     def test_abstract_event_loop_policy_deprecation(self): | 
					
						
							|  |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |                 DeprecationWarning, "'asyncio.AbstractEventLoopPolicy' is deprecated"): | 
					
						
							|  |  |  |             policy = asyncio.AbstractEventLoopPolicy() | 
					
						
							|  |  |  |             self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_default_event_loop_policy_deprecation(self): | 
					
						
							|  |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |                 DeprecationWarning, "'asyncio.DefaultEventLoopPolicy' is deprecated"): | 
					
						
							|  |  |  |             policy = asyncio.DefaultEventLoopPolicy() | 
					
						
							|  |  |  |             self.assertIsInstance(policy, asyncio.DefaultEventLoopPolicy) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_event_loop_policy(self): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._AbstractEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self.assertRaises(NotImplementedError, policy.get_event_loop) | 
					
						
							|  |  |  |         self.assertRaises(NotImplementedError, policy.set_event_loop, object()) | 
					
						
							|  |  |  |         self.assertRaises(NotImplementedError, policy.new_event_loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_event_loop(self): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         self.assertIsNone(policy._local._loop) | 
					
						
							| 
									
										
										
										
											2023-01-13 14:40:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 14:21:20 +05:30
										 |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							|  |  |  |             loop = policy.get_event_loop() | 
					
						
							|  |  |  |         self.assertIsNone(policy._local._loop) | 
					
						
							| 
									
										
										
										
											2023-01-13 14:40:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 14:21:20 +05:30
										 |  |  |     def test_get_event_loop_does_not_call_set_event_loop(self): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2023-01-13 14:40:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         with mock.patch.object( | 
					
						
							|  |  |  |                 policy, "set_event_loop", | 
					
						
							|  |  |  |                 wraps=policy.set_event_loop) as m_set_event_loop: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 14:21:20 +05:30
										 |  |  |             with self.assertRaises(RuntimeError): | 
					
						
							| 
									
										
										
										
											2023-01-13 14:40:29 +02:00
										 |  |  |                 loop = policy.get_event_loop() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 14:21:20 +05:30
										 |  |  |             m_set_event_loop.assert_not_called() | 
					
						
							| 
									
										
										
										
											2013-11-27 10:37:13 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_get_event_loop_after_set_none(self): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         policy.set_event_loop(None) | 
					
						
							| 
									
										
										
										
											2014-12-18 01:20:10 +01:00
										 |  |  |         self.assertRaises(RuntimeError, policy.get_event_loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 10:25:02 +01:00
										 |  |  |     @mock.patch('asyncio.events.threading.current_thread') | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def test_get_event_loop_thread(self, m_current_thread): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def f(): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |             policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2014-12-18 01:20:10 +01:00
										 |  |  |             self.assertRaises(RuntimeError, policy.get_event_loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         th = threading.Thread(target=f) | 
					
						
							|  |  |  |         th.start() | 
					
						
							|  |  |  |         th.join() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_new_event_loop(self): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         loop = policy.new_event_loop() | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:06 +01:00
										 |  |  |         self.assertIsInstance(loop, asyncio.AbstractEventLoop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_set_event_loop(self): | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |         old_loop = policy.new_event_loop() | 
					
						
							|  |  |  |         policy.set_event_loop(old_loop) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-07 05:10:35 +05:30
										 |  |  |         self.assertRaises(TypeError, policy.set_event_loop, object()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         loop = policy.new_event_loop() | 
					
						
							|  |  |  |         policy.set_event_loop(loop) | 
					
						
							|  |  |  |         self.assertIs(loop, policy.get_event_loop()) | 
					
						
							|  |  |  |         self.assertIsNot(old_loop, policy.get_event_loop()) | 
					
						
							|  |  |  |         loop.close() | 
					
						
							|  |  |  |         old_loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_event_loop_policy(self): | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |                 DeprecationWarning, "'asyncio.get_event_loop_policy' is deprecated"): | 
					
						
							|  |  |  |             policy = asyncio.get_event_loop_policy() | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |             self.assertIsInstance(policy, asyncio._AbstractEventLoopPolicy) | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |             self.assertIs(policy, asyncio.get_event_loop_policy()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_set_event_loop_policy(self): | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |         with self.assertWarnsRegex( | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |                 DeprecationWarning, "'asyncio.set_event_loop_policy' is deprecated"): | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |             self.assertRaises( | 
					
						
							|  |  |  |                 TypeError, asyncio.set_event_loop_policy, object()) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |                 DeprecationWarning, "'asyncio.get_event_loop_policy' is deprecated"): | 
					
						
							|  |  |  |             old_policy = asyncio.get_event_loop_policy() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         policy = asyncio._DefaultEventLoopPolicy() | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |         with self.assertWarnsRegex( | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |                 DeprecationWarning, "'asyncio.set_event_loop_policy' is deprecated"): | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |             asyncio.set_event_loop_policy(policy) | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |         with self.assertWarnsRegex( | 
					
						
							|  |  |  |                 DeprecationWarning, "'asyncio.get_event_loop_policy' is deprecated"): | 
					
						
							|  |  |  |             self.assertIs(policy, asyncio.get_event_loop_policy()) | 
					
						
							|  |  |  |             self.assertIsNot(policy, old_policy) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | class GetEventLoopTestsMixin: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _get_running_loop_impl = None | 
					
						
							|  |  |  |     _set_running_loop_impl = None | 
					
						
							|  |  |  |     get_running_loop_impl = None | 
					
						
							|  |  |  |     get_event_loop_impl = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |     Task = None | 
					
						
							|  |  |  |     Future = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self._get_running_loop_saved = events._get_running_loop | 
					
						
							|  |  |  |         self._set_running_loop_saved = events._set_running_loop | 
					
						
							|  |  |  |         self.get_running_loop_saved = events.get_running_loop | 
					
						
							|  |  |  |         self.get_event_loop_saved = events.get_event_loop | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |         self._Task_saved = asyncio.Task | 
					
						
							|  |  |  |         self._Future_saved = asyncio.Future | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         events._get_running_loop = type(self)._get_running_loop_impl | 
					
						
							|  |  |  |         events._set_running_loop = type(self)._set_running_loop_impl | 
					
						
							|  |  |  |         events.get_running_loop = type(self).get_running_loop_impl | 
					
						
							|  |  |  |         events.get_event_loop = type(self).get_event_loop_impl | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         asyncio._get_running_loop = type(self)._get_running_loop_impl | 
					
						
							|  |  |  |         asyncio._set_running_loop = type(self)._set_running_loop_impl | 
					
						
							|  |  |  |         asyncio.get_running_loop = type(self).get_running_loop_impl | 
					
						
							|  |  |  |         asyncio.get_event_loop = type(self).get_event_loop_impl | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |         asyncio.Task = asyncio.tasks.Task = type(self).Task | 
					
						
							|  |  |  |         asyncio.Future = asyncio.futures.Future = type(self).Future | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |         super().setUp() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop = asyncio.new_event_loop() | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |         asyncio.set_event_loop(self.loop) | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             super().tearDown() | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             self.loop.close() | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(None) | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             events._get_running_loop = self._get_running_loop_saved | 
					
						
							|  |  |  |             events._set_running_loop = self._set_running_loop_saved | 
					
						
							|  |  |  |             events.get_running_loop = self.get_running_loop_saved | 
					
						
							|  |  |  |             events.get_event_loop = self.get_event_loop_saved | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             asyncio._get_running_loop = self._get_running_loop_saved | 
					
						
							|  |  |  |             asyncio._set_running_loop = self._set_running_loop_saved | 
					
						
							|  |  |  |             asyncio.get_running_loop = self.get_running_loop_saved | 
					
						
							|  |  |  |             asyncio.get_event_loop = self.get_event_loop_saved | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |             asyncio.Task = asyncio.tasks.Task = self._Task_saved | 
					
						
							|  |  |  |             asyncio.Future = asyncio.futures.Future = self._Future_saved | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |     if sys.platform != 'win32': | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |         def test_get_event_loop_new_process(self): | 
					
						
							| 
									
										
										
										
											2020-06-18 14:53:19 +02:00
										 |  |  |             # bpo-32126: The multiprocessing module used by | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |             # ProcessPoolExecutor is not functional when the | 
					
						
							|  |  |  |             # multiprocessing.synchronize module cannot be imported. | 
					
						
							| 
									
										
										
										
											2020-06-18 14:53:19 +02:00
										 |  |  |             support.skip_if_broken_multiprocessing_synchronize() | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 03:31:15 +02:00
										 |  |  |             self.addCleanup(multiprocessing_cleanup_tests) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |             async def main(): | 
					
						
							| 
									
										
										
										
											2023-02-02 15:50:35 -08:00
										 |  |  |                 if multiprocessing.get_start_method() == 'fork': | 
					
						
							|  |  |  |                     # Avoid 'fork' DeprecationWarning. | 
					
						
							|  |  |  |                     mp_context = multiprocessing.get_context('forkserver') | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     mp_context = None | 
					
						
							|  |  |  |                 pool = concurrent.futures.ProcessPoolExecutor( | 
					
						
							|  |  |  |                         mp_context=mp_context) | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |                 result = await self.loop.run_in_executor( | 
					
						
							|  |  |  |                     pool, _test_get_event_loop_new_process__sub_proc) | 
					
						
							|  |  |  |                 pool.shutdown() | 
					
						
							|  |  |  |                 return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual( | 
					
						
							|  |  |  |                 self.loop.run_until_complete(main()), | 
					
						
							|  |  |  |                 'hello') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-15 15:01:53 +05:30
										 |  |  |     def test_get_running_loop_already_running(self): | 
					
						
							|  |  |  |         async def main(): | 
					
						
							|  |  |  |             running_loop = asyncio.get_running_loop() | 
					
						
							| 
									
										
										
										
											2025-03-24 12:38:33 +00:00
										 |  |  |             with contextlib.closing(asyncio.new_event_loop()) as loop: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     loop.run_forever() | 
					
						
							|  |  |  |                 except RuntimeError: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     self.fail("RuntimeError not raised") | 
					
						
							| 
									
										
										
										
											2025-02-15 15:01:53 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |             self.assertIs(asyncio.get_running_loop(), running_loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.loop.run_until_complete(main()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |     def test_get_event_loop_returns_running_loop(self): | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |         class TestError(Exception): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |         class Policy(asyncio._DefaultEventLoopPolicy): | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |             def get_event_loop(self): | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |                 raise TestError | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |         old_policy = asyncio._get_event_loop_policy() | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |             asyncio._set_event_loop_policy(Policy()) | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |             loop = asyncio.new_event_loop() | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             with self.assertRaises(TestError): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(None) | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             with self.assertRaises(TestError): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  |             with self.assertRaisesRegex(RuntimeError, 'no running'): | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |                 asyncio.get_running_loop() | 
					
						
							| 
									
										
										
										
											2016-11-07 19:00:46 -05:00
										 |  |  |             self.assertIs(asyncio._get_running_loop(), None) | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             async def func(): | 
					
						
							|  |  |  |                 self.assertIs(asyncio.get_event_loop(), loop) | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  |                 self.assertIs(asyncio.get_running_loop(), loop) | 
					
						
							| 
									
										
										
										
											2016-11-07 19:00:46 -05:00
										 |  |  |                 self.assertIs(asyncio._get_running_loop(), loop) | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |             loop.run_until_complete(func()) | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(loop) | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             with self.assertRaises(TestError): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(None) | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             with self.assertRaises(TestError): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |         finally: | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |             asyncio._set_event_loop_policy(old_policy) | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |             if loop is not None: | 
					
						
							|  |  |  |                 loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  |         with self.assertRaisesRegex(RuntimeError, 'no running'): | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |             asyncio.get_running_loop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIs(asyncio._get_running_loop(), None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_event_loop_returns_running_loop2(self): | 
					
						
							| 
									
										
										
										
											2024-12-18 18:04:20 +05:30
										 |  |  |         old_policy = asyncio._get_event_loop_policy() | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2024-12-24 17:30:26 +05:30
										 |  |  |             asyncio._set_event_loop_policy(asyncio._DefaultEventLoopPolicy()) | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |             loop = asyncio.new_event_loop() | 
					
						
							|  |  |  |             self.addCleanup(loop.close) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             with self.assertRaisesRegex(RuntimeError, 'no current'): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(None) | 
					
						
							| 
									
										
										
										
											2024-11-04 14:21:20 +05:30
										 |  |  |             with self.assertRaisesRegex(RuntimeError, 'no current'): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |             async def func(): | 
					
						
							|  |  |  |                 self.assertIs(asyncio.get_event_loop(), loop) | 
					
						
							|  |  |  |                 self.assertIs(asyncio.get_running_loop(), loop) | 
					
						
							|  |  |  |                 self.assertIs(asyncio._get_running_loop(), loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             loop.run_until_complete(func()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(loop) | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             self.assertIs(asyncio.get_event_loop(), loop) | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 12:03:52 +05:30
										 |  |  |             asyncio.set_event_loop(None) | 
					
						
							| 
									
										
										
										
											2022-12-06 19:42:12 +02:00
										 |  |  |             with self.assertRaisesRegex(RuntimeError, 'no current'): | 
					
						
							|  |  |  |                 asyncio.get_event_loop() | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         finally: | 
					
						
							| 
									
										
										
										
											2024-12-18 11:35:29 +05:30
										 |  |  |             asyncio._set_event_loop_policy(old_policy) | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |             if loop is not None: | 
					
						
							|  |  |  |                 loop.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaisesRegex(RuntimeError, 'no running'): | 
					
						
							|  |  |  |             asyncio.get_running_loop() | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-07 19:00:46 -05:00
										 |  |  |         self.assertIs(asyncio._get_running_loop(), None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | class TestPyGetEventLoop(GetEventLoopTestsMixin, unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _get_running_loop_impl = events._py__get_running_loop | 
					
						
							|  |  |  |     _set_running_loop_impl = events._py__set_running_loop | 
					
						
							|  |  |  |     get_running_loop_impl = events._py_get_running_loop | 
					
						
							|  |  |  |     get_event_loop_impl = events._py_get_event_loop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |     Task = asyncio.tasks._PyTask | 
					
						
							|  |  |  |     Future = asyncio.futures._PyFuture | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     import _asyncio  # NoQA | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | else: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class TestCGetEventLoop(GetEventLoopTestsMixin, unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         _get_running_loop_impl = events._c__get_running_loop | 
					
						
							|  |  |  |         _set_running_loop_impl = events._c__set_running_loop | 
					
						
							|  |  |  |         get_running_loop_impl = events._c_get_running_loop | 
					
						
							|  |  |  |         get_event_loop_impl = events._c_get_event_loop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 18:36:16 +05:30
										 |  |  |         Task = asyncio.tasks._CTask | 
					
						
							|  |  |  |         Future = asyncio.futures._CFuture | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:32 +05:30
										 |  |  | class TestServer(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_loop(self): | 
					
						
							|  |  |  |         loop = asyncio.new_event_loop() | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  |         self.addCleanup(loop.close) | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:32 +05:30
										 |  |  |         proto = MyProto(loop) | 
					
						
							|  |  |  |         server = loop.run_until_complete(loop.create_server(lambda: proto, '0.0.0.0', 0)) | 
					
						
							|  |  |  |         self.assertEqual(server.get_loop(), loop) | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  |         server.close() | 
					
						
							|  |  |  |         loop.run_until_complete(server.wait_closed()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:32 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | class TestAbstractServer(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  |     def test_close(self): | 
					
						
							|  |  |  |         with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |             events.AbstractServer().close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_wait_closed(self): | 
					
						
							|  |  |  |         loop = asyncio.new_event_loop() | 
					
						
							|  |  |  |         self.addCleanup(loop.close) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |             loop.run_until_complete(events.AbstractServer().wait_closed()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:32 +05:30
										 |  |  |     def test_get_loop(self): | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  |         with self.assertRaises(NotImplementedError): | 
					
						
							|  |  |  |             events.AbstractServer().get_loop() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main() |