mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-26 11:10:58 +00:00 
			
		
		
		
	python-3.6.zip added from Github
README.cosmo contains the necessary links.
This commit is contained in:
		
							parent
							
								
									75fc601ff5
								
							
						
					
					
						commit
						0c4c56ff39
					
				
					 4219 changed files with 1968626 additions and 0 deletions
				
			
		
							
								
								
									
										10
									
								
								third_party/python/Lib/test/test_asyncio/__init__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								third_party/python/Lib/test/test_asyncio/__init__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| import os | ||||
| from test.support import load_package_tests, import_module | ||||
| 
 | ||||
| # Skip tests if we don't have threading. | ||||
| import_module('threading') | ||||
| # Skip tests if we don't have concurrent.futures. | ||||
| import_module('concurrent.futures') | ||||
| 
 | ||||
| def load_tests(*args): | ||||
|     return load_package_tests(os.path.dirname(__file__), *args) | ||||
							
								
								
									
										4
									
								
								third_party/python/Lib/test/test_asyncio/__main__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								third_party/python/Lib/test/test_asyncio/__main__.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| from . import load_tests | ||||
| import unittest | ||||
| 
 | ||||
| unittest.main() | ||||
							
								
								
									
										8
									
								
								third_party/python/Lib/test/test_asyncio/echo.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								third_party/python/Lib/test/test_asyncio/echo.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| import os | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     while True: | ||||
|         buf = os.read(0, 1024) | ||||
|         if not buf: | ||||
|             break | ||||
|         os.write(1, buf) | ||||
							
								
								
									
										6
									
								
								third_party/python/Lib/test/test_asyncio/echo2.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								third_party/python/Lib/test/test_asyncio/echo2.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| import os | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     buf = os.read(0, 1024) | ||||
|     os.write(1, b'OUT:'+buf) | ||||
|     os.write(2, b'ERR:'+buf) | ||||
							
								
								
									
										11
									
								
								third_party/python/Lib/test/test_asyncio/echo3.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								third_party/python/Lib/test/test_asyncio/echo3.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| import os | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     while True: | ||||
|         buf = os.read(0, 1024) | ||||
|         if not buf: | ||||
|             break | ||||
|         try: | ||||
|             os.write(1, b'OUT:'+buf) | ||||
|         except OSError as ex: | ||||
|             os.write(2, b'ERR:' + ex.__class__.__name__.encode('ascii')) | ||||
							
								
								
									
										1875
									
								
								third_party/python/Lib/test/test_asyncio/test_base_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1875
									
								
								third_party/python/Lib/test/test_asyncio/test_base_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										2832
									
								
								third_party/python/Lib/test/test_asyncio/test_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2832
									
								
								third_party/python/Lib/test/test_asyncio/test_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										692
									
								
								third_party/python/Lib/test/test_asyncio/test_futures.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										692
									
								
								third_party/python/Lib/test/test_asyncio/test_futures.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,692 @@ | |||
| """Tests for futures.py.""" | ||||
| 
 | ||||
| import concurrent.futures | ||||
| import gc | ||||
| import re | ||||
| import sys | ||||
| import threading | ||||
| import unittest | ||||
| from unittest import mock | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import test_utils | ||||
| from asyncio import futures | ||||
| try: | ||||
|     from test import support | ||||
| except ImportError: | ||||
|     from asyncio import test_support as support | ||||
| 
 | ||||
| 
 | ||||
| def _fakefunc(f): | ||||
|     return f | ||||
| 
 | ||||
| 
 | ||||
| def first_cb(): | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
| def last_cb(): | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
| class DuckFuture: | ||||
|     # Class that does not inherit from Future but aims to be duck-type | ||||
|     # compatible with it. | ||||
| 
 | ||||
|     _asyncio_future_blocking = False | ||||
|     __cancelled = False | ||||
|     __result = None | ||||
|     __exception = None | ||||
| 
 | ||||
|     def cancel(self): | ||||
|         if self.done(): | ||||
|             return False | ||||
|         self.__cancelled = True | ||||
|         return True | ||||
| 
 | ||||
|     def cancelled(self): | ||||
|         return self.__cancelled | ||||
| 
 | ||||
|     def done(self): | ||||
|         return (self.__cancelled | ||||
|                 or self.__result is not None | ||||
|                 or self.__exception is not None) | ||||
| 
 | ||||
|     def result(self): | ||||
|         assert not self.cancelled() | ||||
|         if self.__exception is not None: | ||||
|             raise self.__exception | ||||
|         return self.__result | ||||
| 
 | ||||
|     def exception(self): | ||||
|         assert not self.cancelled() | ||||
|         return self.__exception | ||||
| 
 | ||||
|     def set_result(self, result): | ||||
|         assert not self.done() | ||||
|         assert result is not None | ||||
|         self.__result = result | ||||
| 
 | ||||
|     def set_exception(self, exception): | ||||
|         assert not self.done() | ||||
|         assert exception is not None | ||||
|         self.__exception = exception | ||||
| 
 | ||||
|     def __iter__(self): | ||||
|         if not self.done(): | ||||
|             self._asyncio_future_blocking = True | ||||
|             yield self | ||||
|         assert self.done() | ||||
|         return self.result() | ||||
| 
 | ||||
| 
 | ||||
| class DuckTests(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = self.new_test_loop() | ||||
|         self.addCleanup(self.loop.close) | ||||
| 
 | ||||
|     def test_wrap_future(self): | ||||
|         f = DuckFuture() | ||||
|         g = asyncio.wrap_future(f) | ||||
|         assert g is f | ||||
| 
 | ||||
|     def test_ensure_future(self): | ||||
|         f = DuckFuture() | ||||
|         g = asyncio.ensure_future(f) | ||||
|         assert g is f | ||||
| 
 | ||||
| 
 | ||||
| class BaseFutureTests: | ||||
| 
 | ||||
|     def _new_future(self,  *args, **kwargs): | ||||
|         return self.cls(*args, **kwargs) | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = self.new_test_loop() | ||||
|         self.addCleanup(self.loop.close) | ||||
| 
 | ||||
|     def test_isfuture(self): | ||||
|         class MyFuture: | ||||
|             _asyncio_future_blocking = None | ||||
| 
 | ||||
|             def __init__(self): | ||||
|                 self._asyncio_future_blocking = False | ||||
| 
 | ||||
|         self.assertFalse(asyncio.isfuture(MyFuture)) | ||||
|         self.assertTrue(asyncio.isfuture(MyFuture())) | ||||
|         self.assertFalse(asyncio.isfuture(1)) | ||||
| 
 | ||||
|         # As `isinstance(Mock(), Future)` returns `False` | ||||
|         self.assertFalse(asyncio.isfuture(mock.Mock())) | ||||
| 
 | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         self.assertTrue(asyncio.isfuture(f)) | ||||
|         self.assertFalse(asyncio.isfuture(type(f))) | ||||
| 
 | ||||
|         # As `isinstance(Mock(Future), Future)` returns `True` | ||||
|         self.assertTrue(asyncio.isfuture(mock.Mock(type(f)))) | ||||
| 
 | ||||
|         f.cancel() | ||||
| 
 | ||||
|     def test_initial_state(self): | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         self.assertFalse(f.cancelled()) | ||||
|         self.assertFalse(f.done()) | ||||
|         f.cancel() | ||||
|         self.assertTrue(f.cancelled()) | ||||
| 
 | ||||
|     def test_init_constructor_default_loop(self): | ||||
|         asyncio.set_event_loop(self.loop) | ||||
|         f = self._new_future() | ||||
|         self.assertIs(f._loop, self.loop) | ||||
| 
 | ||||
|     def test_constructor_positional(self): | ||||
|         # Make sure Future doesn't accept a positional argument | ||||
|         self.assertRaises(TypeError, self._new_future, 42) | ||||
| 
 | ||||
|     def test_uninitialized(self): | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         self.assertRaises(asyncio.InvalidStateError, fut.result) | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         self.assertRaises(asyncio.InvalidStateError, fut.exception) | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         with self.assertRaises((RuntimeError, AttributeError)): | ||||
|             fut.set_result(None) | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         with self.assertRaises((RuntimeError, AttributeError)): | ||||
|             fut.set_exception(Exception) | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         with self.assertRaises((RuntimeError, AttributeError)): | ||||
|             fut.cancel() | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         with self.assertRaises((RuntimeError, AttributeError)): | ||||
|             fut.add_done_callback(lambda f: None) | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         with self.assertRaises((RuntimeError, AttributeError)): | ||||
|             fut.remove_done_callback(lambda f: None) | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         with self.assertRaises((RuntimeError, AttributeError)): | ||||
|             fut._schedule_callbacks() | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         try: | ||||
|             repr(fut) | ||||
|         except AttributeError: | ||||
|             pass | ||||
|         fut = self.cls.__new__(self.cls, loop=self.loop) | ||||
|         fut.cancelled() | ||||
|         fut.done() | ||||
|         iter(fut) | ||||
| 
 | ||||
|     def test_cancel(self): | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         self.assertTrue(f.cancel()) | ||||
|         self.assertTrue(f.cancelled()) | ||||
|         self.assertTrue(f.done()) | ||||
|         self.assertRaises(asyncio.CancelledError, f.result) | ||||
|         self.assertRaises(asyncio.CancelledError, f.exception) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.set_result, None) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) | ||||
|         self.assertFalse(f.cancel()) | ||||
| 
 | ||||
|     def test_result(self): | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.result) | ||||
| 
 | ||||
|         f.set_result(42) | ||||
|         self.assertFalse(f.cancelled()) | ||||
|         self.assertTrue(f.done()) | ||||
|         self.assertEqual(f.result(), 42) | ||||
|         self.assertEqual(f.exception(), None) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.set_result, None) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) | ||||
|         self.assertFalse(f.cancel()) | ||||
| 
 | ||||
|     def test_exception(self): | ||||
|         exc = RuntimeError() | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.exception) | ||||
| 
 | ||||
|         # StopIteration cannot be raised into a Future - CPython issue26221 | ||||
|         self.assertRaisesRegex(TypeError, "StopIteration .* cannot be raised", | ||||
|                                f.set_exception, StopIteration) | ||||
| 
 | ||||
|         f.set_exception(exc) | ||||
|         self.assertFalse(f.cancelled()) | ||||
|         self.assertTrue(f.done()) | ||||
|         self.assertRaises(RuntimeError, f.result) | ||||
|         self.assertEqual(f.exception(), exc) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.set_result, None) | ||||
|         self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) | ||||
|         self.assertFalse(f.cancel()) | ||||
| 
 | ||||
|     def test_exception_class(self): | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         f.set_exception(RuntimeError) | ||||
|         self.assertIsInstance(f.exception(), RuntimeError) | ||||
| 
 | ||||
|     def test_yield_from_twice(self): | ||||
|         f = self._new_future(loop=self.loop) | ||||
| 
 | ||||
|         def fixture(): | ||||
|             yield 'A' | ||||
|             x = yield from f | ||||
|             yield 'B', x | ||||
|             y = yield from f | ||||
|             yield 'C', y | ||||
| 
 | ||||
|         g = fixture() | ||||
|         self.assertEqual(next(g), 'A')  # yield 'A'. | ||||
|         self.assertEqual(next(g), f)  # First yield from f. | ||||
|         f.set_result(42) | ||||
|         self.assertEqual(next(g), ('B', 42))  # yield 'B', x. | ||||
|         # The second "yield from f" does not yield f. | ||||
|         self.assertEqual(next(g), ('C', 42))  # yield 'C', y. | ||||
| 
 | ||||
|     def test_future_repr(self): | ||||
|         self.loop.set_debug(True) | ||||
|         f_pending_debug = self._new_future(loop=self.loop) | ||||
|         frame = f_pending_debug._source_traceback[-1] | ||||
|         self.assertEqual(repr(f_pending_debug), | ||||
|                          '<Future pending created at %s:%s>' | ||||
|                          % (frame[0], frame[1])) | ||||
|         f_pending_debug.cancel() | ||||
| 
 | ||||
|         self.loop.set_debug(False) | ||||
|         f_pending = self._new_future(loop=self.loop) | ||||
|         self.assertEqual(repr(f_pending), '<Future pending>') | ||||
|         f_pending.cancel() | ||||
| 
 | ||||
|         f_cancelled = self._new_future(loop=self.loop) | ||||
|         f_cancelled.cancel() | ||||
|         self.assertEqual(repr(f_cancelled), '<Future cancelled>') | ||||
| 
 | ||||
|         f_result = self._new_future(loop=self.loop) | ||||
|         f_result.set_result(4) | ||||
|         self.assertEqual(repr(f_result), '<Future finished result=4>') | ||||
|         self.assertEqual(f_result.result(), 4) | ||||
| 
 | ||||
|         exc = RuntimeError() | ||||
|         f_exception = self._new_future(loop=self.loop) | ||||
|         f_exception.set_exception(exc) | ||||
|         self.assertEqual(repr(f_exception), | ||||
|                          '<Future finished exception=RuntimeError()>') | ||||
|         self.assertIs(f_exception.exception(), exc) | ||||
| 
 | ||||
|         def func_repr(func): | ||||
|             filename, lineno = test_utils.get_function_source(func) | ||||
|             text = '%s() at %s:%s' % (func.__qualname__, filename, lineno) | ||||
|             return re.escape(text) | ||||
| 
 | ||||
|         f_one_callbacks = self._new_future(loop=self.loop) | ||||
|         f_one_callbacks.add_done_callback(_fakefunc) | ||||
|         fake_repr = func_repr(_fakefunc) | ||||
|         self.assertRegex(repr(f_one_callbacks), | ||||
|                          r'<Future pending cb=\[%s\]>' % fake_repr) | ||||
|         f_one_callbacks.cancel() | ||||
|         self.assertEqual(repr(f_one_callbacks), | ||||
|                          '<Future cancelled>') | ||||
| 
 | ||||
|         f_two_callbacks = self._new_future(loop=self.loop) | ||||
|         f_two_callbacks.add_done_callback(first_cb) | ||||
|         f_two_callbacks.add_done_callback(last_cb) | ||||
|         first_repr = func_repr(first_cb) | ||||
|         last_repr = func_repr(last_cb) | ||||
|         self.assertRegex(repr(f_two_callbacks), | ||||
|                          r'<Future pending cb=\[%s, %s\]>' | ||||
|                          % (first_repr, last_repr)) | ||||
| 
 | ||||
|         f_many_callbacks = self._new_future(loop=self.loop) | ||||
|         f_many_callbacks.add_done_callback(first_cb) | ||||
|         for i in range(8): | ||||
|             f_many_callbacks.add_done_callback(_fakefunc) | ||||
|         f_many_callbacks.add_done_callback(last_cb) | ||||
|         cb_regex = r'%s, <8 more>, %s' % (first_repr, last_repr) | ||||
|         self.assertRegex(repr(f_many_callbacks), | ||||
|                          r'<Future pending cb=\[%s\]>' % cb_regex) | ||||
|         f_many_callbacks.cancel() | ||||
|         self.assertEqual(repr(f_many_callbacks), | ||||
|                          '<Future cancelled>') | ||||
| 
 | ||||
|     def test_copy_state(self): | ||||
|         from asyncio.futures import _copy_future_state | ||||
| 
 | ||||
|         f = self._new_future(loop=self.loop) | ||||
|         f.set_result(10) | ||||
| 
 | ||||
|         newf = self._new_future(loop=self.loop) | ||||
|         _copy_future_state(f, newf) | ||||
|         self.assertTrue(newf.done()) | ||||
|         self.assertEqual(newf.result(), 10) | ||||
| 
 | ||||
|         f_exception = self._new_future(loop=self.loop) | ||||
|         f_exception.set_exception(RuntimeError()) | ||||
| 
 | ||||
|         newf_exception = self._new_future(loop=self.loop) | ||||
|         _copy_future_state(f_exception, newf_exception) | ||||
|         self.assertTrue(newf_exception.done()) | ||||
|         self.assertRaises(RuntimeError, newf_exception.result) | ||||
| 
 | ||||
|         f_cancelled = self._new_future(loop=self.loop) | ||||
|         f_cancelled.cancel() | ||||
| 
 | ||||
|         newf_cancelled = self._new_future(loop=self.loop) | ||||
|         _copy_future_state(f_cancelled, newf_cancelled) | ||||
|         self.assertTrue(newf_cancelled.cancelled()) | ||||
| 
 | ||||
|     def test_iter(self): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
| 
 | ||||
|         def coro(): | ||||
|             yield from fut | ||||
| 
 | ||||
|         def test(): | ||||
|             arg1, arg2 = coro() | ||||
| 
 | ||||
|         self.assertRaises(AssertionError, test) | ||||
|         fut.cancel() | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_abandoned(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         del fut | ||||
|         self.assertFalse(m_log.error.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_not_called_after_cancel(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_exception(Exception()) | ||||
|         fut.cancel() | ||||
|         del fut | ||||
|         self.assertFalse(m_log.error.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_result_unretrieved(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_result(42) | ||||
|         del fut | ||||
|         self.assertFalse(m_log.error.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_result_retrieved(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_result(42) | ||||
|         fut.result() | ||||
|         del fut | ||||
|         self.assertFalse(m_log.error.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_exception_unretrieved(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_exception(RuntimeError('boom')) | ||||
|         del fut | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         support.gc_collect() | ||||
|         self.assertTrue(m_log.error.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_exception_retrieved(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_exception(RuntimeError('boom')) | ||||
|         fut.exception() | ||||
|         del fut | ||||
|         self.assertFalse(m_log.error.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_tb_logger_exception_result_retrieved(self, m_log): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_exception(RuntimeError('boom')) | ||||
|         self.assertRaises(RuntimeError, fut.result) | ||||
|         del fut | ||||
|         self.assertFalse(m_log.error.called) | ||||
| 
 | ||||
|     def test_wrap_future(self): | ||||
| 
 | ||||
|         def run(arg): | ||||
|             return (arg, threading.get_ident()) | ||||
|         ex = concurrent.futures.ThreadPoolExecutor(1) | ||||
|         f1 = ex.submit(run, 'oi') | ||||
|         f2 = asyncio.wrap_future(f1, loop=self.loop) | ||||
|         res, ident = self.loop.run_until_complete(f2) | ||||
|         self.assertTrue(asyncio.isfuture(f2)) | ||||
|         self.assertEqual(res, 'oi') | ||||
|         self.assertNotEqual(ident, threading.get_ident()) | ||||
|         ex.shutdown(wait=True) | ||||
| 
 | ||||
|     def test_wrap_future_future(self): | ||||
|         f1 = self._new_future(loop=self.loop) | ||||
|         f2 = asyncio.wrap_future(f1) | ||||
|         self.assertIs(f1, f2) | ||||
| 
 | ||||
|     def test_wrap_future_use_global_loop(self): | ||||
|         with mock.patch('asyncio.futures.events') as events: | ||||
|             events.get_event_loop = lambda: self.loop | ||||
|             def run(arg): | ||||
|                 return (arg, threading.get_ident()) | ||||
|             ex = concurrent.futures.ThreadPoolExecutor(1) | ||||
|             f1 = ex.submit(run, 'oi') | ||||
|             f2 = asyncio.wrap_future(f1) | ||||
|             self.assertIs(self.loop, f2._loop) | ||||
|             ex.shutdown(wait=True) | ||||
| 
 | ||||
|     def test_wrap_future_cancel(self): | ||||
|         f1 = concurrent.futures.Future() | ||||
|         f2 = asyncio.wrap_future(f1, loop=self.loop) | ||||
|         f2.cancel() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertTrue(f1.cancelled()) | ||||
|         self.assertTrue(f2.cancelled()) | ||||
| 
 | ||||
|     def test_wrap_future_cancel2(self): | ||||
|         f1 = concurrent.futures.Future() | ||||
|         f2 = asyncio.wrap_future(f1, loop=self.loop) | ||||
|         f1.set_result(42) | ||||
|         f2.cancel() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertFalse(f1.cancelled()) | ||||
|         self.assertEqual(f1.result(), 42) | ||||
|         self.assertTrue(f2.cancelled()) | ||||
| 
 | ||||
|     def test_future_source_traceback(self): | ||||
|         self.loop.set_debug(True) | ||||
| 
 | ||||
|         future = self._new_future(loop=self.loop) | ||||
|         lineno = sys._getframe().f_lineno - 1 | ||||
|         self.assertIsInstance(future._source_traceback, list) | ||||
|         self.assertEqual(future._source_traceback[-2][:3], | ||||
|                          (__file__, | ||||
|                           lineno, | ||||
|                           'test_future_source_traceback')) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def check_future_exception_never_retrieved(self, debug, m_log): | ||||
|         self.loop.set_debug(debug) | ||||
| 
 | ||||
|         def memory_error(): | ||||
|             try: | ||||
|                 raise MemoryError() | ||||
|             except BaseException as exc: | ||||
|                 return exc | ||||
|         exc = memory_error() | ||||
| 
 | ||||
|         future = self._new_future(loop=self.loop) | ||||
|         future.set_exception(exc) | ||||
|         future = None | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         support.gc_collect() | ||||
| 
 | ||||
|         if sys.version_info >= (3, 4): | ||||
|             regex = r'^Future exception was never retrieved\n' | ||||
|             exc_info = (type(exc), exc, exc.__traceback__) | ||||
|             m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) | ||||
|         else: | ||||
|             regex = r'^Future/Task exception was never retrieved\n' | ||||
|             m_log.error.assert_called_once_with(mock.ANY, exc_info=False) | ||||
|         message = m_log.error.call_args[0][0] | ||||
|         self.assertRegex(message, re.compile(regex, re.DOTALL)) | ||||
| 
 | ||||
|     def test_future_exception_never_retrieved(self): | ||||
|         self.check_future_exception_never_retrieved(False) | ||||
| 
 | ||||
|     def test_future_exception_never_retrieved_debug(self): | ||||
|         self.check_future_exception_never_retrieved(True) | ||||
| 
 | ||||
|     def test_set_result_unless_cancelled(self): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.cancel() | ||||
|         futures._set_result_unless_cancelled(fut, 2) | ||||
|         self.assertTrue(fut.cancelled()) | ||||
| 
 | ||||
|     def test_future_stop_iteration_args(self): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fut.set_result((1, 2)) | ||||
|         fi = fut.__iter__() | ||||
|         result = None | ||||
|         try: | ||||
|             fi.send(None) | ||||
|         except StopIteration as ex: | ||||
|             result = ex.args[0] | ||||
|         else: | ||||
|             self.fail('StopIteration was expected') | ||||
|         self.assertEqual(result, (1, 2)) | ||||
| 
 | ||||
|     def test_future_iter_throw(self): | ||||
|         fut = self._new_future(loop=self.loop) | ||||
|         fi = iter(fut) | ||||
|         self.assertRaises(TypeError, fi.throw, | ||||
|                           Exception, Exception("elephant"), 32) | ||||
|         self.assertRaises(TypeError, fi.throw, | ||||
|                           Exception("elephant"), Exception("elephant")) | ||||
|         self.assertRaises(TypeError, fi.throw, list) | ||||
| 
 | ||||
|     def test_future_del_collect(self): | ||||
|         class Evil: | ||||
|             def __del__(self): | ||||
|                 gc.collect() | ||||
| 
 | ||||
|         for i in range(100): | ||||
|             fut = self._new_future(loop=self.loop) | ||||
|             fut.set_result(Evil()) | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipUnless(hasattr(futures, '_CFuture'), | ||||
|                      'requires the C _asyncio module') | ||||
| class CFutureTests(BaseFutureTests, test_utils.TestCase): | ||||
|     cls = getattr(futures, '_CFuture') | ||||
| 
 | ||||
| 
 | ||||
| class PyFutureTests(BaseFutureTests, test_utils.TestCase): | ||||
|     cls = futures._PyFuture | ||||
| 
 | ||||
| 
 | ||||
| class BaseFutureDoneCallbackTests(): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = self.new_test_loop() | ||||
| 
 | ||||
|     def run_briefly(self): | ||||
|         test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|     def _make_callback(self, bag, thing): | ||||
|         # Create a callback function that appends thing to bag. | ||||
|         def bag_appender(future): | ||||
|             bag.append(thing) | ||||
|         return bag_appender | ||||
| 
 | ||||
|     def _new_future(self): | ||||
|         raise NotImplementedError | ||||
| 
 | ||||
|     def test_callbacks_invoked_on_set_result(self): | ||||
|         bag = [] | ||||
|         f = self._new_future() | ||||
|         f.add_done_callback(self._make_callback(bag, 42)) | ||||
|         f.add_done_callback(self._make_callback(bag, 17)) | ||||
| 
 | ||||
|         self.assertEqual(bag, []) | ||||
|         f.set_result('foo') | ||||
| 
 | ||||
|         self.run_briefly() | ||||
| 
 | ||||
|         self.assertEqual(bag, [42, 17]) | ||||
|         self.assertEqual(f.result(), 'foo') | ||||
| 
 | ||||
|     def test_callbacks_invoked_on_set_exception(self): | ||||
|         bag = [] | ||||
|         f = self._new_future() | ||||
|         f.add_done_callback(self._make_callback(bag, 100)) | ||||
| 
 | ||||
|         self.assertEqual(bag, []) | ||||
|         exc = RuntimeError() | ||||
|         f.set_exception(exc) | ||||
| 
 | ||||
|         self.run_briefly() | ||||
| 
 | ||||
|         self.assertEqual(bag, [100]) | ||||
|         self.assertEqual(f.exception(), exc) | ||||
| 
 | ||||
|     def test_remove_done_callback(self): | ||||
|         bag = [] | ||||
|         f = self._new_future() | ||||
|         cb1 = self._make_callback(bag, 1) | ||||
|         cb2 = self._make_callback(bag, 2) | ||||
|         cb3 = self._make_callback(bag, 3) | ||||
| 
 | ||||
|         # Add one cb1 and one cb2. | ||||
|         f.add_done_callback(cb1) | ||||
|         f.add_done_callback(cb2) | ||||
| 
 | ||||
|         # One instance of cb2 removed. Now there's only one cb1. | ||||
|         self.assertEqual(f.remove_done_callback(cb2), 1) | ||||
| 
 | ||||
|         # Never had any cb3 in there. | ||||
|         self.assertEqual(f.remove_done_callback(cb3), 0) | ||||
| 
 | ||||
|         # After this there will be 6 instances of cb1 and one of cb2. | ||||
|         f.add_done_callback(cb2) | ||||
|         for i in range(5): | ||||
|             f.add_done_callback(cb1) | ||||
| 
 | ||||
|         # Remove all instances of cb1. One cb2 remains. | ||||
|         self.assertEqual(f.remove_done_callback(cb1), 6) | ||||
| 
 | ||||
|         self.assertEqual(bag, []) | ||||
|         f.set_result('foo') | ||||
| 
 | ||||
|         self.run_briefly() | ||||
| 
 | ||||
|         self.assertEqual(bag, [2]) | ||||
|         self.assertEqual(f.result(), 'foo') | ||||
| 
 | ||||
|     def test_remove_done_callbacks_list_mutation(self): | ||||
|         # see http://bugs.python.org/issue28963 for details | ||||
| 
 | ||||
|         fut = self._new_future() | ||||
|         fut.add_done_callback(str) | ||||
| 
 | ||||
|         for _ in range(63): | ||||
|             fut.add_done_callback(id) | ||||
| 
 | ||||
|         class evil: | ||||
|             def __eq__(self, other): | ||||
|                 fut.remove_done_callback(id) | ||||
|                 return False | ||||
| 
 | ||||
|         fut.remove_done_callback(evil()) | ||||
| 
 | ||||
|     def test_schedule_callbacks_list_mutation_1(self): | ||||
|         # see http://bugs.python.org/issue28963 for details | ||||
| 
 | ||||
|         def mut(f): | ||||
|             f.remove_done_callback(str) | ||||
| 
 | ||||
|         fut = self._new_future() | ||||
|         fut.add_done_callback(mut) | ||||
|         fut.add_done_callback(str) | ||||
|         fut.add_done_callback(str) | ||||
|         fut.set_result(1) | ||||
|         test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|     def test_schedule_callbacks_list_mutation_2(self): | ||||
|         # see http://bugs.python.org/issue30828 for details | ||||
| 
 | ||||
|         fut = self._new_future() | ||||
|         fut.add_done_callback(str) | ||||
| 
 | ||||
|         for _ in range(63): | ||||
|             fut.add_done_callback(id) | ||||
| 
 | ||||
|         max_extra_cbs = 100 | ||||
|         extra_cbs = 0 | ||||
| 
 | ||||
|         class evil: | ||||
|             def __eq__(self, other): | ||||
|                 nonlocal extra_cbs | ||||
|                 extra_cbs += 1 | ||||
|                 if extra_cbs < max_extra_cbs: | ||||
|                     fut.add_done_callback(id) | ||||
|                 return False | ||||
| 
 | ||||
|         fut.remove_done_callback(evil()) | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipUnless(hasattr(futures, '_CFuture'), | ||||
|                      'requires the C _asyncio module') | ||||
| class CFutureDoneCallbackTests(BaseFutureDoneCallbackTests, | ||||
|                                test_utils.TestCase): | ||||
| 
 | ||||
|     def _new_future(self): | ||||
|         return futures._CFuture(loop=self.loop) | ||||
| 
 | ||||
| 
 | ||||
| class PyFutureDoneCallbackTests(BaseFutureDoneCallbackTests, | ||||
|                                 test_utils.TestCase): | ||||
| 
 | ||||
|     def _new_future(self): | ||||
|         return futures._PyFuture(loop=self.loop) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										1016
									
								
								third_party/python/Lib/test/test_asyncio/test_locks.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1016
									
								
								third_party/python/Lib/test/test_asyncio/test_locks.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										232
									
								
								third_party/python/Lib/test/test_asyncio/test_pep492.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								third_party/python/Lib/test/test_asyncio/test_pep492.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,232 @@ | |||
| """Tests support for new syntax introduced by PEP 492.""" | ||||
| 
 | ||||
| import collections.abc | ||||
| import types | ||||
| import unittest | ||||
| 
 | ||||
| try: | ||||
|     from test import support | ||||
| except ImportError: | ||||
|     from asyncio import test_support as support | ||||
| from unittest import mock | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import test_utils | ||||
| 
 | ||||
| 
 | ||||
| class BaseTest(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = asyncio.BaseEventLoop() | ||||
|         self.loop._process_events = mock.Mock() | ||||
|         self.loop._selector = mock.Mock() | ||||
|         self.loop._selector.select.return_value = () | ||||
|         self.set_event_loop(self.loop) | ||||
| 
 | ||||
| 
 | ||||
| class LockTests(BaseTest): | ||||
| 
 | ||||
|     def test_context_manager_async_with(self): | ||||
|         primitives = [ | ||||
|             asyncio.Lock(loop=self.loop), | ||||
|             asyncio.Condition(loop=self.loop), | ||||
|             asyncio.Semaphore(loop=self.loop), | ||||
|             asyncio.BoundedSemaphore(loop=self.loop), | ||||
|         ] | ||||
| 
 | ||||
|         async def test(lock): | ||||
|             await asyncio.sleep(0.01, loop=self.loop) | ||||
|             self.assertFalse(lock.locked()) | ||||
|             async with lock as _lock: | ||||
|                 self.assertIs(_lock, None) | ||||
|                 self.assertTrue(lock.locked()) | ||||
|                 await asyncio.sleep(0.01, loop=self.loop) | ||||
|                 self.assertTrue(lock.locked()) | ||||
|             self.assertFalse(lock.locked()) | ||||
| 
 | ||||
|         for primitive in primitives: | ||||
|             self.loop.run_until_complete(test(primitive)) | ||||
|             self.assertFalse(primitive.locked()) | ||||
| 
 | ||||
|     def test_context_manager_with_await(self): | ||||
|         primitives = [ | ||||
|             asyncio.Lock(loop=self.loop), | ||||
|             asyncio.Condition(loop=self.loop), | ||||
|             asyncio.Semaphore(loop=self.loop), | ||||
|             asyncio.BoundedSemaphore(loop=self.loop), | ||||
|         ] | ||||
| 
 | ||||
|         async def test(lock): | ||||
|             await asyncio.sleep(0.01, loop=self.loop) | ||||
|             self.assertFalse(lock.locked()) | ||||
|             with await lock as _lock: | ||||
|                 self.assertIs(_lock, None) | ||||
|                 self.assertTrue(lock.locked()) | ||||
|                 await asyncio.sleep(0.01, loop=self.loop) | ||||
|                 self.assertTrue(lock.locked()) | ||||
|             self.assertFalse(lock.locked()) | ||||
| 
 | ||||
|         for primitive in primitives: | ||||
|             self.loop.run_until_complete(test(primitive)) | ||||
|             self.assertFalse(primitive.locked()) | ||||
| 
 | ||||
| 
 | ||||
| class StreamReaderTests(BaseTest): | ||||
| 
 | ||||
|     def test_readline(self): | ||||
|         DATA = b'line1\nline2\nline3' | ||||
| 
 | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(DATA) | ||||
|         stream.feed_eof() | ||||
| 
 | ||||
|         async def reader(): | ||||
|             data = [] | ||||
|             async for line in stream: | ||||
|                 data.append(line) | ||||
|             return data | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(reader()) | ||||
|         self.assertEqual(data, [b'line1\n', b'line2\n', b'line3']) | ||||
| 
 | ||||
| 
 | ||||
| class CoroutineTests(BaseTest): | ||||
| 
 | ||||
|     def test_iscoroutine(self): | ||||
|         async def foo(): pass | ||||
| 
 | ||||
|         f = foo() | ||||
|         try: | ||||
|             self.assertTrue(asyncio.iscoroutine(f)) | ||||
|         finally: | ||||
|             f.close() # silence warning | ||||
| 
 | ||||
|         # Test that asyncio.iscoroutine() uses collections.abc.Coroutine | ||||
|         class FakeCoro: | ||||
|             def send(self, value): pass | ||||
|             def throw(self, typ, val=None, tb=None): pass | ||||
|             def close(self): pass | ||||
|             def __await__(self): yield | ||||
| 
 | ||||
|         self.assertTrue(asyncio.iscoroutine(FakeCoro())) | ||||
| 
 | ||||
|     def test_iscoroutinefunction(self): | ||||
|         async def foo(): pass | ||||
|         self.assertTrue(asyncio.iscoroutinefunction(foo)) | ||||
| 
 | ||||
|     def test_function_returning_awaitable(self): | ||||
|         class Awaitable: | ||||
|             def __await__(self): | ||||
|                 return ('spam',) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def func(): | ||||
|             return Awaitable() | ||||
| 
 | ||||
|         coro = func() | ||||
|         self.assertEqual(coro.send(None), 'spam') | ||||
|         coro.close() | ||||
| 
 | ||||
|     def test_async_def_coroutines(self): | ||||
|         async def bar(): | ||||
|             return 'spam' | ||||
|         async def foo(): | ||||
|             return await bar() | ||||
| 
 | ||||
|         # production mode | ||||
|         data = self.loop.run_until_complete(foo()) | ||||
|         self.assertEqual(data, 'spam') | ||||
| 
 | ||||
|         # debug mode | ||||
|         self.loop.set_debug(True) | ||||
|         data = self.loop.run_until_complete(foo()) | ||||
|         self.assertEqual(data, 'spam') | ||||
| 
 | ||||
|     @mock.patch('asyncio.coroutines.logger') | ||||
|     def test_async_def_wrapped(self, m_log): | ||||
|         async def foo(): | ||||
|             pass | ||||
|         async def start(): | ||||
|             foo_coro = foo() | ||||
|             self.assertRegex( | ||||
|                 repr(foo_coro), | ||||
|                 r'<CoroWrapper .*\.foo\(\) running at .*pep492.*>') | ||||
| 
 | ||||
|             with support.check_warnings((r'.*foo.*was never', | ||||
|                                          RuntimeWarning)): | ||||
|                 foo_coro = None | ||||
|                 support.gc_collect() | ||||
|                 self.assertTrue(m_log.error.called) | ||||
|                 message = m_log.error.call_args[0][0] | ||||
|                 self.assertRegex(message, | ||||
|                                  r'CoroWrapper.*foo.*was never') | ||||
| 
 | ||||
|         self.loop.set_debug(True) | ||||
|         self.loop.run_until_complete(start()) | ||||
| 
 | ||||
|         async def start(): | ||||
|             foo_coro = foo() | ||||
|             task = asyncio.ensure_future(foo_coro, loop=self.loop) | ||||
|             self.assertRegex(repr(task), r'Task.*foo.*running') | ||||
| 
 | ||||
|         self.loop.run_until_complete(start()) | ||||
| 
 | ||||
| 
 | ||||
|     def test_types_coroutine(self): | ||||
|         def gen(): | ||||
|             yield from () | ||||
|             return 'spam' | ||||
| 
 | ||||
|         @types.coroutine | ||||
|         def func(): | ||||
|             return gen() | ||||
| 
 | ||||
|         async def coro(): | ||||
|             wrapper = func() | ||||
|             self.assertIsInstance(wrapper, types._GeneratorWrapper) | ||||
|             return await wrapper | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(coro()) | ||||
|         self.assertEqual(data, 'spam') | ||||
| 
 | ||||
|     def test_task_print_stack(self): | ||||
|         T = None | ||||
| 
 | ||||
|         async def foo(): | ||||
|             f = T.get_stack(limit=1) | ||||
|             try: | ||||
|                 self.assertEqual(f[0].f_code.co_name, 'foo') | ||||
|             finally: | ||||
|                 f = None | ||||
| 
 | ||||
|         async def runner(): | ||||
|             nonlocal T | ||||
|             T = asyncio.ensure_future(foo(), loop=self.loop) | ||||
|             await T | ||||
| 
 | ||||
|         self.loop.run_until_complete(runner()) | ||||
| 
 | ||||
|     def test_double_await(self): | ||||
|         async def afunc(): | ||||
|             await asyncio.sleep(0.1, loop=self.loop) | ||||
| 
 | ||||
|         async def runner(): | ||||
|             coro = afunc() | ||||
|             t = asyncio.Task(coro, loop=self.loop) | ||||
|             try: | ||||
|                 await asyncio.sleep(0, loop=self.loop) | ||||
|                 await coro | ||||
|             finally: | ||||
|                 t.cancel() | ||||
| 
 | ||||
|         self.loop.set_debug(True) | ||||
|         with self.assertRaisesRegex( | ||||
|             RuntimeError, | ||||
|             r'Cannot await.*test_double_await.*\bafunc\b.*while.*\bsleep\b'): | ||||
| 
 | ||||
|             self.loop.run_until_complete(runner()) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										605
									
								
								third_party/python/Lib/test/test_asyncio/test_proactor_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										605
									
								
								third_party/python/Lib/test/test_asyncio/test_proactor_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,605 @@ | |||
| """Tests for proactor_events.py""" | ||||
| 
 | ||||
| import socket | ||||
| import unittest | ||||
| from unittest import mock | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio.proactor_events import BaseProactorEventLoop | ||||
| from asyncio.proactor_events import _ProactorSocketTransport | ||||
| from asyncio.proactor_events import _ProactorWritePipeTransport | ||||
| from asyncio.proactor_events import _ProactorDuplexPipeTransport | ||||
| from asyncio import test_utils | ||||
| 
 | ||||
| 
 | ||||
| def close_transport(transport): | ||||
|     # Don't call transport.close() because the event loop and the IOCP proactor | ||||
|     # are mocked | ||||
|     if transport._sock is None: | ||||
|         return | ||||
|     transport._sock.close() | ||||
|     transport._sock = None | ||||
| 
 | ||||
| 
 | ||||
| class ProactorSocketTransportTests(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = self.new_test_loop() | ||||
|         self.addCleanup(self.loop.close) | ||||
|         self.proactor = mock.Mock() | ||||
|         self.loop._proactor = self.proactor | ||||
|         self.protocol = test_utils.make_test_protocol(asyncio.Protocol) | ||||
|         self.sock = mock.Mock(socket.socket) | ||||
| 
 | ||||
|     def socket_transport(self, waiter=None): | ||||
|         transport = _ProactorSocketTransport(self.loop, self.sock, | ||||
|                                              self.protocol, waiter=waiter) | ||||
|         self.addCleanup(close_transport, transport) | ||||
|         return transport | ||||
| 
 | ||||
|     def test_ctor(self): | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         tr = self.socket_transport(waiter=fut) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertIsNone(fut.result()) | ||||
|         self.protocol.connection_made(tr) | ||||
|         self.proactor.recv.assert_called_with(self.sock, 4096) | ||||
| 
 | ||||
|     def test_loop_reading(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._loop_reading() | ||||
|         self.loop._proactor.recv.assert_called_with(self.sock, 4096) | ||||
|         self.assertFalse(self.protocol.data_received.called) | ||||
|         self.assertFalse(self.protocol.eof_received.called) | ||||
| 
 | ||||
|     def test_loop_reading_data(self): | ||||
|         res = asyncio.Future(loop=self.loop) | ||||
|         res.set_result(b'data') | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._read_fut = res | ||||
|         tr._loop_reading(res) | ||||
|         self.loop._proactor.recv.assert_called_with(self.sock, 4096) | ||||
|         self.protocol.data_received.assert_called_with(b'data') | ||||
| 
 | ||||
|     def test_loop_reading_no_data(self): | ||||
|         res = asyncio.Future(loop=self.loop) | ||||
|         res.set_result(b'') | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         self.assertRaises(AssertionError, tr._loop_reading, res) | ||||
| 
 | ||||
|         tr.close = mock.Mock() | ||||
|         tr._read_fut = res | ||||
|         tr._loop_reading(res) | ||||
|         self.assertFalse(self.loop._proactor.recv.called) | ||||
|         self.assertTrue(self.protocol.eof_received.called) | ||||
|         self.assertTrue(tr.close.called) | ||||
| 
 | ||||
|     def test_loop_reading_aborted(self): | ||||
|         err = self.loop._proactor.recv.side_effect = ConnectionAbortedError() | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._fatal_error = mock.Mock() | ||||
|         tr._loop_reading() | ||||
|         tr._fatal_error.assert_called_with( | ||||
|                             err, | ||||
|                             'Fatal read error on pipe transport') | ||||
| 
 | ||||
|     def test_loop_reading_aborted_closing(self): | ||||
|         self.loop._proactor.recv.side_effect = ConnectionAbortedError() | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._closing = True | ||||
|         tr._fatal_error = mock.Mock() | ||||
|         tr._loop_reading() | ||||
|         self.assertFalse(tr._fatal_error.called) | ||||
| 
 | ||||
|     def test_loop_reading_aborted_is_fatal(self): | ||||
|         self.loop._proactor.recv.side_effect = ConnectionAbortedError() | ||||
|         tr = self.socket_transport() | ||||
|         tr._closing = False | ||||
|         tr._fatal_error = mock.Mock() | ||||
|         tr._loop_reading() | ||||
|         self.assertTrue(tr._fatal_error.called) | ||||
| 
 | ||||
|     def test_loop_reading_conn_reset_lost(self): | ||||
|         err = self.loop._proactor.recv.side_effect = ConnectionResetError() | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._closing = False | ||||
|         tr._fatal_error = mock.Mock() | ||||
|         tr._force_close = mock.Mock() | ||||
|         tr._loop_reading() | ||||
|         self.assertFalse(tr._fatal_error.called) | ||||
|         tr._force_close.assert_called_with(err) | ||||
| 
 | ||||
|     def test_loop_reading_exception(self): | ||||
|         err = self.loop._proactor.recv.side_effect = (OSError()) | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._fatal_error = mock.Mock() | ||||
|         tr._loop_reading() | ||||
|         tr._fatal_error.assert_called_with( | ||||
|                             err, | ||||
|                             'Fatal read error on pipe transport') | ||||
| 
 | ||||
|     def test_write(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._loop_writing = mock.Mock() | ||||
|         tr.write(b'data') | ||||
|         self.assertEqual(tr._buffer, None) | ||||
|         tr._loop_writing.assert_called_with(data=b'data') | ||||
| 
 | ||||
|     def test_write_no_data(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr.write(b'') | ||||
|         self.assertFalse(tr._buffer) | ||||
| 
 | ||||
|     def test_write_more(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._write_fut = mock.Mock() | ||||
|         tr._loop_writing = mock.Mock() | ||||
|         tr.write(b'data') | ||||
|         self.assertEqual(tr._buffer, b'data') | ||||
|         self.assertFalse(tr._loop_writing.called) | ||||
| 
 | ||||
|     def test_loop_writing(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._buffer = bytearray(b'data') | ||||
|         tr._loop_writing() | ||||
|         self.loop._proactor.send.assert_called_with(self.sock, b'data') | ||||
|         self.loop._proactor.send.return_value.add_done_callback.\ | ||||
|             assert_called_with(tr._loop_writing) | ||||
| 
 | ||||
|     @mock.patch('asyncio.proactor_events.logger') | ||||
|     def test_loop_writing_err(self, m_log): | ||||
|         err = self.loop._proactor.send.side_effect = OSError() | ||||
|         tr = self.socket_transport() | ||||
|         tr._fatal_error = mock.Mock() | ||||
|         tr._buffer = [b'da', b'ta'] | ||||
|         tr._loop_writing() | ||||
|         tr._fatal_error.assert_called_with( | ||||
|                             err, | ||||
|                             'Fatal write error on pipe transport') | ||||
|         tr._conn_lost = 1 | ||||
| 
 | ||||
|         tr.write(b'data') | ||||
|         tr.write(b'data') | ||||
|         tr.write(b'data') | ||||
|         tr.write(b'data') | ||||
|         tr.write(b'data') | ||||
|         self.assertEqual(tr._buffer, None) | ||||
|         m_log.warning.assert_called_with('socket.send() raised exception.') | ||||
| 
 | ||||
|     def test_loop_writing_stop(self): | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         fut.set_result(b'data') | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._write_fut = fut | ||||
|         tr._loop_writing(fut) | ||||
|         self.assertIsNone(tr._write_fut) | ||||
| 
 | ||||
|     def test_loop_writing_closing(self): | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         fut.set_result(1) | ||||
| 
 | ||||
|         tr = self.socket_transport() | ||||
|         tr._write_fut = fut | ||||
|         tr.close() | ||||
|         tr._loop_writing(fut) | ||||
|         self.assertIsNone(tr._write_fut) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.protocol.connection_lost.assert_called_with(None) | ||||
| 
 | ||||
|     def test_abort(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._force_close = mock.Mock() | ||||
|         tr.abort() | ||||
|         tr._force_close.assert_called_with(None) | ||||
| 
 | ||||
|     def test_close(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr.close() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.protocol.connection_lost.assert_called_with(None) | ||||
|         self.assertTrue(tr.is_closing()) | ||||
|         self.assertEqual(tr._conn_lost, 1) | ||||
| 
 | ||||
|         self.protocol.connection_lost.reset_mock() | ||||
|         tr.close() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertFalse(self.protocol.connection_lost.called) | ||||
| 
 | ||||
|     def test_close_write_fut(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._write_fut = mock.Mock() | ||||
|         tr.close() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertFalse(self.protocol.connection_lost.called) | ||||
| 
 | ||||
|     def test_close_buffer(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._buffer = [b'data'] | ||||
|         tr.close() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertFalse(self.protocol.connection_lost.called) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_fatal_error(self, m_logging): | ||||
|         tr = self.socket_transport() | ||||
|         tr._force_close = mock.Mock() | ||||
|         tr._fatal_error(None) | ||||
|         self.assertTrue(tr._force_close.called) | ||||
|         self.assertTrue(m_logging.error.called) | ||||
| 
 | ||||
|     def test_force_close(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._buffer = [b'data'] | ||||
|         read_fut = tr._read_fut = mock.Mock() | ||||
|         write_fut = tr._write_fut = mock.Mock() | ||||
|         tr._force_close(None) | ||||
| 
 | ||||
|         read_fut.cancel.assert_called_with() | ||||
|         write_fut.cancel.assert_called_with() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.protocol.connection_lost.assert_called_with(None) | ||||
|         self.assertEqual(None, tr._buffer) | ||||
|         self.assertEqual(tr._conn_lost, 1) | ||||
| 
 | ||||
|     def test_force_close_idempotent(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._closing = True | ||||
|         tr._force_close(None) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertFalse(self.protocol.connection_lost.called) | ||||
| 
 | ||||
|     def test_fatal_error_2(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._buffer = [b'data'] | ||||
|         tr._force_close(None) | ||||
| 
 | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.protocol.connection_lost.assert_called_with(None) | ||||
|         self.assertEqual(None, tr._buffer) | ||||
| 
 | ||||
|     def test_call_connection_lost(self): | ||||
|         tr = self.socket_transport() | ||||
|         tr._call_connection_lost(None) | ||||
|         self.assertTrue(self.protocol.connection_lost.called) | ||||
|         self.assertTrue(self.sock.close.called) | ||||
| 
 | ||||
|     def test_write_eof(self): | ||||
|         tr = self.socket_transport() | ||||
|         self.assertTrue(tr.can_write_eof()) | ||||
|         tr.write_eof() | ||||
|         self.sock.shutdown.assert_called_with(socket.SHUT_WR) | ||||
|         tr.write_eof() | ||||
|         self.assertEqual(self.sock.shutdown.call_count, 1) | ||||
|         tr.close() | ||||
| 
 | ||||
|     def test_write_eof_buffer(self): | ||||
|         tr = self.socket_transport() | ||||
|         f = asyncio.Future(loop=self.loop) | ||||
|         tr._loop._proactor.send.return_value = f | ||||
|         tr.write(b'data') | ||||
|         tr.write_eof() | ||||
|         self.assertTrue(tr._eof_written) | ||||
|         self.assertFalse(self.sock.shutdown.called) | ||||
|         tr._loop._proactor.send.assert_called_with(self.sock, b'data') | ||||
|         f.set_result(4) | ||||
|         self.loop._run_once() | ||||
|         self.sock.shutdown.assert_called_with(socket.SHUT_WR) | ||||
|         tr.close() | ||||
| 
 | ||||
|     def test_write_eof_write_pipe(self): | ||||
|         tr = _ProactorWritePipeTransport( | ||||
|             self.loop, self.sock, self.protocol) | ||||
|         self.assertTrue(tr.can_write_eof()) | ||||
|         tr.write_eof() | ||||
|         self.assertTrue(tr.is_closing()) | ||||
|         self.loop._run_once() | ||||
|         self.assertTrue(self.sock.close.called) | ||||
|         tr.close() | ||||
| 
 | ||||
|     def test_write_eof_buffer_write_pipe(self): | ||||
|         tr = _ProactorWritePipeTransport(self.loop, self.sock, self.protocol) | ||||
|         f = asyncio.Future(loop=self.loop) | ||||
|         tr._loop._proactor.send.return_value = f | ||||
|         tr.write(b'data') | ||||
|         tr.write_eof() | ||||
|         self.assertTrue(tr.is_closing()) | ||||
|         self.assertFalse(self.sock.shutdown.called) | ||||
|         tr._loop._proactor.send.assert_called_with(self.sock, b'data') | ||||
|         f.set_result(4) | ||||
|         self.loop._run_once() | ||||
|         self.loop._run_once() | ||||
|         self.assertTrue(self.sock.close.called) | ||||
|         tr.close() | ||||
| 
 | ||||
|     def test_write_eof_duplex_pipe(self): | ||||
|         tr = _ProactorDuplexPipeTransport( | ||||
|             self.loop, self.sock, self.protocol) | ||||
|         self.assertFalse(tr.can_write_eof()) | ||||
|         with self.assertRaises(NotImplementedError): | ||||
|             tr.write_eof() | ||||
|         close_transport(tr) | ||||
| 
 | ||||
|     def test_pause_resume_reading(self): | ||||
|         tr = self.socket_transport() | ||||
|         futures = [] | ||||
|         for msg in [b'data1', b'data2', b'data3', b'data4', b'data5', b'']: | ||||
|             f = asyncio.Future(loop=self.loop) | ||||
|             f.set_result(msg) | ||||
|             futures.append(f) | ||||
| 
 | ||||
|         self.loop._proactor.recv.side_effect = futures | ||||
|         self.loop._run_once() | ||||
|         self.assertFalse(tr._paused) | ||||
|         self.loop._run_once() | ||||
|         self.protocol.data_received.assert_called_with(b'data1') | ||||
|         self.loop._run_once() | ||||
|         self.protocol.data_received.assert_called_with(b'data2') | ||||
| 
 | ||||
|         tr.pause_reading() | ||||
|         tr.pause_reading() | ||||
|         self.assertTrue(tr._paused) | ||||
|         for i in range(10): | ||||
|             self.loop._run_once() | ||||
|         self.protocol.data_received.assert_called_with(b'data2') | ||||
| 
 | ||||
|         tr.resume_reading() | ||||
|         tr.resume_reading() | ||||
|         self.assertFalse(tr._paused) | ||||
|         self.loop._run_once() | ||||
|         self.protocol.data_received.assert_called_with(b'data3') | ||||
|         self.loop._run_once() | ||||
|         self.protocol.data_received.assert_called_with(b'data4') | ||||
| 
 | ||||
|         tr.pause_reading() | ||||
|         tr.resume_reading() | ||||
|         self.loop.call_exception_handler = mock.Mock() | ||||
|         self.loop._run_once() | ||||
|         self.loop.call_exception_handler.assert_not_called() | ||||
|         self.protocol.data_received.assert_called_with(b'data5') | ||||
|         tr.close() | ||||
| 
 | ||||
| 
 | ||||
|     def pause_writing_transport(self, high): | ||||
|         tr = self.socket_transport() | ||||
|         tr.set_write_buffer_limits(high=high) | ||||
| 
 | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 0) | ||||
|         self.assertFalse(self.protocol.pause_writing.called) | ||||
|         self.assertFalse(self.protocol.resume_writing.called) | ||||
|         return tr | ||||
| 
 | ||||
|     def test_pause_resume_writing(self): | ||||
|         tr = self.pause_writing_transport(high=4) | ||||
| 
 | ||||
|         # write a large chunk, must pause writing | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         self.loop._proactor.send.return_value = fut | ||||
|         tr.write(b'large data') | ||||
|         self.loop._run_once() | ||||
|         self.assertTrue(self.protocol.pause_writing.called) | ||||
| 
 | ||||
|         # flush the buffer | ||||
|         fut.set_result(None) | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 0) | ||||
|         self.assertTrue(self.protocol.resume_writing.called) | ||||
| 
 | ||||
|     def test_pause_writing_2write(self): | ||||
|         tr = self.pause_writing_transport(high=4) | ||||
| 
 | ||||
|         # first short write, the buffer is not full (3 <= 4) | ||||
|         fut1 = asyncio.Future(loop=self.loop) | ||||
|         self.loop._proactor.send.return_value = fut1 | ||||
|         tr.write(b'123') | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 3) | ||||
|         self.assertFalse(self.protocol.pause_writing.called) | ||||
| 
 | ||||
|         # fill the buffer, must pause writing (6 > 4) | ||||
|         tr.write(b'abc') | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 6) | ||||
|         self.assertTrue(self.protocol.pause_writing.called) | ||||
| 
 | ||||
|     def test_pause_writing_3write(self): | ||||
|         tr = self.pause_writing_transport(high=4) | ||||
| 
 | ||||
|         # first short write, the buffer is not full (1 <= 4) | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         self.loop._proactor.send.return_value = fut | ||||
|         tr.write(b'1') | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 1) | ||||
|         self.assertFalse(self.protocol.pause_writing.called) | ||||
| 
 | ||||
|         # second short write, the buffer is not full (3 <= 4) | ||||
|         tr.write(b'23') | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 3) | ||||
|         self.assertFalse(self.protocol.pause_writing.called) | ||||
| 
 | ||||
|         # fill the buffer, must pause writing (6 > 4) | ||||
|         tr.write(b'abc') | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 6) | ||||
|         self.assertTrue(self.protocol.pause_writing.called) | ||||
| 
 | ||||
|     def test_dont_pause_writing(self): | ||||
|         tr = self.pause_writing_transport(high=4) | ||||
| 
 | ||||
|         # write a large chunk which completes immedialty, | ||||
|         # it should not pause writing | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         fut.set_result(None) | ||||
|         self.loop._proactor.send.return_value = fut | ||||
|         tr.write(b'very large data') | ||||
|         self.loop._run_once() | ||||
|         self.assertEqual(tr.get_write_buffer_size(), 0) | ||||
|         self.assertFalse(self.protocol.pause_writing.called) | ||||
| 
 | ||||
| 
 | ||||
| class BaseProactorEventLoopTests(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
| 
 | ||||
|         self.sock = test_utils.mock_nonblocking_socket() | ||||
|         self.proactor = mock.Mock() | ||||
| 
 | ||||
|         self.ssock, self.csock = mock.Mock(), mock.Mock() | ||||
| 
 | ||||
|         class EventLoop(BaseProactorEventLoop): | ||||
|             def _socketpair(s): | ||||
|                 return (self.ssock, self.csock) | ||||
| 
 | ||||
|         self.loop = EventLoop(self.proactor) | ||||
|         self.set_event_loop(self.loop) | ||||
| 
 | ||||
|     @mock.patch.object(BaseProactorEventLoop, 'call_soon') | ||||
|     @mock.patch.object(BaseProactorEventLoop, '_socketpair') | ||||
|     def test_ctor(self, socketpair, call_soon): | ||||
|         ssock, csock = socketpair.return_value = ( | ||||
|             mock.Mock(), mock.Mock()) | ||||
|         loop = BaseProactorEventLoop(self.proactor) | ||||
|         self.assertIs(loop._ssock, ssock) | ||||
|         self.assertIs(loop._csock, csock) | ||||
|         self.assertEqual(loop._internal_fds, 1) | ||||
|         call_soon.assert_called_with(loop._loop_self_reading) | ||||
|         loop.close() | ||||
| 
 | ||||
|     def test_close_self_pipe(self): | ||||
|         self.loop._close_self_pipe() | ||||
|         self.assertEqual(self.loop._internal_fds, 0) | ||||
|         self.assertTrue(self.ssock.close.called) | ||||
|         self.assertTrue(self.csock.close.called) | ||||
|         self.assertIsNone(self.loop._ssock) | ||||
|         self.assertIsNone(self.loop._csock) | ||||
| 
 | ||||
|         # Don't call close(): _close_self_pipe() cannot be called twice | ||||
|         self.loop._closed = True | ||||
| 
 | ||||
|     def test_close(self): | ||||
|         self.loop._close_self_pipe = mock.Mock() | ||||
|         self.loop.close() | ||||
|         self.assertTrue(self.loop._close_self_pipe.called) | ||||
|         self.assertTrue(self.proactor.close.called) | ||||
|         self.assertIsNone(self.loop._proactor) | ||||
| 
 | ||||
|         self.loop._close_self_pipe.reset_mock() | ||||
|         self.loop.close() | ||||
|         self.assertFalse(self.loop._close_self_pipe.called) | ||||
| 
 | ||||
|     def test_sock_recv(self): | ||||
|         self.loop.sock_recv(self.sock, 1024) | ||||
|         self.proactor.recv.assert_called_with(self.sock, 1024) | ||||
| 
 | ||||
|     def test_sock_sendall(self): | ||||
|         self.loop.sock_sendall(self.sock, b'data') | ||||
|         self.proactor.send.assert_called_with(self.sock, b'data') | ||||
| 
 | ||||
|     def test_sock_connect(self): | ||||
|         self.loop.sock_connect(self.sock, ('1.2.3.4', 123)) | ||||
|         self.proactor.connect.assert_called_with(self.sock, ('1.2.3.4', 123)) | ||||
| 
 | ||||
|     def test_sock_accept(self): | ||||
|         self.loop.sock_accept(self.sock) | ||||
|         self.proactor.accept.assert_called_with(self.sock) | ||||
| 
 | ||||
|     def test_socketpair(self): | ||||
|         class EventLoop(BaseProactorEventLoop): | ||||
|             # override the destructor to not log a ResourceWarning | ||||
|             def __del__(self): | ||||
|                 pass | ||||
|         self.assertRaises( | ||||
|             NotImplementedError, EventLoop, self.proactor) | ||||
| 
 | ||||
|     def test_make_socket_transport(self): | ||||
|         tr = self.loop._make_socket_transport(self.sock, asyncio.Protocol()) | ||||
|         self.assertIsInstance(tr, _ProactorSocketTransport) | ||||
|         close_transport(tr) | ||||
| 
 | ||||
|     def test_loop_self_reading(self): | ||||
|         self.loop._loop_self_reading() | ||||
|         self.proactor.recv.assert_called_with(self.ssock, 4096) | ||||
|         self.proactor.recv.return_value.add_done_callback.assert_called_with( | ||||
|             self.loop._loop_self_reading) | ||||
| 
 | ||||
|     def test_loop_self_reading_fut(self): | ||||
|         fut = mock.Mock() | ||||
|         self.loop._loop_self_reading(fut) | ||||
|         self.assertTrue(fut.result.called) | ||||
|         self.proactor.recv.assert_called_with(self.ssock, 4096) | ||||
|         self.proactor.recv.return_value.add_done_callback.assert_called_with( | ||||
|             self.loop._loop_self_reading) | ||||
| 
 | ||||
|     def test_loop_self_reading_exception(self): | ||||
|         self.loop.call_exception_handler = mock.Mock() | ||||
|         self.proactor.recv.side_effect = OSError() | ||||
|         self.loop._loop_self_reading() | ||||
|         self.assertTrue(self.loop.call_exception_handler.called) | ||||
| 
 | ||||
|     def test_write_to_self(self): | ||||
|         self.loop._write_to_self() | ||||
|         self.csock.send.assert_called_with(b'\0') | ||||
| 
 | ||||
|     def test_process_events(self): | ||||
|         self.loop._process_events([]) | ||||
| 
 | ||||
|     @mock.patch('asyncio.base_events.logger') | ||||
|     def test_create_server(self, m_log): | ||||
|         pf = mock.Mock() | ||||
|         call_soon = self.loop.call_soon = mock.Mock() | ||||
| 
 | ||||
|         self.loop._start_serving(pf, self.sock) | ||||
|         self.assertTrue(call_soon.called) | ||||
| 
 | ||||
|         # callback | ||||
|         loop = call_soon.call_args[0][0] | ||||
|         loop() | ||||
|         self.proactor.accept.assert_called_with(self.sock) | ||||
| 
 | ||||
|         # conn | ||||
|         fut = mock.Mock() | ||||
|         fut.result.return_value = (mock.Mock(), mock.Mock()) | ||||
| 
 | ||||
|         make_tr = self.loop._make_socket_transport = mock.Mock() | ||||
|         loop(fut) | ||||
|         self.assertTrue(fut.result.called) | ||||
|         self.assertTrue(make_tr.called) | ||||
| 
 | ||||
|         # exception | ||||
|         fut.result.side_effect = OSError() | ||||
|         loop(fut) | ||||
|         self.assertTrue(self.sock.close.called) | ||||
|         self.assertTrue(m_log.error.called) | ||||
| 
 | ||||
|     def test_create_server_cancel(self): | ||||
|         pf = mock.Mock() | ||||
|         call_soon = self.loop.call_soon = mock.Mock() | ||||
| 
 | ||||
|         self.loop._start_serving(pf, self.sock) | ||||
|         loop = call_soon.call_args[0][0] | ||||
| 
 | ||||
|         # cancelled | ||||
|         fut = asyncio.Future(loop=self.loop) | ||||
|         fut.cancel() | ||||
|         loop(fut) | ||||
|         self.assertTrue(self.sock.close.called) | ||||
| 
 | ||||
|     def test_stop_serving(self): | ||||
|         sock = mock.Mock() | ||||
|         self.loop._stop_serving(sock) | ||||
|         self.assertTrue(sock.close.called) | ||||
|         self.proactor._stop_serving.assert_called_with(sock) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										643
									
								
								third_party/python/Lib/test/test_asyncio/test_queues.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										643
									
								
								third_party/python/Lib/test/test_asyncio/test_queues.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,643 @@ | |||
| """Tests for queues.py""" | ||||
| 
 | ||||
| import unittest | ||||
| from unittest import mock | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import test_utils | ||||
| 
 | ||||
| 
 | ||||
| class _QueueTestBase(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = self.new_test_loop() | ||||
| 
 | ||||
| 
 | ||||
| class QueueBasicTests(_QueueTestBase): | ||||
| 
 | ||||
|     def _test_repr_or_str(self, fn, expect_id): | ||||
|         """Test Queue's repr or str. | ||||
| 
 | ||||
|         fn is repr or str. expect_id is True if we expect the Queue's id to | ||||
|         appear in fn(Queue()). | ||||
|         """ | ||||
|         def gen(): | ||||
|             when = yield | ||||
|             self.assertAlmostEqual(0.1, when) | ||||
|             when = yield 0.1 | ||||
|             self.assertAlmostEqual(0.2, when) | ||||
|             yield 0.1 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=loop) | ||||
|         self.assertTrue(fn(q).startswith('<Queue'), fn(q)) | ||||
|         id_is_present = hex(id(q)) in fn(q) | ||||
|         self.assertEqual(expect_id, id_is_present) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def add_getter(): | ||||
|             q = asyncio.Queue(loop=loop) | ||||
|             # Start a task that waits to get. | ||||
|             asyncio.Task(q.get(), loop=loop) | ||||
|             # Let it start waiting. | ||||
|             yield from asyncio.sleep(0.1, loop=loop) | ||||
|             self.assertTrue('_getters[1]' in fn(q)) | ||||
|             # resume q.get coroutine to finish generator | ||||
|             q.put_nowait(0) | ||||
| 
 | ||||
|         loop.run_until_complete(add_getter()) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def add_putter(): | ||||
|             q = asyncio.Queue(maxsize=1, loop=loop) | ||||
|             q.put_nowait(1) | ||||
|             # Start a task that waits to put. | ||||
|             asyncio.Task(q.put(2), loop=loop) | ||||
|             # Let it start waiting. | ||||
|             yield from asyncio.sleep(0.1, loop=loop) | ||||
|             self.assertTrue('_putters[1]' in fn(q)) | ||||
|             # resume q.put coroutine to finish generator | ||||
|             q.get_nowait() | ||||
| 
 | ||||
|         loop.run_until_complete(add_putter()) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=loop) | ||||
|         q.put_nowait(1) | ||||
|         self.assertTrue('_queue=[1]' in fn(q)) | ||||
| 
 | ||||
|     def test_ctor_loop(self): | ||||
|         loop = mock.Mock() | ||||
|         q = asyncio.Queue(loop=loop) | ||||
|         self.assertIs(q._loop, loop) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         self.assertIs(q._loop, self.loop) | ||||
| 
 | ||||
|     def test_ctor_noloop(self): | ||||
|         asyncio.set_event_loop(self.loop) | ||||
|         q = asyncio.Queue() | ||||
|         self.assertIs(q._loop, self.loop) | ||||
| 
 | ||||
|     def test_repr(self): | ||||
|         self._test_repr_or_str(repr, True) | ||||
| 
 | ||||
|     def test_str(self): | ||||
|         self._test_repr_or_str(str, False) | ||||
| 
 | ||||
|     def test_empty(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         self.assertTrue(q.empty()) | ||||
|         q.put_nowait(1) | ||||
|         self.assertFalse(q.empty()) | ||||
|         self.assertEqual(1, q.get_nowait()) | ||||
|         self.assertTrue(q.empty()) | ||||
| 
 | ||||
|     def test_full(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         self.assertFalse(q.full()) | ||||
| 
 | ||||
|         q = asyncio.Queue(maxsize=1, loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
|         self.assertTrue(q.full()) | ||||
| 
 | ||||
|     def test_order(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         for i in [1, 3, 2]: | ||||
|             q.put_nowait(i) | ||||
| 
 | ||||
|         items = [q.get_nowait() for _ in range(3)] | ||||
|         self.assertEqual([1, 3, 2], items) | ||||
| 
 | ||||
|     def test_maxsize(self): | ||||
| 
 | ||||
|         def gen(): | ||||
|             when = yield | ||||
|             self.assertAlmostEqual(0.01, when) | ||||
|             when = yield 0.01 | ||||
|             self.assertAlmostEqual(0.02, when) | ||||
|             yield 0.01 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
| 
 | ||||
|         q = asyncio.Queue(maxsize=2, loop=loop) | ||||
|         self.assertEqual(2, q.maxsize) | ||||
|         have_been_put = [] | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def putter(): | ||||
|             for i in range(3): | ||||
|                 yield from q.put(i) | ||||
|                 have_been_put.append(i) | ||||
|             return True | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def test(): | ||||
|             t = asyncio.Task(putter(), loop=loop) | ||||
|             yield from asyncio.sleep(0.01, loop=loop) | ||||
| 
 | ||||
|             # The putter is blocked after putting two items. | ||||
|             self.assertEqual([0, 1], have_been_put) | ||||
|             self.assertEqual(0, q.get_nowait()) | ||||
| 
 | ||||
|             # Let the putter resume and put last item. | ||||
|             yield from asyncio.sleep(0.01, loop=loop) | ||||
|             self.assertEqual([0, 1, 2], have_been_put) | ||||
|             self.assertEqual(1, q.get_nowait()) | ||||
|             self.assertEqual(2, q.get_nowait()) | ||||
| 
 | ||||
|             self.assertTrue(t.done()) | ||||
|             self.assertTrue(t.result()) | ||||
| 
 | ||||
|         loop.run_until_complete(test()) | ||||
|         self.assertAlmostEqual(0.02, loop.time()) | ||||
| 
 | ||||
| 
 | ||||
| class QueueGetTests(_QueueTestBase): | ||||
| 
 | ||||
|     def test_blocking_get(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_get(): | ||||
|             return (yield from q.get()) | ||||
| 
 | ||||
|         res = self.loop.run_until_complete(queue_get()) | ||||
|         self.assertEqual(1, res) | ||||
| 
 | ||||
|     def test_get_with_putters(self): | ||||
|         q = asyncio.Queue(1, loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
| 
 | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         q._putters.append(waiter) | ||||
| 
 | ||||
|         res = self.loop.run_until_complete(q.get()) | ||||
|         self.assertEqual(1, res) | ||||
|         self.assertTrue(waiter.done()) | ||||
|         self.assertIsNone(waiter.result()) | ||||
| 
 | ||||
|     def test_blocking_get_wait(self): | ||||
| 
 | ||||
|         def gen(): | ||||
|             when = yield | ||||
|             self.assertAlmostEqual(0.01, when) | ||||
|             yield 0.01 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=loop) | ||||
|         started = asyncio.Event(loop=loop) | ||||
|         finished = False | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_get(): | ||||
|             nonlocal finished | ||||
|             started.set() | ||||
|             res = yield from q.get() | ||||
|             finished = True | ||||
|             return res | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_put(): | ||||
|             loop.call_later(0.01, q.put_nowait, 1) | ||||
|             queue_get_task = asyncio.Task(queue_get(), loop=loop) | ||||
|             yield from started.wait() | ||||
|             self.assertFalse(finished) | ||||
|             res = yield from queue_get_task | ||||
|             self.assertTrue(finished) | ||||
|             return res | ||||
| 
 | ||||
|         res = loop.run_until_complete(queue_put()) | ||||
|         self.assertEqual(1, res) | ||||
|         self.assertAlmostEqual(0.01, loop.time()) | ||||
| 
 | ||||
|     def test_nonblocking_get(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
|         self.assertEqual(1, q.get_nowait()) | ||||
| 
 | ||||
|     def test_nonblocking_get_exception(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         self.assertRaises(asyncio.QueueEmpty, q.get_nowait) | ||||
| 
 | ||||
|     def test_get_cancelled(self): | ||||
| 
 | ||||
|         def gen(): | ||||
|             when = yield | ||||
|             self.assertAlmostEqual(0.01, when) | ||||
|             when = yield 0.01 | ||||
|             self.assertAlmostEqual(0.061, when) | ||||
|             yield 0.05 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=loop) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_get(): | ||||
|             return (yield from asyncio.wait_for(q.get(), 0.051, loop=loop)) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def test(): | ||||
|             get_task = asyncio.Task(queue_get(), loop=loop) | ||||
|             yield from asyncio.sleep(0.01, loop=loop)  # let the task start | ||||
|             q.put_nowait(1) | ||||
|             return (yield from get_task) | ||||
| 
 | ||||
|         self.assertEqual(1, loop.run_until_complete(test())) | ||||
|         self.assertAlmostEqual(0.06, loop.time()) | ||||
| 
 | ||||
|     def test_get_cancelled_race(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
| 
 | ||||
|         t1 = asyncio.Task(q.get(), loop=self.loop) | ||||
|         t2 = asyncio.Task(q.get(), loop=self.loop) | ||||
| 
 | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         t1.cancel() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertTrue(t1.done()) | ||||
|         q.put_nowait('a') | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertEqual(t2.result(), 'a') | ||||
| 
 | ||||
|     def test_get_with_waiting_putters(self): | ||||
|         q = asyncio.Queue(loop=self.loop, maxsize=1) | ||||
|         asyncio.Task(q.put('a'), loop=self.loop) | ||||
|         asyncio.Task(q.put('b'), loop=self.loop) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertEqual(self.loop.run_until_complete(q.get()), 'a') | ||||
|         self.assertEqual(self.loop.run_until_complete(q.get()), 'b') | ||||
| 
 | ||||
|     def test_why_are_getters_waiting(self): | ||||
|         # From issue #268. | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def consumer(queue, num_expected): | ||||
|             for _ in range(num_expected): | ||||
|                 yield from queue.get() | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def producer(queue, num_items): | ||||
|             for i in range(num_items): | ||||
|                 yield from queue.put(i) | ||||
| 
 | ||||
|         queue_size = 1 | ||||
|         producer_num_items = 5 | ||||
|         q = asyncio.Queue(queue_size, loop=self.loop) | ||||
| 
 | ||||
|         self.loop.run_until_complete( | ||||
|             asyncio.gather(producer(q, producer_num_items), | ||||
|                            consumer(q, producer_num_items), | ||||
|                            loop=self.loop), | ||||
|             ) | ||||
| 
 | ||||
|     def test_cancelled_getters_not_being_held_in_self_getters(self): | ||||
|         def a_generator(): | ||||
|             yield 0.1 | ||||
|             yield 0.2 | ||||
| 
 | ||||
|         self.loop = self.new_test_loop(a_generator) | ||||
|         @asyncio.coroutine | ||||
|         def consumer(queue): | ||||
|             try: | ||||
|                 item = yield from asyncio.wait_for(queue.get(), 0.1, loop=self.loop) | ||||
|             except asyncio.TimeoutError: | ||||
|                 pass | ||||
| 
 | ||||
|         queue = asyncio.Queue(loop=self.loop, maxsize=5) | ||||
|         self.loop.run_until_complete(self.loop.create_task(consumer(queue))) | ||||
|         self.assertEqual(len(queue._getters), 0) | ||||
| 
 | ||||
| 
 | ||||
| class QueuePutTests(_QueueTestBase): | ||||
| 
 | ||||
|     def test_blocking_put(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_put(): | ||||
|             # No maxsize, won't block. | ||||
|             yield from q.put(1) | ||||
| 
 | ||||
|         self.loop.run_until_complete(queue_put()) | ||||
| 
 | ||||
|     def test_blocking_put_wait(self): | ||||
| 
 | ||||
|         def gen(): | ||||
|             when = yield | ||||
|             self.assertAlmostEqual(0.01, when) | ||||
|             yield 0.01 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
| 
 | ||||
|         q = asyncio.Queue(maxsize=1, loop=loop) | ||||
|         started = asyncio.Event(loop=loop) | ||||
|         finished = False | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_put(): | ||||
|             nonlocal finished | ||||
|             started.set() | ||||
|             yield from q.put(1) | ||||
|             yield from q.put(2) | ||||
|             finished = True | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_get(): | ||||
|             loop.call_later(0.01, q.get_nowait) | ||||
|             queue_put_task = asyncio.Task(queue_put(), loop=loop) | ||||
|             yield from started.wait() | ||||
|             self.assertFalse(finished) | ||||
|             yield from queue_put_task | ||||
|             self.assertTrue(finished) | ||||
| 
 | ||||
|         loop.run_until_complete(queue_get()) | ||||
|         self.assertAlmostEqual(0.01, loop.time()) | ||||
| 
 | ||||
|     def test_nonblocking_put(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
|         self.assertEqual(1, q.get_nowait()) | ||||
| 
 | ||||
|     def test_get_cancel_drop_one_pending_reader(self): | ||||
|         def gen(): | ||||
|             yield 0.01 | ||||
|             yield 0.1 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=loop) | ||||
| 
 | ||||
|         reader = loop.create_task(q.get()) | ||||
| 
 | ||||
|         loop.run_until_complete(asyncio.sleep(0.01, loop=loop)) | ||||
| 
 | ||||
|         q.put_nowait(1) | ||||
|         q.put_nowait(2) | ||||
|         reader.cancel() | ||||
| 
 | ||||
|         try: | ||||
|             loop.run_until_complete(reader) | ||||
|         except asyncio.CancelledError: | ||||
|             # try again | ||||
|             reader = loop.create_task(q.get()) | ||||
|             loop.run_until_complete(reader) | ||||
| 
 | ||||
|         result = reader.result() | ||||
|         # if we get 2, it means 1 got dropped! | ||||
|         self.assertEqual(1, result) | ||||
| 
 | ||||
|     def test_get_cancel_drop_many_pending_readers(self): | ||||
|         def gen(): | ||||
|             yield 0.01 | ||||
|             yield 0.1 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
|         loop.set_debug(True) | ||||
| 
 | ||||
|         q = asyncio.Queue(loop=loop) | ||||
| 
 | ||||
|         reader1 = loop.create_task(q.get()) | ||||
|         reader2 = loop.create_task(q.get()) | ||||
|         reader3 = loop.create_task(q.get()) | ||||
| 
 | ||||
|         loop.run_until_complete(asyncio.sleep(0.01, loop=loop)) | ||||
| 
 | ||||
|         q.put_nowait(1) | ||||
|         q.put_nowait(2) | ||||
|         reader1.cancel() | ||||
| 
 | ||||
|         try: | ||||
|             loop.run_until_complete(reader1) | ||||
|         except asyncio.CancelledError: | ||||
|             pass | ||||
| 
 | ||||
|         loop.run_until_complete(reader3) | ||||
| 
 | ||||
|         # It is undefined in which order concurrent readers receive results. | ||||
|         self.assertEqual({reader2.result(), reader3.result()}, {1, 2}) | ||||
| 
 | ||||
|     def test_put_cancel_drop(self): | ||||
| 
 | ||||
|         def gen(): | ||||
|             yield 0.01 | ||||
|             yield 0.1 | ||||
| 
 | ||||
|         loop = self.new_test_loop(gen) | ||||
|         q = asyncio.Queue(1, loop=loop) | ||||
| 
 | ||||
|         q.put_nowait(1) | ||||
| 
 | ||||
|         # putting a second item in the queue has to block (qsize=1) | ||||
|         writer = loop.create_task(q.put(2)) | ||||
|         loop.run_until_complete(asyncio.sleep(0.01, loop=loop)) | ||||
| 
 | ||||
|         value1 = q.get_nowait() | ||||
|         self.assertEqual(value1, 1) | ||||
| 
 | ||||
|         writer.cancel() | ||||
|         try: | ||||
|             loop.run_until_complete(writer) | ||||
|         except asyncio.CancelledError: | ||||
|             # try again | ||||
|             writer = loop.create_task(q.put(2)) | ||||
|             loop.run_until_complete(writer) | ||||
| 
 | ||||
|         value2 = q.get_nowait() | ||||
|         self.assertEqual(value2, 2) | ||||
|         self.assertEqual(q.qsize(), 0) | ||||
| 
 | ||||
|     def test_nonblocking_put_exception(self): | ||||
|         q = asyncio.Queue(maxsize=1, loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
|         self.assertRaises(asyncio.QueueFull, q.put_nowait, 2) | ||||
| 
 | ||||
|     def test_float_maxsize(self): | ||||
|         q = asyncio.Queue(maxsize=1.3, loop=self.loop) | ||||
|         q.put_nowait(1) | ||||
|         q.put_nowait(2) | ||||
|         self.assertTrue(q.full()) | ||||
|         self.assertRaises(asyncio.QueueFull, q.put_nowait, 3) | ||||
| 
 | ||||
|         q = asyncio.Queue(maxsize=1.3, loop=self.loop) | ||||
|         @asyncio.coroutine | ||||
|         def queue_put(): | ||||
|             yield from q.put(1) | ||||
|             yield from q.put(2) | ||||
|             self.assertTrue(q.full()) | ||||
|         self.loop.run_until_complete(queue_put()) | ||||
| 
 | ||||
|     def test_put_cancelled(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def queue_put(): | ||||
|             yield from q.put(1) | ||||
|             return True | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def test(): | ||||
|             return (yield from q.get()) | ||||
| 
 | ||||
|         t = asyncio.Task(queue_put(), loop=self.loop) | ||||
|         self.assertEqual(1, self.loop.run_until_complete(test())) | ||||
|         self.assertTrue(t.done()) | ||||
|         self.assertTrue(t.result()) | ||||
| 
 | ||||
|     def test_put_cancelled_race(self): | ||||
|         q = asyncio.Queue(loop=self.loop, maxsize=1) | ||||
| 
 | ||||
|         put_a = asyncio.Task(q.put('a'), loop=self.loop) | ||||
|         put_b = asyncio.Task(q.put('b'), loop=self.loop) | ||||
|         put_c = asyncio.Task(q.put('X'), loop=self.loop) | ||||
| 
 | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertTrue(put_a.done()) | ||||
|         self.assertFalse(put_b.done()) | ||||
| 
 | ||||
|         put_c.cancel() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertTrue(put_c.done()) | ||||
|         self.assertEqual(q.get_nowait(), 'a') | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertEqual(q.get_nowait(), 'b') | ||||
| 
 | ||||
|         self.loop.run_until_complete(put_b) | ||||
| 
 | ||||
|     def test_put_with_waiting_getters(self): | ||||
|         q = asyncio.Queue(loop=self.loop) | ||||
|         t = asyncio.Task(q.get(), loop=self.loop) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.loop.run_until_complete(q.put('a')) | ||||
|         self.assertEqual(self.loop.run_until_complete(t), 'a') | ||||
| 
 | ||||
|     def test_why_are_putters_waiting(self): | ||||
|         # From issue #265. | ||||
| 
 | ||||
|         queue = asyncio.Queue(2, loop=self.loop) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def putter(item): | ||||
|             yield from queue.put(item) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def getter(): | ||||
|             yield | ||||
|             num = queue.qsize() | ||||
|             for _ in range(num): | ||||
|                 item = queue.get_nowait() | ||||
| 
 | ||||
|         t0 = putter(0) | ||||
|         t1 = putter(1) | ||||
|         t2 = putter(2) | ||||
|         t3 = putter(3) | ||||
|         self.loop.run_until_complete( | ||||
|             asyncio.gather(getter(), t0, t1, t2, t3, loop=self.loop)) | ||||
| 
 | ||||
| 
 | ||||
| class LifoQueueTests(_QueueTestBase): | ||||
| 
 | ||||
|     def test_order(self): | ||||
|         q = asyncio.LifoQueue(loop=self.loop) | ||||
|         for i in [1, 3, 2]: | ||||
|             q.put_nowait(i) | ||||
| 
 | ||||
|         items = [q.get_nowait() for _ in range(3)] | ||||
|         self.assertEqual([2, 3, 1], items) | ||||
| 
 | ||||
| 
 | ||||
| class PriorityQueueTests(_QueueTestBase): | ||||
| 
 | ||||
|     def test_order(self): | ||||
|         q = asyncio.PriorityQueue(loop=self.loop) | ||||
|         for i in [1, 3, 2]: | ||||
|             q.put_nowait(i) | ||||
| 
 | ||||
|         items = [q.get_nowait() for _ in range(3)] | ||||
|         self.assertEqual([1, 2, 3], items) | ||||
| 
 | ||||
| 
 | ||||
| class _QueueJoinTestMixin: | ||||
| 
 | ||||
|     q_class = None | ||||
| 
 | ||||
|     def test_task_done_underflow(self): | ||||
|         q = self.q_class(loop=self.loop) | ||||
|         self.assertRaises(ValueError, q.task_done) | ||||
| 
 | ||||
|     def test_task_done(self): | ||||
|         q = self.q_class(loop=self.loop) | ||||
|         for i in range(100): | ||||
|             q.put_nowait(i) | ||||
| 
 | ||||
|         accumulator = 0 | ||||
| 
 | ||||
|         # Two workers get items from the queue and call task_done after each. | ||||
|         # Join the queue and assert all items have been processed. | ||||
|         running = True | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def worker(): | ||||
|             nonlocal accumulator | ||||
| 
 | ||||
|             while running: | ||||
|                 item = yield from q.get() | ||||
|                 accumulator += item | ||||
|                 q.task_done() | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def test(): | ||||
|             tasks = [asyncio.Task(worker(), loop=self.loop) | ||||
|                      for index in range(2)] | ||||
| 
 | ||||
|             yield from q.join() | ||||
|             return tasks | ||||
| 
 | ||||
|         tasks = self.loop.run_until_complete(test()) | ||||
|         self.assertEqual(sum(range(100)), accumulator) | ||||
| 
 | ||||
|         # close running generators | ||||
|         running = False | ||||
|         for i in range(len(tasks)): | ||||
|             q.put_nowait(0) | ||||
|         self.loop.run_until_complete(asyncio.wait(tasks, loop=self.loop)) | ||||
| 
 | ||||
|     def test_join_empty_queue(self): | ||||
|         q = self.q_class(loop=self.loop) | ||||
| 
 | ||||
|         # Test that a queue join()s successfully, and before anything else | ||||
|         # (done twice for insurance). | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def join(): | ||||
|             yield from q.join() | ||||
|             yield from q.join() | ||||
| 
 | ||||
|         self.loop.run_until_complete(join()) | ||||
| 
 | ||||
|     def test_format(self): | ||||
|         q = self.q_class(loop=self.loop) | ||||
|         self.assertEqual(q._format(), 'maxsize=0') | ||||
| 
 | ||||
|         q._unfinished_tasks = 2 | ||||
|         self.assertEqual(q._format(), 'maxsize=0 tasks=2') | ||||
| 
 | ||||
| 
 | ||||
| class QueueJoinTests(_QueueJoinTestMixin, _QueueTestBase): | ||||
|     q_class = asyncio.Queue | ||||
| 
 | ||||
| 
 | ||||
| class LifoQueueJoinTests(_QueueJoinTestMixin, _QueueTestBase): | ||||
|     q_class = asyncio.LifoQueue | ||||
| 
 | ||||
| 
 | ||||
| class PriorityQueueJoinTests(_QueueJoinTestMixin, _QueueTestBase): | ||||
|     q_class = asyncio.PriorityQueue | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										1861
									
								
								third_party/python/Lib/test/test_asyncio/test_selector_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1861
									
								
								third_party/python/Lib/test/test_asyncio/test_selector_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										151
									
								
								third_party/python/Lib/test/test_asyncio/test_sslproto.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								third_party/python/Lib/test/test_asyncio/test_sslproto.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,151 @@ | |||
| """Tests for asyncio/sslproto.py.""" | ||||
| 
 | ||||
| import logging | ||||
| import unittest | ||||
| from unittest import mock | ||||
| try: | ||||
|     import ssl | ||||
| except ImportError: | ||||
|     ssl = None | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import log | ||||
| from asyncio import sslproto | ||||
| from asyncio import test_utils | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipIf(ssl is None, 'No ssl module') | ||||
| class SslProtoHandshakeTests(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = asyncio.new_event_loop() | ||||
|         self.set_event_loop(self.loop) | ||||
| 
 | ||||
|     def ssl_protocol(self, *, waiter=None, proto=None): | ||||
|         sslcontext = test_utils.dummy_ssl_context() | ||||
|         if proto is None:  # app protocol | ||||
|             proto = asyncio.Protocol() | ||||
|         ssl_proto = sslproto.SSLProtocol(self.loop, proto, sslcontext, waiter) | ||||
|         self.assertIs(ssl_proto._app_transport.get_protocol(), proto) | ||||
|         self.addCleanup(ssl_proto._app_transport.close) | ||||
|         return ssl_proto | ||||
| 
 | ||||
|     def connection_made(self, ssl_proto, *, do_handshake=None): | ||||
|         transport = mock.Mock() | ||||
|         sslpipe = mock.Mock() | ||||
|         sslpipe.shutdown.return_value = b'' | ||||
|         if do_handshake: | ||||
|             sslpipe.do_handshake.side_effect = do_handshake | ||||
|         else: | ||||
|             def mock_handshake(callback): | ||||
|                 return [] | ||||
|             sslpipe.do_handshake.side_effect = mock_handshake | ||||
|         with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe): | ||||
|             ssl_proto.connection_made(transport) | ||||
|         return transport | ||||
| 
 | ||||
|     def test_cancel_handshake(self): | ||||
|         # Python issue #23197: cancelling a handshake must not raise an | ||||
|         # exception or log an error, even if the handshake failed | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
|         handshake_fut = asyncio.Future(loop=self.loop) | ||||
| 
 | ||||
|         def do_handshake(callback): | ||||
|             exc = Exception() | ||||
|             callback(exc) | ||||
|             handshake_fut.set_result(None) | ||||
|             return [] | ||||
| 
 | ||||
|         waiter.cancel() | ||||
| 
 | ||||
|         with test_utils.disable_logger(): | ||||
|             self.connection_made(ssl_proto, do_handshake=do_handshake) | ||||
|             self.loop.run_until_complete(handshake_fut) | ||||
| 
 | ||||
|     def test_eof_received_waiter(self): | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
|         self.connection_made(ssl_proto) | ||||
|         ssl_proto.eof_received() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertIsInstance(waiter.exception(), ConnectionResetError) | ||||
| 
 | ||||
|     def test_fatal_error_no_name_error(self): | ||||
|         # From issue #363. | ||||
|         # _fatal_error() generates a NameError if sslproto.py | ||||
|         # does not import base_events. | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
|         # Temporarily turn off error logging so as not to spoil test output. | ||||
|         log_level = log.logger.getEffectiveLevel() | ||||
|         log.logger.setLevel(logging.FATAL) | ||||
|         try: | ||||
|             ssl_proto._fatal_error(None) | ||||
|         finally: | ||||
|             # Restore error logging. | ||||
|             log.logger.setLevel(log_level) | ||||
| 
 | ||||
|     def test_connection_lost(self): | ||||
|         # From issue #472. | ||||
|         # yield from waiter hang if lost_connection was called. | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
|         self.connection_made(ssl_proto) | ||||
|         ssl_proto.connection_lost(ConnectionAbortedError) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertIsInstance(waiter.exception(), ConnectionAbortedError) | ||||
| 
 | ||||
|     def test_close_during_handshake(self): | ||||
|         # bpo-29743 Closing transport during handshake process leaks socket | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
| 
 | ||||
|         transport = self.connection_made(ssl_proto) | ||||
|         test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|         ssl_proto._app_transport.close() | ||||
|         self.assertTrue(transport.abort.called) | ||||
| 
 | ||||
|     def test_get_extra_info_on_closed_connection(self): | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
|         self.assertIsNone(ssl_proto._get_extra_info('socket')) | ||||
|         default = object() | ||||
|         self.assertIs(ssl_proto._get_extra_info('socket', default), default) | ||||
|         self.connection_made(ssl_proto) | ||||
|         self.assertIsNotNone(ssl_proto._get_extra_info('socket')) | ||||
|         ssl_proto.connection_lost(None) | ||||
|         self.assertIsNone(ssl_proto._get_extra_info('socket')) | ||||
| 
 | ||||
|     def test_set_new_app_protocol(self): | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         ssl_proto = self.ssl_protocol(waiter=waiter) | ||||
|         new_app_proto = asyncio.Protocol() | ||||
|         ssl_proto._app_transport.set_protocol(new_app_proto) | ||||
|         self.assertIs(ssl_proto._app_transport.get_protocol(), new_app_proto) | ||||
|         self.assertIs(ssl_proto._app_protocol, new_app_proto) | ||||
| 
 | ||||
|     def test_data_received_after_closing(self): | ||||
|         ssl_proto = self.ssl_protocol() | ||||
|         self.connection_made(ssl_proto) | ||||
|         transp = ssl_proto._app_transport | ||||
| 
 | ||||
|         transp.close() | ||||
| 
 | ||||
|         # should not raise | ||||
|         self.assertIsNone(ssl_proto.data_received(b'data')) | ||||
| 
 | ||||
|     def test_write_after_closing(self): | ||||
|         ssl_proto = self.ssl_protocol() | ||||
|         self.connection_made(ssl_proto) | ||||
|         transp = ssl_proto._app_transport | ||||
|         transp.close() | ||||
| 
 | ||||
|         # should not raise | ||||
|         self.assertIsNone(transp.write(b'data')) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										868
									
								
								third_party/python/Lib/test/test_asyncio/test_streams.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										868
									
								
								third_party/python/Lib/test/test_asyncio/test_streams.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,868 @@ | |||
| """Tests for streams.py.""" | ||||
| 
 | ||||
| import gc | ||||
| import os | ||||
| import queue | ||||
| import pickle | ||||
| import socket | ||||
| import sys | ||||
| import threading | ||||
| import unittest | ||||
| from unittest import mock | ||||
| try: | ||||
|     import ssl | ||||
| except ImportError: | ||||
|     ssl = None | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import test_utils | ||||
| 
 | ||||
| 
 | ||||
| class StreamReaderTests(test_utils.TestCase): | ||||
| 
 | ||||
|     DATA = b'line1\nline2\nline3\n' | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = asyncio.new_event_loop() | ||||
|         self.set_event_loop(self.loop) | ||||
| 
 | ||||
|     def tearDown(self): | ||||
|         # just in case if we have transport close callbacks | ||||
|         test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|         self.loop.close() | ||||
|         gc.collect() | ||||
|         super().tearDown() | ||||
| 
 | ||||
|     @mock.patch('asyncio.streams.events') | ||||
|     def test_ctor_global_loop(self, m_events): | ||||
|         stream = asyncio.StreamReader() | ||||
|         self.assertIs(stream._loop, m_events.get_event_loop.return_value) | ||||
| 
 | ||||
|     def _basetest_open_connection(self, open_connection_fut): | ||||
|         reader, writer = self.loop.run_until_complete(open_connection_fut) | ||||
|         writer.write(b'GET / HTTP/1.0\r\n\r\n') | ||||
|         f = reader.readline() | ||||
|         data = self.loop.run_until_complete(f) | ||||
|         self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') | ||||
|         f = reader.read() | ||||
|         data = self.loop.run_until_complete(f) | ||||
|         self.assertTrue(data.endswith(b'\r\n\r\nTest message')) | ||||
|         writer.close() | ||||
| 
 | ||||
|     def test_open_connection(self): | ||||
|         with test_utils.run_test_server() as httpd: | ||||
|             conn_fut = asyncio.open_connection(*httpd.address, | ||||
|                                                loop=self.loop) | ||||
|             self._basetest_open_connection(conn_fut) | ||||
| 
 | ||||
|     @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') | ||||
|     def test_open_unix_connection(self): | ||||
|         with test_utils.run_test_unix_server() as httpd: | ||||
|             conn_fut = asyncio.open_unix_connection(httpd.address, | ||||
|                                                     loop=self.loop) | ||||
|             self._basetest_open_connection(conn_fut) | ||||
| 
 | ||||
|     def _basetest_open_connection_no_loop_ssl(self, open_connection_fut): | ||||
|         try: | ||||
|             reader, writer = self.loop.run_until_complete(open_connection_fut) | ||||
|         finally: | ||||
|             asyncio.set_event_loop(None) | ||||
|         writer.write(b'GET / HTTP/1.0\r\n\r\n') | ||||
|         f = reader.read() | ||||
|         data = self.loop.run_until_complete(f) | ||||
|         self.assertTrue(data.endswith(b'\r\n\r\nTest message')) | ||||
| 
 | ||||
|         writer.close() | ||||
| 
 | ||||
|     @unittest.skipIf(ssl is None, 'No ssl module') | ||||
|     def test_open_connection_no_loop_ssl(self): | ||||
|         with test_utils.run_test_server(use_ssl=True) as httpd: | ||||
|             conn_fut = asyncio.open_connection( | ||||
|                 *httpd.address, | ||||
|                 ssl=test_utils.dummy_ssl_context(), | ||||
|                 loop=self.loop) | ||||
| 
 | ||||
|             self._basetest_open_connection_no_loop_ssl(conn_fut) | ||||
| 
 | ||||
|     @unittest.skipIf(ssl is None, 'No ssl module') | ||||
|     @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') | ||||
|     def test_open_unix_connection_no_loop_ssl(self): | ||||
|         with test_utils.run_test_unix_server(use_ssl=True) as httpd: | ||||
|             conn_fut = asyncio.open_unix_connection( | ||||
|                 httpd.address, | ||||
|                 ssl=test_utils.dummy_ssl_context(), | ||||
|                 server_hostname='', | ||||
|                 loop=self.loop) | ||||
| 
 | ||||
|             self._basetest_open_connection_no_loop_ssl(conn_fut) | ||||
| 
 | ||||
|     def _basetest_open_connection_error(self, open_connection_fut): | ||||
|         reader, writer = self.loop.run_until_complete(open_connection_fut) | ||||
|         writer._protocol.connection_lost(ZeroDivisionError()) | ||||
|         f = reader.read() | ||||
|         with self.assertRaises(ZeroDivisionError): | ||||
|             self.loop.run_until_complete(f) | ||||
|         writer.close() | ||||
|         test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|     def test_open_connection_error(self): | ||||
|         with test_utils.run_test_server() as httpd: | ||||
|             conn_fut = asyncio.open_connection(*httpd.address, | ||||
|                                                loop=self.loop) | ||||
|             self._basetest_open_connection_error(conn_fut) | ||||
| 
 | ||||
|     @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') | ||||
|     def test_open_unix_connection_error(self): | ||||
|         with test_utils.run_test_unix_server() as httpd: | ||||
|             conn_fut = asyncio.open_unix_connection(httpd.address, | ||||
|                                                     loop=self.loop) | ||||
|             self._basetest_open_connection_error(conn_fut) | ||||
| 
 | ||||
|     def test_feed_empty_data(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         stream.feed_data(b'') | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_feed_nonempty_data(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         stream.feed_data(self.DATA) | ||||
|         self.assertEqual(self.DATA, stream._buffer) | ||||
| 
 | ||||
|     def test_read_zero(self): | ||||
|         # Read zero bytes. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(self.DATA) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.read(0)) | ||||
|         self.assertEqual(b'', data) | ||||
|         self.assertEqual(self.DATA, stream._buffer) | ||||
| 
 | ||||
|     def test_read(self): | ||||
|         # Read bytes. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         read_task = asyncio.Task(stream.read(30), loop=self.loop) | ||||
| 
 | ||||
|         def cb(): | ||||
|             stream.feed_data(self.DATA) | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(read_task) | ||||
|         self.assertEqual(self.DATA, data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_read_line_breaks(self): | ||||
|         # Read bytes without line breaks. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'line1') | ||||
|         stream.feed_data(b'line2') | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.read(5)) | ||||
| 
 | ||||
|         self.assertEqual(b'line1', data) | ||||
|         self.assertEqual(b'line2', stream._buffer) | ||||
| 
 | ||||
|     def test_read_eof(self): | ||||
|         # Read bytes, stop at eof. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         read_task = asyncio.Task(stream.read(1024), loop=self.loop) | ||||
| 
 | ||||
|         def cb(): | ||||
|             stream.feed_eof() | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(read_task) | ||||
|         self.assertEqual(b'', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_read_until_eof(self): | ||||
|         # Read all bytes until eof. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         read_task = asyncio.Task(stream.read(-1), loop=self.loop) | ||||
| 
 | ||||
|         def cb(): | ||||
|             stream.feed_data(b'chunk1\n') | ||||
|             stream.feed_data(b'chunk2') | ||||
|             stream.feed_eof() | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(read_task) | ||||
| 
 | ||||
|         self.assertEqual(b'chunk1\nchunk2', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_read_exception(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'line\n') | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.read(2)) | ||||
|         self.assertEqual(b'li', data) | ||||
| 
 | ||||
|         stream.set_exception(ValueError()) | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.read(2)) | ||||
| 
 | ||||
|     def test_invalid_limit(self): | ||||
|         with self.assertRaisesRegex(ValueError, 'imit'): | ||||
|             asyncio.StreamReader(limit=0, loop=self.loop) | ||||
| 
 | ||||
|         with self.assertRaisesRegex(ValueError, 'imit'): | ||||
|             asyncio.StreamReader(limit=-1, loop=self.loop) | ||||
| 
 | ||||
|     def test_read_limit(self): | ||||
|         stream = asyncio.StreamReader(limit=3, loop=self.loop) | ||||
|         stream.feed_data(b'chunk') | ||||
|         data = self.loop.run_until_complete(stream.read(5)) | ||||
|         self.assertEqual(b'chunk', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readline(self): | ||||
|         # Read one line. 'readline' will need to wait for the data | ||||
|         # to come from 'cb' | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'chunk1 ') | ||||
|         read_task = asyncio.Task(stream.readline(), loop=self.loop) | ||||
| 
 | ||||
|         def cb(): | ||||
|             stream.feed_data(b'chunk2 ') | ||||
|             stream.feed_data(b'chunk3 ') | ||||
|             stream.feed_data(b'\n chunk4') | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         line = self.loop.run_until_complete(read_task) | ||||
|         self.assertEqual(b'chunk1 chunk2 chunk3 \n', line) | ||||
|         self.assertEqual(b' chunk4', stream._buffer) | ||||
| 
 | ||||
|     def test_readline_limit_with_existing_data(self): | ||||
|         # Read one line. The data is in StreamReader's buffer | ||||
|         # before the event loop is run. | ||||
| 
 | ||||
|         stream = asyncio.StreamReader(limit=3, loop=self.loop) | ||||
|         stream.feed_data(b'li') | ||||
|         stream.feed_data(b'ne1\nline2\n') | ||||
| 
 | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.readline()) | ||||
|         # The buffer should contain the remaining data after exception | ||||
|         self.assertEqual(b'line2\n', stream._buffer) | ||||
| 
 | ||||
|         stream = asyncio.StreamReader(limit=3, loop=self.loop) | ||||
|         stream.feed_data(b'li') | ||||
|         stream.feed_data(b'ne1') | ||||
|         stream.feed_data(b'li') | ||||
| 
 | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.readline()) | ||||
|         # No b'\n' at the end. The 'limit' is set to 3. So before | ||||
|         # waiting for the new data in buffer, 'readline' will consume | ||||
|         # the entire buffer, and since the length of the consumed data | ||||
|         # is more than 3, it will raise a ValueError. The buffer is | ||||
|         # expected to be empty now. | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_at_eof(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         self.assertFalse(stream.at_eof()) | ||||
| 
 | ||||
|         stream.feed_data(b'some data\n') | ||||
|         self.assertFalse(stream.at_eof()) | ||||
| 
 | ||||
|         self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertFalse(stream.at_eof()) | ||||
| 
 | ||||
|         stream.feed_data(b'some data\n') | ||||
|         stream.feed_eof() | ||||
|         self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertTrue(stream.at_eof()) | ||||
| 
 | ||||
|     def test_readline_limit(self): | ||||
|         # Read one line. StreamReaders are fed with data after | ||||
|         # their 'readline' methods are called. | ||||
| 
 | ||||
|         stream = asyncio.StreamReader(limit=7, loop=self.loop) | ||||
|         def cb(): | ||||
|             stream.feed_data(b'chunk1') | ||||
|             stream.feed_data(b'chunk2') | ||||
|             stream.feed_data(b'chunk3\n') | ||||
|             stream.feed_eof() | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.readline()) | ||||
|         # The buffer had just one line of data, and after raising | ||||
|         # a ValueError it should be empty. | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream = asyncio.StreamReader(limit=7, loop=self.loop) | ||||
|         def cb(): | ||||
|             stream.feed_data(b'chunk1') | ||||
|             stream.feed_data(b'chunk2\n') | ||||
|             stream.feed_data(b'chunk3\n') | ||||
|             stream.feed_eof() | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.readline()) | ||||
|         self.assertEqual(b'chunk3\n', stream._buffer) | ||||
| 
 | ||||
|         # check strictness of the limit | ||||
|         stream = asyncio.StreamReader(limit=7, loop=self.loop) | ||||
|         stream.feed_data(b'1234567\n') | ||||
|         line = self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertEqual(b'1234567\n', line) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'12345678\n') | ||||
|         with self.assertRaises(ValueError) as cm: | ||||
|             self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'12345678') | ||||
|         with self.assertRaises(ValueError) as cm: | ||||
|             self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readline_nolimit_nowait(self): | ||||
|         # All needed data for the first 'readline' call will be | ||||
|         # in the buffer. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(self.DATA[:6]) | ||||
|         stream.feed_data(self.DATA[6:]) | ||||
| 
 | ||||
|         line = self.loop.run_until_complete(stream.readline()) | ||||
| 
 | ||||
|         self.assertEqual(b'line1\n', line) | ||||
|         self.assertEqual(b'line2\nline3\n', stream._buffer) | ||||
| 
 | ||||
|     def test_readline_eof(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'some data') | ||||
|         stream.feed_eof() | ||||
| 
 | ||||
|         line = self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertEqual(b'some data', line) | ||||
| 
 | ||||
|     def test_readline_empty_eof(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_eof() | ||||
| 
 | ||||
|         line = self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertEqual(b'', line) | ||||
| 
 | ||||
|     def test_readline_read_byte_count(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(self.DATA) | ||||
| 
 | ||||
|         self.loop.run_until_complete(stream.readline()) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.read(7)) | ||||
| 
 | ||||
|         self.assertEqual(b'line2\nl', data) | ||||
|         self.assertEqual(b'ine3\n', stream._buffer) | ||||
| 
 | ||||
|     def test_readline_exception(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'line\n') | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.readline()) | ||||
|         self.assertEqual(b'line\n', data) | ||||
| 
 | ||||
|         stream.set_exception(ValueError()) | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.readline()) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readuntil_separator(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         with self.assertRaisesRegex(ValueError, 'Separator should be'): | ||||
|             self.loop.run_until_complete(stream.readuntil(separator=b'')) | ||||
| 
 | ||||
|     def test_readuntil_multi_chunks(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         stream.feed_data(b'lineAAA') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(separator=b'AAA')) | ||||
|         self.assertEqual(b'lineAAA', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'lineAAA') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'AAA')) | ||||
|         self.assertEqual(b'lineAAA', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'lineAAAxxx') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'AAA')) | ||||
|         self.assertEqual(b'lineAAA', data) | ||||
|         self.assertEqual(b'xxx', stream._buffer) | ||||
| 
 | ||||
|     def test_readuntil_multi_chunks_1(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         stream.feed_data(b'QWEaa') | ||||
|         stream.feed_data(b'XYaa') | ||||
|         stream.feed_data(b'a') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'aaa')) | ||||
|         self.assertEqual(b'QWEaaXYaaa', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'QWEaa') | ||||
|         stream.feed_data(b'XYa') | ||||
|         stream.feed_data(b'aa') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'aaa')) | ||||
|         self.assertEqual(b'QWEaaXYaaa', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'aaa') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'aaa')) | ||||
|         self.assertEqual(b'aaa', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'Xaaa') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'aaa')) | ||||
|         self.assertEqual(b'Xaaa', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'XXX') | ||||
|         stream.feed_data(b'a') | ||||
|         stream.feed_data(b'a') | ||||
|         stream.feed_data(b'a') | ||||
|         data = self.loop.run_until_complete(stream.readuntil(b'aaa')) | ||||
|         self.assertEqual(b'XXXaaa', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readuntil_eof(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'some dataAA') | ||||
|         stream.feed_eof() | ||||
| 
 | ||||
|         with self.assertRaises(asyncio.IncompleteReadError) as cm: | ||||
|             self.loop.run_until_complete(stream.readuntil(b'AAA')) | ||||
|         self.assertEqual(cm.exception.partial, b'some dataAA') | ||||
|         self.assertIsNone(cm.exception.expected) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readuntil_limit_found_sep(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop, limit=3) | ||||
|         stream.feed_data(b'some dataAA') | ||||
| 
 | ||||
|         with self.assertRaisesRegex(asyncio.LimitOverrunError, | ||||
|                                     'not found') as cm: | ||||
|             self.loop.run_until_complete(stream.readuntil(b'AAA')) | ||||
| 
 | ||||
|         self.assertEqual(b'some dataAA', stream._buffer) | ||||
| 
 | ||||
|         stream.feed_data(b'A') | ||||
|         with self.assertRaisesRegex(asyncio.LimitOverrunError, | ||||
|                                     'is found') as cm: | ||||
|             self.loop.run_until_complete(stream.readuntil(b'AAA')) | ||||
| 
 | ||||
|         self.assertEqual(b'some dataAAA', stream._buffer) | ||||
| 
 | ||||
|     def test_readexactly_zero_or_less(self): | ||||
|         # Read exact number of bytes (zero or less). | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(self.DATA) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.readexactly(0)) | ||||
|         self.assertEqual(b'', data) | ||||
|         self.assertEqual(self.DATA, stream._buffer) | ||||
| 
 | ||||
|         with self.assertRaisesRegex(ValueError, 'less than zero'): | ||||
|             self.loop.run_until_complete(stream.readexactly(-1)) | ||||
|         self.assertEqual(self.DATA, stream._buffer) | ||||
| 
 | ||||
|     def test_readexactly(self): | ||||
|         # Read exact number of bytes. | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         n = 2 * len(self.DATA) | ||||
|         read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) | ||||
| 
 | ||||
|         def cb(): | ||||
|             stream.feed_data(self.DATA) | ||||
|             stream.feed_data(self.DATA) | ||||
|             stream.feed_data(self.DATA) | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(read_task) | ||||
|         self.assertEqual(self.DATA + self.DATA, data) | ||||
|         self.assertEqual(self.DATA, stream._buffer) | ||||
| 
 | ||||
|     def test_readexactly_limit(self): | ||||
|         stream = asyncio.StreamReader(limit=3, loop=self.loop) | ||||
|         stream.feed_data(b'chunk') | ||||
|         data = self.loop.run_until_complete(stream.readexactly(5)) | ||||
|         self.assertEqual(b'chunk', data) | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readexactly_eof(self): | ||||
|         # Read exact number of bytes (eof). | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         n = 2 * len(self.DATA) | ||||
|         read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) | ||||
| 
 | ||||
|         def cb(): | ||||
|             stream.feed_data(self.DATA) | ||||
|             stream.feed_eof() | ||||
|         self.loop.call_soon(cb) | ||||
| 
 | ||||
|         with self.assertRaises(asyncio.IncompleteReadError) as cm: | ||||
|             self.loop.run_until_complete(read_task) | ||||
|         self.assertEqual(cm.exception.partial, self.DATA) | ||||
|         self.assertEqual(cm.exception.expected, n) | ||||
|         self.assertEqual(str(cm.exception), | ||||
|                          '18 bytes read on a total of 36 expected bytes') | ||||
|         self.assertEqual(b'', stream._buffer) | ||||
| 
 | ||||
|     def test_readexactly_exception(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'line\n') | ||||
| 
 | ||||
|         data = self.loop.run_until_complete(stream.readexactly(2)) | ||||
|         self.assertEqual(b'li', data) | ||||
| 
 | ||||
|         stream.set_exception(ValueError()) | ||||
|         self.assertRaises( | ||||
|             ValueError, self.loop.run_until_complete, stream.readexactly(2)) | ||||
| 
 | ||||
|     def test_exception(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         self.assertIsNone(stream.exception()) | ||||
| 
 | ||||
|         exc = ValueError() | ||||
|         stream.set_exception(exc) | ||||
|         self.assertIs(stream.exception(), exc) | ||||
| 
 | ||||
|     def test_exception_waiter(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def set_err(): | ||||
|             stream.set_exception(ValueError()) | ||||
| 
 | ||||
|         t1 = asyncio.Task(stream.readline(), loop=self.loop) | ||||
|         t2 = asyncio.Task(set_err(), loop=self.loop) | ||||
| 
 | ||||
|         self.loop.run_until_complete(asyncio.wait([t1, t2], loop=self.loop)) | ||||
| 
 | ||||
|         self.assertRaises(ValueError, t1.result) | ||||
| 
 | ||||
|     def test_exception_cancel(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
| 
 | ||||
|         t = asyncio.Task(stream.readline(), loop=self.loop) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         t.cancel() | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         # The following line fails if set_exception() isn't careful. | ||||
|         stream.set_exception(RuntimeError('message')) | ||||
|         test_utils.run_briefly(self.loop) | ||||
|         self.assertIs(stream._waiter, None) | ||||
| 
 | ||||
|     def test_start_server(self): | ||||
| 
 | ||||
|         class MyServer: | ||||
| 
 | ||||
|             def __init__(self, loop): | ||||
|                 self.server = None | ||||
|                 self.loop = loop | ||||
| 
 | ||||
|             @asyncio.coroutine | ||||
|             def handle_client(self, client_reader, client_writer): | ||||
|                 data = yield from client_reader.readline() | ||||
|                 client_writer.write(data) | ||||
|                 yield from client_writer.drain() | ||||
|                 client_writer.close() | ||||
| 
 | ||||
|             def start(self): | ||||
|                 sock = socket.socket() | ||||
|                 sock.bind(('127.0.0.1', 0)) | ||||
|                 self.server = self.loop.run_until_complete( | ||||
|                     asyncio.start_server(self.handle_client, | ||||
|                                          sock=sock, | ||||
|                                          loop=self.loop)) | ||||
|                 return sock.getsockname() | ||||
| 
 | ||||
|             def handle_client_callback(self, client_reader, client_writer): | ||||
|                 self.loop.create_task(self.handle_client(client_reader, | ||||
|                                                          client_writer)) | ||||
| 
 | ||||
|             def start_callback(self): | ||||
|                 sock = socket.socket() | ||||
|                 sock.bind(('127.0.0.1', 0)) | ||||
|                 addr = sock.getsockname() | ||||
|                 sock.close() | ||||
|                 self.server = self.loop.run_until_complete( | ||||
|                     asyncio.start_server(self.handle_client_callback, | ||||
|                                          host=addr[0], port=addr[1], | ||||
|                                          loop=self.loop)) | ||||
|                 return addr | ||||
| 
 | ||||
|             def stop(self): | ||||
|                 if self.server is not None: | ||||
|                     self.server.close() | ||||
|                     self.loop.run_until_complete(self.server.wait_closed()) | ||||
|                     self.server = None | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def client(addr): | ||||
|             reader, writer = yield from asyncio.open_connection( | ||||
|                 *addr, loop=self.loop) | ||||
|             # send a line | ||||
|             writer.write(b"hello world!\n") | ||||
|             # read it back | ||||
|             msgback = yield from reader.readline() | ||||
|             writer.close() | ||||
|             return msgback | ||||
| 
 | ||||
|         # test the server variant with a coroutine as client handler | ||||
|         server = MyServer(self.loop) | ||||
|         addr = server.start() | ||||
|         msg = self.loop.run_until_complete(asyncio.Task(client(addr), | ||||
|                                                         loop=self.loop)) | ||||
|         server.stop() | ||||
|         self.assertEqual(msg, b"hello world!\n") | ||||
| 
 | ||||
|         # test the server variant with a callback as client handler | ||||
|         server = MyServer(self.loop) | ||||
|         addr = server.start_callback() | ||||
|         msg = self.loop.run_until_complete(asyncio.Task(client(addr), | ||||
|                                                         loop=self.loop)) | ||||
|         server.stop() | ||||
|         self.assertEqual(msg, b"hello world!\n") | ||||
| 
 | ||||
|     @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') | ||||
|     def test_start_unix_server(self): | ||||
| 
 | ||||
|         class MyServer: | ||||
| 
 | ||||
|             def __init__(self, loop, path): | ||||
|                 self.server = None | ||||
|                 self.loop = loop | ||||
|                 self.path = path | ||||
| 
 | ||||
|             @asyncio.coroutine | ||||
|             def handle_client(self, client_reader, client_writer): | ||||
|                 data = yield from client_reader.readline() | ||||
|                 client_writer.write(data) | ||||
|                 yield from client_writer.drain() | ||||
|                 client_writer.close() | ||||
| 
 | ||||
|             def start(self): | ||||
|                 self.server = self.loop.run_until_complete( | ||||
|                     asyncio.start_unix_server(self.handle_client, | ||||
|                                               path=self.path, | ||||
|                                               loop=self.loop)) | ||||
| 
 | ||||
|             def handle_client_callback(self, client_reader, client_writer): | ||||
|                 self.loop.create_task(self.handle_client(client_reader, | ||||
|                                                          client_writer)) | ||||
| 
 | ||||
|             def start_callback(self): | ||||
|                 start = asyncio.start_unix_server(self.handle_client_callback, | ||||
|                                                   path=self.path, | ||||
|                                                   loop=self.loop) | ||||
|                 self.server = self.loop.run_until_complete(start) | ||||
| 
 | ||||
|             def stop(self): | ||||
|                 if self.server is not None: | ||||
|                     self.server.close() | ||||
|                     self.loop.run_until_complete(self.server.wait_closed()) | ||||
|                     self.server = None | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def client(path): | ||||
|             reader, writer = yield from asyncio.open_unix_connection( | ||||
|                 path, loop=self.loop) | ||||
|             # send a line | ||||
|             writer.write(b"hello world!\n") | ||||
|             # read it back | ||||
|             msgback = yield from reader.readline() | ||||
|             writer.close() | ||||
|             return msgback | ||||
| 
 | ||||
|         # test the server variant with a coroutine as client handler | ||||
|         with test_utils.unix_socket_path() as path: | ||||
|             server = MyServer(self.loop, path) | ||||
|             server.start() | ||||
|             msg = self.loop.run_until_complete(asyncio.Task(client(path), | ||||
|                                                             loop=self.loop)) | ||||
|             server.stop() | ||||
|             self.assertEqual(msg, b"hello world!\n") | ||||
| 
 | ||||
|         # test the server variant with a callback as client handler | ||||
|         with test_utils.unix_socket_path() as path: | ||||
|             server = MyServer(self.loop, path) | ||||
|             server.start_callback() | ||||
|             msg = self.loop.run_until_complete(asyncio.Task(client(path), | ||||
|                                                             loop=self.loop)) | ||||
|             server.stop() | ||||
|             self.assertEqual(msg, b"hello world!\n") | ||||
| 
 | ||||
|     @unittest.skipIf(sys.platform == 'win32', "Don't have pipes") | ||||
|     def test_read_all_from_pipe_reader(self): | ||||
|         # See asyncio issue 168.  This test is derived from the example | ||||
|         # subprocess_attach_read_pipe.py, but we configure the | ||||
|         # StreamReader's limit so that twice it is less than the size | ||||
|         # of the data writter.  Also we must explicitly attach a child | ||||
|         # watcher to the event loop. | ||||
| 
 | ||||
|         code = """\ | ||||
| import os, sys | ||||
| fd = int(sys.argv[1]) | ||||
| os.write(fd, b'data') | ||||
| os.close(fd) | ||||
| """ | ||||
|         rfd, wfd = os.pipe() | ||||
|         args = [sys.executable, '-c', code, str(wfd)] | ||||
| 
 | ||||
|         pipe = open(rfd, 'rb', 0) | ||||
|         reader = asyncio.StreamReader(loop=self.loop, limit=1) | ||||
|         protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop) | ||||
|         transport, _ = self.loop.run_until_complete( | ||||
|             self.loop.connect_read_pipe(lambda: protocol, pipe)) | ||||
| 
 | ||||
|         watcher = asyncio.SafeChildWatcher() | ||||
|         watcher.attach_loop(self.loop) | ||||
|         try: | ||||
|             asyncio.set_child_watcher(watcher) | ||||
|             create = asyncio.create_subprocess_exec(*args, | ||||
|                                                     pass_fds={wfd}, | ||||
|                                                     loop=self.loop) | ||||
|             proc = self.loop.run_until_complete(create) | ||||
|             self.loop.run_until_complete(proc.wait()) | ||||
|         finally: | ||||
|             asyncio.set_child_watcher(None) | ||||
| 
 | ||||
|         os.close(wfd) | ||||
|         data = self.loop.run_until_complete(reader.read(-1)) | ||||
|         self.assertEqual(data, b'data') | ||||
| 
 | ||||
|     def test_streamreader_constructor(self): | ||||
|         self.addCleanup(asyncio.set_event_loop, None) | ||||
|         asyncio.set_event_loop(self.loop) | ||||
| 
 | ||||
|         # asyncio issue #184: Ensure that StreamReaderProtocol constructor | ||||
|         # retrieves the current loop if the loop parameter is not set | ||||
|         reader = asyncio.StreamReader() | ||||
|         self.assertIs(reader._loop, self.loop) | ||||
| 
 | ||||
|     def test_streamreaderprotocol_constructor(self): | ||||
|         self.addCleanup(asyncio.set_event_loop, None) | ||||
|         asyncio.set_event_loop(self.loop) | ||||
| 
 | ||||
|         # asyncio issue #184: Ensure that StreamReaderProtocol constructor | ||||
|         # retrieves the current loop if the loop parameter is not set | ||||
|         reader = mock.Mock() | ||||
|         protocol = asyncio.StreamReaderProtocol(reader) | ||||
|         self.assertIs(protocol._loop, self.loop) | ||||
| 
 | ||||
|     def test_drain_raises(self): | ||||
|         # See http://bugs.python.org/issue25441 | ||||
| 
 | ||||
|         # This test should not use asyncio for the mock server; the | ||||
|         # whole point of the test is to test for a bug in drain() | ||||
|         # where it never gives up the event loop but the socket is | ||||
|         # closed on the  server side. | ||||
| 
 | ||||
|         q = queue.Queue() | ||||
| 
 | ||||
|         def server(): | ||||
|             # Runs in a separate thread. | ||||
|             sock = socket.socket() | ||||
|             with sock: | ||||
|                 sock.bind(('localhost', 0)) | ||||
|                 sock.listen(1) | ||||
|                 addr = sock.getsockname() | ||||
|                 q.put(addr) | ||||
|                 clt, _ = sock.accept() | ||||
|                 clt.close() | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def client(host, port): | ||||
|             reader, writer = yield from asyncio.open_connection( | ||||
|                 host, port, loop=self.loop) | ||||
| 
 | ||||
|             while True: | ||||
|                 writer.write(b"foo\n") | ||||
|                 yield from writer.drain() | ||||
| 
 | ||||
|         # Start the server thread and wait for it to be listening. | ||||
|         thread = threading.Thread(target=server) | ||||
|         thread.setDaemon(True) | ||||
|         thread.start() | ||||
|         addr = q.get() | ||||
| 
 | ||||
|         # Should not be stuck in an infinite loop. | ||||
|         with self.assertRaises((ConnectionResetError, BrokenPipeError)): | ||||
|             self.loop.run_until_complete(client(*addr)) | ||||
| 
 | ||||
|         # Clean up the thread.  (Only on success; on failure, it may | ||||
|         # be stuck in accept().) | ||||
|         thread.join() | ||||
| 
 | ||||
|     def test___repr__(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         self.assertEqual("<StreamReader>", repr(stream)) | ||||
| 
 | ||||
|     def test___repr__nondefault_limit(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop, limit=123) | ||||
|         self.assertEqual("<StreamReader l=123>", repr(stream)) | ||||
| 
 | ||||
|     def test___repr__eof(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_eof() | ||||
|         self.assertEqual("<StreamReader eof>", repr(stream)) | ||||
| 
 | ||||
|     def test___repr__data(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream.feed_data(b'data') | ||||
|         self.assertEqual("<StreamReader 4 bytes>", repr(stream)) | ||||
| 
 | ||||
|     def test___repr__exception(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         exc = RuntimeError() | ||||
|         stream.set_exception(exc) | ||||
|         self.assertEqual("<StreamReader e=RuntimeError()>", repr(stream)) | ||||
| 
 | ||||
|     def test___repr__waiter(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream._waiter = asyncio.Future(loop=self.loop) | ||||
|         self.assertRegex( | ||||
|             repr(stream), | ||||
|             r"<StreamReader w=<Future pending[\S ]*>>") | ||||
|         stream._waiter.set_result(None) | ||||
|         self.loop.run_until_complete(stream._waiter) | ||||
|         stream._waiter = None | ||||
|         self.assertEqual("<StreamReader>", repr(stream)) | ||||
| 
 | ||||
|     def test___repr__transport(self): | ||||
|         stream = asyncio.StreamReader(loop=self.loop) | ||||
|         stream._transport = mock.Mock() | ||||
|         stream._transport.__repr__ = mock.Mock() | ||||
|         stream._transport.__repr__.return_value = "<Transport>" | ||||
|         self.assertEqual("<StreamReader t=<Transport>>", repr(stream)) | ||||
| 
 | ||||
|     def test_IncompleteReadError_pickleable(self): | ||||
|         e = asyncio.IncompleteReadError(b'abc', 10) | ||||
|         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | ||||
|             with self.subTest(pickle_protocol=proto): | ||||
|                 e2 = pickle.loads(pickle.dumps(e, protocol=proto)) | ||||
|                 self.assertEqual(str(e), str(e2)) | ||||
|                 self.assertEqual(e.partial, e2.partial) | ||||
|                 self.assertEqual(e.expected, e2.expected) | ||||
| 
 | ||||
|     def test_LimitOverrunError_pickleable(self): | ||||
|         e = asyncio.LimitOverrunError('message', 10) | ||||
|         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | ||||
|             with self.subTest(pickle_protocol=proto): | ||||
|                 e2 = pickle.loads(pickle.dumps(e, protocol=proto)) | ||||
|                 self.assertEqual(str(e), str(e2)) | ||||
|                 self.assertEqual(e.consumed, e2.consumed) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										533
									
								
								third_party/python/Lib/test/test_asyncio/test_subprocess.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										533
									
								
								third_party/python/Lib/test/test_asyncio/test_subprocess.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,533 @@ | |||
| import signal | ||||
| import sys | ||||
| import unittest | ||||
| import warnings | ||||
| from unittest import mock | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import base_subprocess | ||||
| from asyncio import subprocess | ||||
| from asyncio import test_utils | ||||
| try: | ||||
|     from test import support | ||||
| except ImportError: | ||||
|     from asyncio import test_support as support | ||||
| if sys.platform != 'win32': | ||||
|     from asyncio import unix_events | ||||
| 
 | ||||
| # Program blocking | ||||
| PROGRAM_BLOCKED = [sys.executable, '-c', 'import time; time.sleep(3600)'] | ||||
| 
 | ||||
| # Program copying input to output | ||||
| PROGRAM_CAT = [ | ||||
|     sys.executable, '-c', | ||||
|     ';'.join(('import sys', | ||||
|               'data = sys.stdin.buffer.read()', | ||||
|               'sys.stdout.buffer.write(data)'))] | ||||
| 
 | ||||
| class TestSubprocessTransport(base_subprocess.BaseSubprocessTransport): | ||||
|     def _start(self, *args, **kwargs): | ||||
|         self._proc = mock.Mock() | ||||
|         self._proc.stdin = None | ||||
|         self._proc.stdout = None | ||||
|         self._proc.stderr = None | ||||
| 
 | ||||
| 
 | ||||
| class SubprocessTransportTests(test_utils.TestCase): | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = self.new_test_loop() | ||||
|         self.set_event_loop(self.loop) | ||||
| 
 | ||||
| 
 | ||||
|     def create_transport(self, waiter=None): | ||||
|         protocol = mock.Mock() | ||||
|         protocol.connection_made._is_coroutine = False | ||||
|         protocol.process_exited._is_coroutine = False | ||||
|         transport = TestSubprocessTransport( | ||||
|                         self.loop, protocol, ['test'], False, | ||||
|                         None, None, None, 0, waiter=waiter) | ||||
|         return (transport, protocol) | ||||
| 
 | ||||
|     def test_proc_exited(self): | ||||
|         waiter = asyncio.Future(loop=self.loop) | ||||
|         transport, protocol = self.create_transport(waiter) | ||||
|         transport._process_exited(6) | ||||
|         self.loop.run_until_complete(waiter) | ||||
| 
 | ||||
|         self.assertEqual(transport.get_returncode(), 6) | ||||
| 
 | ||||
|         self.assertTrue(protocol.connection_made.called) | ||||
|         self.assertTrue(protocol.process_exited.called) | ||||
|         self.assertTrue(protocol.connection_lost.called) | ||||
|         self.assertEqual(protocol.connection_lost.call_args[0], (None,)) | ||||
| 
 | ||||
|         self.assertFalse(transport.is_closing()) | ||||
|         self.assertIsNone(transport._loop) | ||||
|         self.assertIsNone(transport._proc) | ||||
|         self.assertIsNone(transport._protocol) | ||||
| 
 | ||||
|         # methods must raise ProcessLookupError if the process exited | ||||
|         self.assertRaises(ProcessLookupError, | ||||
|                           transport.send_signal, signal.SIGTERM) | ||||
|         self.assertRaises(ProcessLookupError, transport.terminate) | ||||
|         self.assertRaises(ProcessLookupError, transport.kill) | ||||
| 
 | ||||
|         transport.close() | ||||
| 
 | ||||
| 
 | ||||
| class SubprocessMixin: | ||||
| 
 | ||||
|     def test_stdin_stdout(self): | ||||
|         args = PROGRAM_CAT | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def run(data): | ||||
|             proc = yield from asyncio.create_subprocess_exec( | ||||
|                                           *args, | ||||
|                                           stdin=subprocess.PIPE, | ||||
|                                           stdout=subprocess.PIPE, | ||||
|                                           loop=self.loop) | ||||
| 
 | ||||
|             # feed data | ||||
|             proc.stdin.write(data) | ||||
|             yield from proc.stdin.drain() | ||||
|             proc.stdin.close() | ||||
| 
 | ||||
|             # get output and exitcode | ||||
|             data = yield from proc.stdout.read() | ||||
|             exitcode = yield from proc.wait() | ||||
|             return (exitcode, data) | ||||
| 
 | ||||
|         task = run(b'some data') | ||||
|         task = asyncio.wait_for(task, 60.0, loop=self.loop) | ||||
|         exitcode, stdout = self.loop.run_until_complete(task) | ||||
|         self.assertEqual(exitcode, 0) | ||||
|         self.assertEqual(stdout, b'some data') | ||||
| 
 | ||||
|     def test_communicate(self): | ||||
|         args = PROGRAM_CAT | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def run(data): | ||||
|             proc = yield from asyncio.create_subprocess_exec( | ||||
|                                           *args, | ||||
|                                           stdin=subprocess.PIPE, | ||||
|                                           stdout=subprocess.PIPE, | ||||
|                                           loop=self.loop) | ||||
|             stdout, stderr = yield from proc.communicate(data) | ||||
|             return proc.returncode, stdout | ||||
| 
 | ||||
|         task = run(b'some data') | ||||
|         task = asyncio.wait_for(task, 60.0, loop=self.loop) | ||||
|         exitcode, stdout = self.loop.run_until_complete(task) | ||||
|         self.assertEqual(exitcode, 0) | ||||
|         self.assertEqual(stdout, b'some data') | ||||
| 
 | ||||
|     def test_shell(self): | ||||
|         create = asyncio.create_subprocess_shell('exit 7', | ||||
|                                                  loop=self.loop) | ||||
|         proc = self.loop.run_until_complete(create) | ||||
|         exitcode = self.loop.run_until_complete(proc.wait()) | ||||
|         self.assertEqual(exitcode, 7) | ||||
| 
 | ||||
|     def test_start_new_session(self): | ||||
|         # start the new process in a new session | ||||
|         create = asyncio.create_subprocess_shell('exit 8', | ||||
|                                                  start_new_session=True, | ||||
|                                                  loop=self.loop) | ||||
|         proc = self.loop.run_until_complete(create) | ||||
|         exitcode = self.loop.run_until_complete(proc.wait()) | ||||
|         self.assertEqual(exitcode, 8) | ||||
| 
 | ||||
|     def test_kill(self): | ||||
|         args = PROGRAM_BLOCKED | ||||
|         create = asyncio.create_subprocess_exec(*args, loop=self.loop) | ||||
|         proc = self.loop.run_until_complete(create) | ||||
|         proc.kill() | ||||
|         returncode = self.loop.run_until_complete(proc.wait()) | ||||
|         if sys.platform == 'win32': | ||||
|             self.assertIsInstance(returncode, int) | ||||
|             # expect 1 but sometimes get 0 | ||||
|         else: | ||||
|             self.assertEqual(-signal.SIGKILL, returncode) | ||||
| 
 | ||||
|     def test_terminate(self): | ||||
|         args = PROGRAM_BLOCKED | ||||
|         create = asyncio.create_subprocess_exec(*args, loop=self.loop) | ||||
|         proc = self.loop.run_until_complete(create) | ||||
|         proc.terminate() | ||||
|         returncode = self.loop.run_until_complete(proc.wait()) | ||||
|         if sys.platform == 'win32': | ||||
|             self.assertIsInstance(returncode, int) | ||||
|             # expect 1 but sometimes get 0 | ||||
|         else: | ||||
|             self.assertEqual(-signal.SIGTERM, returncode) | ||||
| 
 | ||||
|     @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") | ||||
|     def test_send_signal(self): | ||||
|         # 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: | ||||
|             code = 'import time; print("sleeping", flush=True); time.sleep(3600)' | ||||
|             args = [sys.executable, '-c', code] | ||||
|             create = asyncio.create_subprocess_exec(*args, | ||||
|                                                     stdout=subprocess.PIPE, | ||||
|                                                     loop=self.loop) | ||||
|             proc = self.loop.run_until_complete(create) | ||||
| 
 | ||||
|             @asyncio.coroutine | ||||
|             def send_signal(proc): | ||||
|                 # basic synchronization to wait until the program is sleeping | ||||
|                 line = yield from proc.stdout.readline() | ||||
|                 self.assertEqual(line, b'sleeping\n') | ||||
| 
 | ||||
|                 proc.send_signal(signal.SIGHUP) | ||||
|                 returncode = (yield from proc.wait()) | ||||
|                 return returncode | ||||
| 
 | ||||
|             returncode = self.loop.run_until_complete(send_signal(proc)) | ||||
|             self.assertEqual(-signal.SIGHUP, returncode) | ||||
|         finally: | ||||
|             signal.signal(signal.SIGHUP, old_handler) | ||||
| 
 | ||||
|     def prepare_broken_pipe_test(self): | ||||
|         # buffer large enough to feed the whole pipe buffer | ||||
|         large_data = b'x' * support.PIPE_MAX_SIZE | ||||
| 
 | ||||
|         # the program ends before the stdin can be feeded | ||||
|         create = asyncio.create_subprocess_exec( | ||||
|                              sys.executable, '-c', 'pass', | ||||
|                              stdin=subprocess.PIPE, | ||||
|                              loop=self.loop) | ||||
|         proc = self.loop.run_until_complete(create) | ||||
|         return (proc, large_data) | ||||
| 
 | ||||
|     def test_stdin_broken_pipe(self): | ||||
|         proc, large_data = self.prepare_broken_pipe_test() | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def write_stdin(proc, data): | ||||
|             yield from asyncio.sleep(0.5, loop=self.loop) | ||||
|             proc.stdin.write(data) | ||||
|             yield from proc.stdin.drain() | ||||
| 
 | ||||
|         coro = write_stdin(proc, large_data) | ||||
|         # drain() must raise BrokenPipeError or ConnectionResetError | ||||
|         with test_utils.disable_logger(): | ||||
|             self.assertRaises((BrokenPipeError, ConnectionResetError), | ||||
|                               self.loop.run_until_complete, coro) | ||||
|         self.loop.run_until_complete(proc.wait()) | ||||
| 
 | ||||
|     def test_communicate_ignore_broken_pipe(self): | ||||
|         proc, large_data = self.prepare_broken_pipe_test() | ||||
| 
 | ||||
|         # communicate() must ignore BrokenPipeError when feeding stdin | ||||
|         with test_utils.disable_logger(): | ||||
|             self.loop.run_until_complete(proc.communicate(large_data)) | ||||
|         self.loop.run_until_complete(proc.wait()) | ||||
| 
 | ||||
|     def test_pause_reading(self): | ||||
|         limit = 10 | ||||
|         size = (limit * 2 + 1) | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def test_pause_reading(): | ||||
|             code = '\n'.join(( | ||||
|                 'import sys', | ||||
|                 'sys.stdout.write("x" * %s)' % size, | ||||
|                 'sys.stdout.flush()', | ||||
|             )) | ||||
| 
 | ||||
|             connect_read_pipe = self.loop.connect_read_pipe | ||||
| 
 | ||||
|             @asyncio.coroutine | ||||
|             def connect_read_pipe_mock(*args, **kw): | ||||
|                 transport, protocol = yield from connect_read_pipe(*args, **kw) | ||||
|                 transport.pause_reading = mock.Mock() | ||||
|                 transport.resume_reading = mock.Mock() | ||||
|                 return (transport, protocol) | ||||
| 
 | ||||
|             self.loop.connect_read_pipe = connect_read_pipe_mock | ||||
| 
 | ||||
|             proc = yield from asyncio.create_subprocess_exec( | ||||
|                                          sys.executable, '-c', code, | ||||
|                                          stdin=asyncio.subprocess.PIPE, | ||||
|                                          stdout=asyncio.subprocess.PIPE, | ||||
|                                          limit=limit, | ||||
|                                          loop=self.loop) | ||||
|             stdout_transport = proc._transport.get_pipe_transport(1) | ||||
| 
 | ||||
|             stdout, stderr = yield from proc.communicate() | ||||
| 
 | ||||
|             # The child process produced more than limit bytes of output, | ||||
|             # the stream reader transport should pause the protocol to not | ||||
|             # allocate too much memory. | ||||
|             return (stdout, stdout_transport) | ||||
| 
 | ||||
|         # Issue #22685: Ensure that the stream reader pauses the protocol | ||||
|         # when the child process produces too much data | ||||
|         stdout, transport = self.loop.run_until_complete(test_pause_reading()) | ||||
| 
 | ||||
|         self.assertEqual(stdout, b'x' * size) | ||||
|         self.assertTrue(transport.pause_reading.called) | ||||
|         self.assertTrue(transport.resume_reading.called) | ||||
| 
 | ||||
|     def test_stdin_not_inheritable(self): | ||||
|         # asyncio issue #209: stdin must not be inheritable, otherwise | ||||
|         # the Process.communicate() hangs | ||||
|         @asyncio.coroutine | ||||
|         def len_message(message): | ||||
|             code = 'import sys; data = sys.stdin.read(); print(len(data))' | ||||
|             proc = yield from asyncio.create_subprocess_exec( | ||||
|                                           sys.executable, '-c', code, | ||||
|                                           stdin=asyncio.subprocess.PIPE, | ||||
|                                           stdout=asyncio.subprocess.PIPE, | ||||
|                                           stderr=asyncio.subprocess.PIPE, | ||||
|                                           close_fds=False, | ||||
|                                           loop=self.loop) | ||||
|             stdout, stderr = yield from proc.communicate(message) | ||||
|             exitcode = yield from proc.wait() | ||||
|             return (stdout, exitcode) | ||||
| 
 | ||||
|         output, exitcode = self.loop.run_until_complete(len_message(b'abc')) | ||||
|         self.assertEqual(output.rstrip(), b'3') | ||||
|         self.assertEqual(exitcode, 0) | ||||
| 
 | ||||
|     def test_empty_input(self): | ||||
|         @asyncio.coroutine | ||||
|         def empty_input(): | ||||
|             code = 'import sys; data = sys.stdin.read(); print(len(data))' | ||||
|             proc = yield from asyncio.create_subprocess_exec( | ||||
|                                           sys.executable, '-c', code, | ||||
|                                           stdin=asyncio.subprocess.PIPE, | ||||
|                                           stdout=asyncio.subprocess.PIPE, | ||||
|                                           stderr=asyncio.subprocess.PIPE, | ||||
|                                           close_fds=False, | ||||
|                                           loop=self.loop) | ||||
|             stdout, stderr = yield from proc.communicate(b'') | ||||
|             exitcode = yield from proc.wait() | ||||
|             return (stdout, exitcode) | ||||
| 
 | ||||
|         output, exitcode = self.loop.run_until_complete(empty_input()) | ||||
|         self.assertEqual(output.rstrip(), b'0') | ||||
|         self.assertEqual(exitcode, 0) | ||||
| 
 | ||||
|     def test_cancel_process_wait(self): | ||||
|         # Issue #23140: cancel Process.wait() | ||||
| 
 | ||||
|         @asyncio.coroutine | ||||
|         def cancel_wait(): | ||||
|             proc = yield from asyncio.create_subprocess_exec( | ||||
|                                           *PROGRAM_BLOCKED, | ||||
|                                           loop=self.loop) | ||||
| 
 | ||||
|             # Create an internal future waiting on the process exit | ||||
|             task = self.loop.create_task(proc.wait()) | ||||
|             self.loop.call_soon(task.cancel) | ||||
|             try: | ||||
|                 yield from task | ||||
|             except asyncio.CancelledError: | ||||
|                 pass | ||||
| 
 | ||||
|             # Cancel the future | ||||
|             task.cancel() | ||||
| 
 | ||||
|             # Kill the process and wait until it is done | ||||
|             proc.kill() | ||||
|             yield from proc.wait() | ||||
| 
 | ||||
|         self.loop.run_until_complete(cancel_wait()) | ||||
| 
 | ||||
|     def test_cancel_make_subprocess_transport_exec(self): | ||||
|         @asyncio.coroutine | ||||
|         def cancel_make_transport(): | ||||
|             coro = asyncio.create_subprocess_exec(*PROGRAM_BLOCKED, | ||||
|                                                   loop=self.loop) | ||||
|             task = self.loop.create_task(coro) | ||||
| 
 | ||||
|             self.loop.call_soon(task.cancel) | ||||
|             try: | ||||
|                 yield from task | ||||
|             except asyncio.CancelledError: | ||||
|                 pass | ||||
| 
 | ||||
|         # ignore the log: | ||||
|         # "Exception during subprocess creation, kill the subprocess" | ||||
|         with test_utils.disable_logger(): | ||||
|             self.loop.run_until_complete(cancel_make_transport()) | ||||
| 
 | ||||
|     def test_cancel_post_init(self): | ||||
|         @asyncio.coroutine | ||||
|         def cancel_make_transport(): | ||||
|             coro = self.loop.subprocess_exec(asyncio.SubprocessProtocol, | ||||
|                                              *PROGRAM_BLOCKED) | ||||
|             task = self.loop.create_task(coro) | ||||
| 
 | ||||
|             self.loop.call_soon(task.cancel) | ||||
|             try: | ||||
|                 yield from task | ||||
|             except asyncio.CancelledError: | ||||
|                 pass | ||||
| 
 | ||||
|         # ignore the log: | ||||
|         # "Exception during subprocess creation, kill the subprocess" | ||||
|         with test_utils.disable_logger(): | ||||
|             self.loop.run_until_complete(cancel_make_transport()) | ||||
|             test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|     def test_close_kill_running(self): | ||||
|         @asyncio.coroutine | ||||
|         def kill_running(): | ||||
|             create = self.loop.subprocess_exec(asyncio.SubprocessProtocol, | ||||
|                                                *PROGRAM_BLOCKED) | ||||
|             transport, protocol = yield from create | ||||
| 
 | ||||
|             kill_called = False | ||||
|             def kill(): | ||||
|                 nonlocal kill_called | ||||
|                 kill_called = True | ||||
|                 orig_kill() | ||||
| 
 | ||||
|             proc = transport.get_extra_info('subprocess') | ||||
|             orig_kill = proc.kill | ||||
|             proc.kill = kill | ||||
|             returncode = transport.get_returncode() | ||||
|             transport.close() | ||||
|             yield from transport._wait() | ||||
|             return (returncode, kill_called) | ||||
| 
 | ||||
|         # Ignore "Close running child process: kill ..." log | ||||
|         with test_utils.disable_logger(): | ||||
|             returncode, killed = self.loop.run_until_complete(kill_running()) | ||||
|         self.assertIsNone(returncode) | ||||
| 
 | ||||
|         # transport.close() must kill the process if it is still running | ||||
|         self.assertTrue(killed) | ||||
|         test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|     def test_close_dont_kill_finished(self): | ||||
|         @asyncio.coroutine | ||||
|         def kill_running(): | ||||
|             create = self.loop.subprocess_exec(asyncio.SubprocessProtocol, | ||||
|                                                *PROGRAM_BLOCKED) | ||||
|             transport, protocol = yield from create | ||||
|             proc = transport.get_extra_info('subprocess') | ||||
| 
 | ||||
|             # kill the process (but asyncio is not notified immediately) | ||||
|             proc.kill() | ||||
|             proc.wait() | ||||
| 
 | ||||
|             proc.kill = mock.Mock() | ||||
|             proc_returncode = proc.poll() | ||||
|             transport_returncode = transport.get_returncode() | ||||
|             transport.close() | ||||
|             return (proc_returncode, transport_returncode, proc.kill.called) | ||||
| 
 | ||||
|         # Ignore "Unknown child process pid ..." log of SafeChildWatcher, | ||||
|         # emitted because the test already consumes the exit status: | ||||
|         # proc.wait() | ||||
|         with test_utils.disable_logger(): | ||||
|             result = self.loop.run_until_complete(kill_running()) | ||||
|             test_utils.run_briefly(self.loop) | ||||
| 
 | ||||
|         proc_returncode, transport_return_code, killed = result | ||||
| 
 | ||||
|         self.assertIsNotNone(proc_returncode) | ||||
|         self.assertIsNone(transport_return_code) | ||||
| 
 | ||||
|         # transport.close() must not kill the process if it finished, even if | ||||
|         # the transport was not notified yet | ||||
|         self.assertFalse(killed) | ||||
| 
 | ||||
|         # Unlike SafeChildWatcher, FastChildWatcher does not pop the | ||||
|         # callbacks if waitpid() is called elsewhere. Let's clear them | ||||
|         # manually to avoid a warning when the watcher is detached. | ||||
|         if sys.platform != 'win32' and \ | ||||
|            isinstance(self, SubprocessFastWatcherTests): | ||||
|             asyncio.get_child_watcher()._callbacks.clear() | ||||
| 
 | ||||
|     def test_popen_error(self): | ||||
|         # Issue #24763: check that the subprocess transport is closed | ||||
|         # when BaseSubprocessTransport fails | ||||
|         if sys.platform == 'win32': | ||||
|             target = 'asyncio.windows_utils.Popen' | ||||
|         else: | ||||
|             target = 'subprocess.Popen' | ||||
|         with mock.patch(target) as popen: | ||||
|             exc = ZeroDivisionError | ||||
|             popen.side_effect = exc | ||||
| 
 | ||||
|             create = asyncio.create_subprocess_exec(sys.executable, '-c', | ||||
|                                                     'pass', loop=self.loop) | ||||
|             with warnings.catch_warnings(record=True) as warns: | ||||
|                 with self.assertRaises(exc): | ||||
|                     self.loop.run_until_complete(create) | ||||
|                 self.assertEqual(warns, []) | ||||
| 
 | ||||
|     def test_read_stdout_after_process_exit(self): | ||||
|         @asyncio.coroutine | ||||
|         def execute(): | ||||
|             code = '\n'.join(['import sys', | ||||
|                               'for _ in range(64):', | ||||
|                               '    sys.stdout.write("x" * 4096)', | ||||
|                               'sys.stdout.flush()', | ||||
|                               'sys.exit(1)']) | ||||
| 
 | ||||
|             fut = asyncio.create_subprocess_exec( | ||||
|                 sys.executable, '-c', code, | ||||
|                 stdout=asyncio.subprocess.PIPE, | ||||
|                 loop=self.loop) | ||||
| 
 | ||||
|             process = yield from fut | ||||
|             while True: | ||||
|                 data = yield from process.stdout.read(65536) | ||||
|                 if data: | ||||
|                     yield from asyncio.sleep(0.3, loop=self.loop) | ||||
|                 else: | ||||
|                     break | ||||
| 
 | ||||
|         self.loop.run_until_complete(execute()) | ||||
| 
 | ||||
| 
 | ||||
| if sys.platform != 'win32': | ||||
|     # Unix | ||||
|     class SubprocessWatcherMixin(SubprocessMixin): | ||||
| 
 | ||||
|         Watcher = None | ||||
| 
 | ||||
|         def setUp(self): | ||||
|             super().setUp() | ||||
|             policy = asyncio.get_event_loop_policy() | ||||
|             self.loop = policy.new_event_loop() | ||||
|             self.set_event_loop(self.loop) | ||||
| 
 | ||||
|             watcher = self.Watcher() | ||||
|             watcher.attach_loop(self.loop) | ||||
|             policy.set_child_watcher(watcher) | ||||
|             self.addCleanup(policy.set_child_watcher, None) | ||||
| 
 | ||||
|     class SubprocessSafeWatcherTests(SubprocessWatcherMixin, | ||||
|                                      test_utils.TestCase): | ||||
| 
 | ||||
|         Watcher = unix_events.SafeChildWatcher | ||||
| 
 | ||||
|     class SubprocessFastWatcherTests(SubprocessWatcherMixin, | ||||
|                                      test_utils.TestCase): | ||||
| 
 | ||||
|         Watcher = unix_events.FastChildWatcher | ||||
| 
 | ||||
| else: | ||||
|     # Windows | ||||
|     class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase): | ||||
| 
 | ||||
|         def setUp(self): | ||||
|             super().setUp() | ||||
|             self.loop = asyncio.ProactorEventLoop() | ||||
|             self.set_event_loop(self.loop) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										2679
									
								
								third_party/python/Lib/test/test_asyncio/test_tasks.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2679
									
								
								third_party/python/Lib/test/test_asyncio/test_tasks.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										91
									
								
								third_party/python/Lib/test/test_asyncio/test_transports.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								third_party/python/Lib/test/test_asyncio/test_transports.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,91 @@ | |||
| """Tests for transports.py.""" | ||||
| 
 | ||||
| import unittest | ||||
| from unittest import mock | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import transports | ||||
| 
 | ||||
| 
 | ||||
| class TransportTests(unittest.TestCase): | ||||
| 
 | ||||
|     def test_ctor_extra_is_none(self): | ||||
|         transport = asyncio.Transport() | ||||
|         self.assertEqual(transport._extra, {}) | ||||
| 
 | ||||
|     def test_get_extra_info(self): | ||||
|         transport = asyncio.Transport({'extra': 'info'}) | ||||
|         self.assertEqual('info', transport.get_extra_info('extra')) | ||||
|         self.assertIsNone(transport.get_extra_info('unknown')) | ||||
| 
 | ||||
|         default = object() | ||||
|         self.assertIs(default, transport.get_extra_info('unknown', default)) | ||||
| 
 | ||||
|     def test_writelines(self): | ||||
|         transport = asyncio.Transport() | ||||
|         transport.write = mock.Mock() | ||||
| 
 | ||||
|         transport.writelines([b'line1', | ||||
|                               bytearray(b'line2'), | ||||
|                               memoryview(b'line3')]) | ||||
|         self.assertEqual(1, transport.write.call_count) | ||||
|         transport.write.assert_called_with(b'line1line2line3') | ||||
| 
 | ||||
|     def test_not_implemented(self): | ||||
|         transport = asyncio.Transport() | ||||
| 
 | ||||
|         self.assertRaises(NotImplementedError, | ||||
|                           transport.set_write_buffer_limits) | ||||
|         self.assertRaises(NotImplementedError, transport.get_write_buffer_size) | ||||
|         self.assertRaises(NotImplementedError, transport.write, 'data') | ||||
|         self.assertRaises(NotImplementedError, transport.write_eof) | ||||
|         self.assertRaises(NotImplementedError, transport.can_write_eof) | ||||
|         self.assertRaises(NotImplementedError, transport.pause_reading) | ||||
|         self.assertRaises(NotImplementedError, transport.resume_reading) | ||||
|         self.assertRaises(NotImplementedError, transport.close) | ||||
|         self.assertRaises(NotImplementedError, transport.abort) | ||||
| 
 | ||||
|     def test_dgram_not_implemented(self): | ||||
|         transport = asyncio.DatagramTransport() | ||||
| 
 | ||||
|         self.assertRaises(NotImplementedError, transport.sendto, 'data') | ||||
|         self.assertRaises(NotImplementedError, transport.abort) | ||||
| 
 | ||||
|     def test_subprocess_transport_not_implemented(self): | ||||
|         transport = asyncio.SubprocessTransport() | ||||
| 
 | ||||
|         self.assertRaises(NotImplementedError, transport.get_pid) | ||||
|         self.assertRaises(NotImplementedError, transport.get_returncode) | ||||
|         self.assertRaises(NotImplementedError, transport.get_pipe_transport, 1) | ||||
|         self.assertRaises(NotImplementedError, transport.send_signal, 1) | ||||
|         self.assertRaises(NotImplementedError, transport.terminate) | ||||
|         self.assertRaises(NotImplementedError, transport.kill) | ||||
| 
 | ||||
|     def test_flowcontrol_mixin_set_write_limits(self): | ||||
| 
 | ||||
|         class MyTransport(transports._FlowControlMixin, | ||||
|                           transports.Transport): | ||||
| 
 | ||||
|             def get_write_buffer_size(self): | ||||
|                 return 512 | ||||
| 
 | ||||
|         loop = mock.Mock() | ||||
|         transport = MyTransport(loop=loop) | ||||
|         transport._protocol = mock.Mock() | ||||
| 
 | ||||
|         self.assertFalse(transport._protocol_paused) | ||||
| 
 | ||||
|         with self.assertRaisesRegex(ValueError, 'high.*must be >= low'): | ||||
|             transport.set_write_buffer_limits(high=0, low=1) | ||||
| 
 | ||||
|         transport.set_write_buffer_limits(high=1024, low=128) | ||||
|         self.assertFalse(transport._protocol_paused) | ||||
|         self.assertEqual(transport.get_write_buffer_limits(), (128, 1024)) | ||||
| 
 | ||||
|         transport.set_write_buffer_limits(high=256, low=128) | ||||
|         self.assertTrue(transport._protocol_paused) | ||||
|         self.assertEqual(transport.get_write_buffer_limits(), (128, 256)) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										1638
									
								
								third_party/python/Lib/test/test_asyncio/test_unix_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1638
									
								
								third_party/python/Lib/test/test_asyncio/test_unix_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										164
									
								
								third_party/python/Lib/test/test_asyncio/test_windows_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								third_party/python/Lib/test/test_asyncio/test_windows_events.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,164 @@ | |||
| import os | ||||
| import sys | ||||
| import unittest | ||||
| from unittest import mock | ||||
| 
 | ||||
| if sys.platform != 'win32': | ||||
|     raise unittest.SkipTest('Windows only') | ||||
| 
 | ||||
| import _winapi | ||||
| 
 | ||||
| import asyncio | ||||
| from asyncio import _overlapped | ||||
| from asyncio import test_utils | ||||
| from asyncio import windows_events | ||||
| 
 | ||||
| 
 | ||||
| class UpperProto(asyncio.Protocol): | ||||
|     def __init__(self): | ||||
|         self.buf = [] | ||||
| 
 | ||||
|     def connection_made(self, trans): | ||||
|         self.trans = trans | ||||
| 
 | ||||
|     def data_received(self, data): | ||||
|         self.buf.append(data) | ||||
|         if b'\n' in data: | ||||
|             self.trans.write(b''.join(self.buf).upper()) | ||||
|             self.trans.close() | ||||
| 
 | ||||
| 
 | ||||
| class ProactorTests(test_utils.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.loop = asyncio.ProactorEventLoop() | ||||
|         self.set_event_loop(self.loop) | ||||
| 
 | ||||
|     def test_close(self): | ||||
|         a, b = self.loop._socketpair() | ||||
|         trans = self.loop._make_socket_transport(a, asyncio.Protocol()) | ||||
|         f = asyncio.ensure_future(self.loop.sock_recv(b, 100)) | ||||
|         trans.close() | ||||
|         self.loop.run_until_complete(f) | ||||
|         self.assertEqual(f.result(), b'') | ||||
|         b.close() | ||||
| 
 | ||||
|     def test_double_bind(self): | ||||
|         ADDRESS = r'\\.\pipe\test_double_bind-%s' % os.getpid() | ||||
|         server1 = windows_events.PipeServer(ADDRESS) | ||||
|         with self.assertRaises(PermissionError): | ||||
|             windows_events.PipeServer(ADDRESS) | ||||
|         server1.close() | ||||
| 
 | ||||
|     def test_pipe(self): | ||||
|         res = self.loop.run_until_complete(self._test_pipe()) | ||||
|         self.assertEqual(res, 'done') | ||||
| 
 | ||||
|     def _test_pipe(self): | ||||
|         ADDRESS = r'\\.\pipe\_test_pipe-%s' % os.getpid() | ||||
| 
 | ||||
|         with self.assertRaises(FileNotFoundError): | ||||
|             yield from self.loop.create_pipe_connection( | ||||
|                 asyncio.Protocol, ADDRESS) | ||||
| 
 | ||||
|         [server] = yield from self.loop.start_serving_pipe( | ||||
|             UpperProto, ADDRESS) | ||||
|         self.assertIsInstance(server, windows_events.PipeServer) | ||||
| 
 | ||||
|         clients = [] | ||||
|         for i in range(5): | ||||
|             stream_reader = asyncio.StreamReader(loop=self.loop) | ||||
|             protocol = asyncio.StreamReaderProtocol(stream_reader, | ||||
|                                                     loop=self.loop) | ||||
|             trans, proto = yield from self.loop.create_pipe_connection( | ||||
|                 lambda: protocol, ADDRESS) | ||||
|             self.assertIsInstance(trans, asyncio.Transport) | ||||
|             self.assertEqual(protocol, proto) | ||||
|             clients.append((stream_reader, trans)) | ||||
| 
 | ||||
|         for i, (r, w) in enumerate(clients): | ||||
|             w.write('lower-{}\n'.format(i).encode()) | ||||
| 
 | ||||
|         for i, (r, w) in enumerate(clients): | ||||
|             response = yield from r.readline() | ||||
|             self.assertEqual(response, 'LOWER-{}\n'.format(i).encode()) | ||||
|             w.close() | ||||
| 
 | ||||
|         server.close() | ||||
| 
 | ||||
|         with self.assertRaises(FileNotFoundError): | ||||
|             yield from self.loop.create_pipe_connection( | ||||
|                 asyncio.Protocol, ADDRESS) | ||||
| 
 | ||||
|         return 'done' | ||||
| 
 | ||||
|     def test_connect_pipe_cancel(self): | ||||
|         exc = OSError() | ||||
|         exc.winerror = _overlapped.ERROR_PIPE_BUSY | ||||
|         with mock.patch.object(_overlapped, 'ConnectPipe', side_effect=exc) as connect: | ||||
|             coro = self.loop._proactor.connect_pipe('pipe_address') | ||||
|             task = self.loop.create_task(coro) | ||||
| 
 | ||||
|             # check that it's possible to cancel connect_pipe() | ||||
|             task.cancel() | ||||
|             with self.assertRaises(asyncio.CancelledError): | ||||
|                 self.loop.run_until_complete(task) | ||||
| 
 | ||||
|     def test_wait_for_handle(self): | ||||
|         event = _overlapped.CreateEvent(None, True, False, None) | ||||
|         self.addCleanup(_winapi.CloseHandle, event) | ||||
| 
 | ||||
|         # Wait for unset event with 0.5s timeout; | ||||
|         # result should be False at timeout | ||||
|         fut = self.loop._proactor.wait_for_handle(event, 0.5) | ||||
|         start = self.loop.time() | ||||
|         done = self.loop.run_until_complete(fut) | ||||
|         elapsed = self.loop.time() - start | ||||
| 
 | ||||
|         self.assertEqual(done, False) | ||||
|         self.assertFalse(fut.result()) | ||||
|         # bpo-31008: Tolerate only 450 ms (at least 500 ms expected), | ||||
|         # because of bad clock resolution on Windows | ||||
|         self.assertTrue(0.45 <= elapsed <= 0.9, elapsed) | ||||
| 
 | ||||
|         _overlapped.SetEvent(event) | ||||
| 
 | ||||
|         # Wait for set event; | ||||
|         # result should be True immediately | ||||
|         fut = self.loop._proactor.wait_for_handle(event, 10) | ||||
|         start = self.loop.time() | ||||
|         done = self.loop.run_until_complete(fut) | ||||
|         elapsed = self.loop.time() - start | ||||
| 
 | ||||
|         self.assertEqual(done, True) | ||||
|         self.assertTrue(fut.result()) | ||||
|         self.assertTrue(0 <= elapsed < 0.3, elapsed) | ||||
| 
 | ||||
|         # asyncio issue #195: cancelling a done _WaitHandleFuture | ||||
|         # must not crash | ||||
|         fut.cancel() | ||||
| 
 | ||||
|     def test_wait_for_handle_cancel(self): | ||||
|         event = _overlapped.CreateEvent(None, True, False, None) | ||||
|         self.addCleanup(_winapi.CloseHandle, event) | ||||
| 
 | ||||
|         # Wait for unset event with a cancelled future; | ||||
|         # CancelledError should be raised immediately | ||||
|         fut = self.loop._proactor.wait_for_handle(event, 10) | ||||
|         fut.cancel() | ||||
|         start = self.loop.time() | ||||
|         with self.assertRaises(asyncio.CancelledError): | ||||
|             self.loop.run_until_complete(fut) | ||||
|         elapsed = self.loop.time() - start | ||||
|         self.assertTrue(0 <= elapsed < 0.1, elapsed) | ||||
| 
 | ||||
|         # asyncio issue #195: cancelling a _WaitHandleFuture twice | ||||
|         # must not crash | ||||
|         fut = self.loop._proactor.wait_for_handle(event) | ||||
|         fut.cancel() | ||||
|         fut.cancel() | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
							
								
								
									
										182
									
								
								third_party/python/Lib/test/test_asyncio/test_windows_utils.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								third_party/python/Lib/test/test_asyncio/test_windows_utils.py
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,182 @@ | |||
| """Tests for window_utils""" | ||||
| 
 | ||||
| import socket | ||||
| import sys | ||||
| import unittest | ||||
| import warnings | ||||
| from unittest import mock | ||||
| 
 | ||||
| if sys.platform != 'win32': | ||||
|     raise unittest.SkipTest('Windows only') | ||||
| 
 | ||||
| import _winapi | ||||
| 
 | ||||
| from asyncio import _overlapped | ||||
| from asyncio import windows_utils | ||||
| try: | ||||
|     from test import support | ||||
| except ImportError: | ||||
|     from asyncio import test_support as support | ||||
| 
 | ||||
| 
 | ||||
| class WinsocketpairTests(unittest.TestCase): | ||||
| 
 | ||||
|     def check_winsocketpair(self, ssock, csock): | ||||
|         csock.send(b'xxx') | ||||
|         self.assertEqual(b'xxx', ssock.recv(1024)) | ||||
|         csock.close() | ||||
|         ssock.close() | ||||
| 
 | ||||
|     def test_winsocketpair(self): | ||||
|         ssock, csock = windows_utils.socketpair() | ||||
|         self.check_winsocketpair(ssock, csock) | ||||
| 
 | ||||
|     @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') | ||||
|     def test_winsocketpair_ipv6(self): | ||||
|         ssock, csock = windows_utils.socketpair(family=socket.AF_INET6) | ||||
|         self.check_winsocketpair(ssock, csock) | ||||
| 
 | ||||
|     @unittest.skipIf(hasattr(socket, 'socketpair'), | ||||
|                      'socket.socketpair is available') | ||||
|     @mock.patch('asyncio.windows_utils.socket') | ||||
|     def test_winsocketpair_exc(self, m_socket): | ||||
|         m_socket.AF_INET = socket.AF_INET | ||||
|         m_socket.SOCK_STREAM = socket.SOCK_STREAM | ||||
|         m_socket.socket.return_value.getsockname.return_value = ('', 12345) | ||||
|         m_socket.socket.return_value.accept.return_value = object(), object() | ||||
|         m_socket.socket.return_value.connect.side_effect = OSError() | ||||
| 
 | ||||
|         self.assertRaises(OSError, windows_utils.socketpair) | ||||
| 
 | ||||
|     def test_winsocketpair_invalid_args(self): | ||||
|         self.assertRaises(ValueError, | ||||
|                           windows_utils.socketpair, family=socket.AF_UNSPEC) | ||||
|         self.assertRaises(ValueError, | ||||
|                           windows_utils.socketpair, type=socket.SOCK_DGRAM) | ||||
|         self.assertRaises(ValueError, | ||||
|                           windows_utils.socketpair, proto=1) | ||||
| 
 | ||||
|     @unittest.skipIf(hasattr(socket, 'socketpair'), | ||||
|                      'socket.socketpair is available') | ||||
|     @mock.patch('asyncio.windows_utils.socket') | ||||
|     def test_winsocketpair_close(self, m_socket): | ||||
|         m_socket.AF_INET = socket.AF_INET | ||||
|         m_socket.SOCK_STREAM = socket.SOCK_STREAM | ||||
|         sock = mock.Mock() | ||||
|         m_socket.socket.return_value = sock | ||||
|         sock.bind.side_effect = OSError | ||||
|         self.assertRaises(OSError, windows_utils.socketpair) | ||||
|         self.assertTrue(sock.close.called) | ||||
| 
 | ||||
| 
 | ||||
| class PipeTests(unittest.TestCase): | ||||
| 
 | ||||
|     def test_pipe_overlapped(self): | ||||
|         h1, h2 = windows_utils.pipe(overlapped=(True, True)) | ||||
|         try: | ||||
|             ov1 = _overlapped.Overlapped() | ||||
|             self.assertFalse(ov1.pending) | ||||
|             self.assertEqual(ov1.error, 0) | ||||
| 
 | ||||
|             ov1.ReadFile(h1, 100) | ||||
|             self.assertTrue(ov1.pending) | ||||
|             self.assertEqual(ov1.error, _winapi.ERROR_IO_PENDING) | ||||
|             ERROR_IO_INCOMPLETE = 996 | ||||
|             try: | ||||
|                 ov1.getresult() | ||||
|             except OSError as e: | ||||
|                 self.assertEqual(e.winerror, ERROR_IO_INCOMPLETE) | ||||
|             else: | ||||
|                 raise RuntimeError('expected ERROR_IO_INCOMPLETE') | ||||
| 
 | ||||
|             ov2 = _overlapped.Overlapped() | ||||
|             self.assertFalse(ov2.pending) | ||||
|             self.assertEqual(ov2.error, 0) | ||||
| 
 | ||||
|             ov2.WriteFile(h2, b"hello") | ||||
|             self.assertIn(ov2.error, {0, _winapi.ERROR_IO_PENDING}) | ||||
| 
 | ||||
|             res = _winapi.WaitForMultipleObjects([ov2.event], False, 100) | ||||
|             self.assertEqual(res, _winapi.WAIT_OBJECT_0) | ||||
| 
 | ||||
|             self.assertFalse(ov1.pending) | ||||
|             self.assertEqual(ov1.error, ERROR_IO_INCOMPLETE) | ||||
|             self.assertFalse(ov2.pending) | ||||
|             self.assertIn(ov2.error, {0, _winapi.ERROR_IO_PENDING}) | ||||
|             self.assertEqual(ov1.getresult(), b"hello") | ||||
|         finally: | ||||
|             _winapi.CloseHandle(h1) | ||||
|             _winapi.CloseHandle(h2) | ||||
| 
 | ||||
|     def test_pipe_handle(self): | ||||
|         h, _ = windows_utils.pipe(overlapped=(True, True)) | ||||
|         _winapi.CloseHandle(_) | ||||
|         p = windows_utils.PipeHandle(h) | ||||
|         self.assertEqual(p.fileno(), h) | ||||
|         self.assertEqual(p.handle, h) | ||||
| 
 | ||||
|         # check garbage collection of p closes handle | ||||
|         with warnings.catch_warnings(): | ||||
|             warnings.filterwarnings("ignore", "",  ResourceWarning) | ||||
|             del p | ||||
|             support.gc_collect() | ||||
|         try: | ||||
|             _winapi.CloseHandle(h) | ||||
|         except OSError as e: | ||||
|             self.assertEqual(e.winerror, 6)     # ERROR_INVALID_HANDLE | ||||
|         else: | ||||
|             raise RuntimeError('expected ERROR_INVALID_HANDLE') | ||||
| 
 | ||||
| 
 | ||||
| class PopenTests(unittest.TestCase): | ||||
| 
 | ||||
|     def test_popen(self): | ||||
|         command = r"""if 1: | ||||
|             import sys | ||||
|             s = sys.stdin.readline() | ||||
|             sys.stdout.write(s.upper()) | ||||
|             sys.stderr.write('stderr') | ||||
|             """ | ||||
|         msg = b"blah\n" | ||||
| 
 | ||||
|         p = windows_utils.Popen([sys.executable, '-c', command], | ||||
|                                 stdin=windows_utils.PIPE, | ||||
|                                 stdout=windows_utils.PIPE, | ||||
|                                 stderr=windows_utils.PIPE) | ||||
| 
 | ||||
|         for f in [p.stdin, p.stdout, p.stderr]: | ||||
|             self.assertIsInstance(f, windows_utils.PipeHandle) | ||||
| 
 | ||||
|         ovin = _overlapped.Overlapped() | ||||
|         ovout = _overlapped.Overlapped() | ||||
|         overr = _overlapped.Overlapped() | ||||
| 
 | ||||
|         ovin.WriteFile(p.stdin.handle, msg) | ||||
|         ovout.ReadFile(p.stdout.handle, 100) | ||||
|         overr.ReadFile(p.stderr.handle, 100) | ||||
| 
 | ||||
|         events = [ovin.event, ovout.event, overr.event] | ||||
|         # Super-long timeout for slow buildbots. | ||||
|         res = _winapi.WaitForMultipleObjects(events, True, 10000) | ||||
|         self.assertEqual(res, _winapi.WAIT_OBJECT_0) | ||||
|         self.assertFalse(ovout.pending) | ||||
|         self.assertFalse(overr.pending) | ||||
|         self.assertFalse(ovin.pending) | ||||
| 
 | ||||
|         self.assertEqual(ovin.getresult(), len(msg)) | ||||
|         out = ovout.getresult().rstrip() | ||||
|         err = overr.getresult().rstrip() | ||||
| 
 | ||||
|         self.assertGreater(len(out), 0) | ||||
|         self.assertGreater(len(err), 0) | ||||
|         # allow for partial reads... | ||||
|         self.assertTrue(msg.upper().rstrip().startswith(out)) | ||||
|         self.assertTrue(b"stderr".startswith(err)) | ||||
| 
 | ||||
|         # The context manager calls wait() and closes resources | ||||
|         with p: | ||||
|             pass | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue