mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	bpo-32662: Implement Server.start_serving() and Server.serve_forever() (#5312)
* bpo-32662: Implement Server.start_serving() and Server.serve_forever() New methods: * Server.start_serving(), * Server.serve_forever(), and * Server.is_serving(). Add 'start_serving' keyword parameter to loop.create_server() and loop.create_unix_server().
This commit is contained in:
		
							parent
							
								
									1aa094f740
								
							
						
					
					
						commit
						c9070d03f5
					
				
					 6 changed files with 337 additions and 38 deletions
				
			
		
							
								
								
									
										117
									
								
								Lib/test/test_asyncio/test_server.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								Lib/test/test_asyncio/test_server.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
import asyncio
 | 
			
		||||
import socket
 | 
			
		||||
import threading
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
from test.test_asyncio import utils as test_utils
 | 
			
		||||
from test.test_asyncio import functional as func_tests
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseStartServer(func_tests.FunctionalTestCaseMixin):
 | 
			
		||||
 | 
			
		||||
    def new_loop(self):
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
    def test_start_server_1(self):
 | 
			
		||||
        HELLO_MSG = b'1' * 1024 * 5 + b'\n'
 | 
			
		||||
 | 
			
		||||
        def client(sock, addr):
 | 
			
		||||
            sock.connect(addr)
 | 
			
		||||
            sock.send(HELLO_MSG)
 | 
			
		||||
            sock.recv_all(1)
 | 
			
		||||
            sock.close()
 | 
			
		||||
 | 
			
		||||
        async def serve(reader, writer):
 | 
			
		||||
            await reader.readline()
 | 
			
		||||
            main_task.cancel()
 | 
			
		||||
            writer.write(b'1')
 | 
			
		||||
            writer.close()
 | 
			
		||||
            await writer.wait_closed()
 | 
			
		||||
 | 
			
		||||
        async def main(srv):
 | 
			
		||||
            async with srv:
 | 
			
		||||
                await srv.serve_forever()
 | 
			
		||||
 | 
			
		||||
        srv = self.loop.run_until_complete(asyncio.start_server(
 | 
			
		||||
            serve, '127.0.0.1', 0, loop=self.loop, start_serving=False))
 | 
			
		||||
 | 
			
		||||
        self.assertFalse(srv.is_serving())
 | 
			
		||||
 | 
			
		||||
        main_task = self.loop.create_task(main(srv))
 | 
			
		||||
 | 
			
		||||
        addr = srv.sockets[0].getsockname()
 | 
			
		||||
        with self.assertRaises(asyncio.CancelledError):
 | 
			
		||||
            with self.tcp_client(lambda sock: client(sock, addr)):
 | 
			
		||||
                self.loop.run_until_complete(main_task)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(srv.sockets, [])
 | 
			
		||||
 | 
			
		||||
        self.assertIsNone(srv._sockets)
 | 
			
		||||
        self.assertIsNone(srv._waiters)
 | 
			
		||||
        self.assertFalse(srv.is_serving())
 | 
			
		||||
 | 
			
		||||
        with self.assertRaisesRegex(RuntimeError, r'is closed'):
 | 
			
		||||
            self.loop.run_until_complete(srv.serve_forever())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SelectorStartServerTests(BaseStartServer, unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def new_loop(self):
 | 
			
		||||
        return asyncio.SelectorEventLoop()
 | 
			
		||||
 | 
			
		||||
    @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'no Unix sockets')
 | 
			
		||||
    def test_start_unix_server_1(self):
 | 
			
		||||
        HELLO_MSG = b'1' * 1024 * 5 + b'\n'
 | 
			
		||||
        started = threading.Event()
 | 
			
		||||
 | 
			
		||||
        def client(sock, addr):
 | 
			
		||||
            started.wait(5)
 | 
			
		||||
            sock.connect(addr)
 | 
			
		||||
            sock.send(HELLO_MSG)
 | 
			
		||||
            sock.recv_all(1)
 | 
			
		||||
            sock.close()
 | 
			
		||||
 | 
			
		||||
        async def serve(reader, writer):
 | 
			
		||||
            await reader.readline()
 | 
			
		||||
            main_task.cancel()
 | 
			
		||||
            writer.write(b'1')
 | 
			
		||||
            writer.close()
 | 
			
		||||
            await writer.wait_closed()
 | 
			
		||||
 | 
			
		||||
        async def main(srv):
 | 
			
		||||
            async with srv:
 | 
			
		||||
                self.assertFalse(srv.is_serving())
 | 
			
		||||
                await srv.start_serving()
 | 
			
		||||
                self.assertTrue(srv.is_serving())
 | 
			
		||||
                started.set()
 | 
			
		||||
                await srv.serve_forever()
 | 
			
		||||
 | 
			
		||||
        with test_utils.unix_socket_path() as addr:
 | 
			
		||||
            srv = self.loop.run_until_complete(asyncio.start_unix_server(
 | 
			
		||||
                serve, addr, loop=self.loop, start_serving=False))
 | 
			
		||||
 | 
			
		||||
            main_task = self.loop.create_task(main(srv))
 | 
			
		||||
 | 
			
		||||
            with self.assertRaises(asyncio.CancelledError):
 | 
			
		||||
                with self.unix_client(lambda sock: client(sock, addr)):
 | 
			
		||||
                    self.loop.run_until_complete(main_task)
 | 
			
		||||
 | 
			
		||||
            self.assertEqual(srv.sockets, [])
 | 
			
		||||
 | 
			
		||||
            self.assertIsNone(srv._sockets)
 | 
			
		||||
            self.assertIsNone(srv._waiters)
 | 
			
		||||
            self.assertFalse(srv.is_serving())
 | 
			
		||||
 | 
			
		||||
            with self.assertRaisesRegex(RuntimeError, r'is closed'):
 | 
			
		||||
                self.loop.run_until_complete(srv.serve_forever())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@unittest.skipUnless(hasattr(asyncio, 'ProactorEventLoop'), 'Windows only')
 | 
			
		||||
class ProactorStartServerTests(BaseStartServer, unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def new_loop(self):
 | 
			
		||||
        return asyncio.ProactorEventLoop()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue