def setup(self): self.pipeA = MockStream('pipeA') self.pipeB = MockStream('pipeB') self.readerA = StreamReaderProxy(self.pipeA) self.writerA = StreamWriterProxy(self.pipeA) self.readerB = StreamReaderProxy(self.pipeB) self.writerB = StreamWriterProxy(self.pipeB)
def setup(self): self.EBNF_lsp = EBNFServer.EBNFLanguageServerProtocol() self.lsp_table = self.EBNF_lsp.lsp_fulltable.copy() self.lsp_table.setdefault('default', EBNFParser.compile_src) self.pipeA = MockStream('pipeA') self.pipeB = MockStream('pipeB') self.readerA = StreamReaderProxy(self.pipeA) self.writerA = StreamWriterProxy(self.pipeA) self.readerB = StreamReaderProxy(self.pipeB) self.writerB = StreamWriterProxy(self.pipeB)
class TestServer: def setup(self): self.pipeA = MockStream('pipeA') self.pipeB = MockStream('pipeB') self.readerA = StreamReaderProxy(self.pipeA) self.writerA = StreamWriterProxy(self.pipeA) self.readerB = StreamReaderProxy(self.pipeB) self.writerB = StreamWriterProxy(self.pipeB) def teardown(self): self.writerA.close() self.writerB.close() def test_server_process(self): """Basic Test of server module.""" async def compile_remote(src, reader, writer) -> bytes: writer.write(add_header(src.encode())) await writer.drain() data = await read_full_content(reader) # writer.close() # if sys.version_info >= (3, 7): await writer.wait_closed() header, data, backlog = split_header(data) return data.decode() # assert data.decode() == "Test", data.decode() p = None try: p = spawn_stream_server(self.readerA, self.writerB, (mock_compiler, set()), threading.Thread) data = asyncio_run( compile_remote('Test', self.readerB, self.writerA)) assert data == "tEST" finally: if p is not None: stop_stream_server(self.readerB, self.writerA) p.join()
def run_server(host, port, log_path=None): """ Starts a new atfServer. If `port` is already occupied, different ports will be tried. """ global KNOWN_HOST, KNOWN_PORT global scriptpath, servername from multiprocessing import set_start_method # 'forkserver' or 'spawn' required to avoid broken process pools if sys.platform.lower().startswith('linux'): set_start_method('forkserver') else: set_start_method('spawn') grammar_src = os.path.abspath(__file__).replace('Server.py', '.ebnf') dhparserdir = os.path.abspath(os.path.join(scriptpath, '../..')) if scriptpath not in sys.path: sys.path.append(scriptpath) if dhparserdir not in sys.path: sys.path.append(dhparserdir) # from tst_atf_grammar import recompile_grammar # recompile_grammar(os.path.join(scriptpath, 'atf.ebnf'), force=False) from DHParser.dsl import recompile_grammar if not recompile_grammar( grammar_src, force=False, notify=lambda: print('recompiling ' + grammar_src)): print('\nErrors while recompiling "%s":' % grammar_src + '\n--------------------------------------\n\n') with open('atf_ebnf_ERRORS.txt', encoding='utf-8') as f: print(f.read()) sys.exit(1) from atfParser import compile_src from DHParser.server import Server, probe_tcp_server, StreamReaderProxy, StreamWriterProxy from DHParser.lsp import gen_lsp_table atf_lsp = atfLanguageServerProtocol() lsp_table = atf_lsp.lsp_fulltable.copy() lsp_table.setdefault('default', compile_src) atf_server = Server(rpc_functions=lsp_table, cpu_bound=atf_lsp.cpu_bound.lsp_table.keys(), blocking=atf_lsp.blocking.lsp_table.keys(), connection_callback=atf_lsp.connect, server_name="atfServer", strict_lsp=True) if log_path is not None: # echoing does not work with stream connections! atf_server.echo_log = True if port >= 0 and host else False msg = atf_server.start_logging(log_path.strip('" \'')) if atf_server.echo_log: echo(msg) if port < 0 or not host: # communication via streams instead of tcp server reader = StreamReaderProxy(sys.stdin) writer = StreamWriterProxy(sys.stdout) atf_server.run_stream_server(reader, writer) return cfg_filename = get_config_filename() overwrite = not os.path.exists(cfg_filename) ports = ALTERNATIVE_PORTS.copy() if port == DEFAULT_PORT else [] if port in ports: ports.remove(port) ports.append(port) while ports: port = ports.pop() if (host, port) == (KNOWN_HOST, KNOWN_PORT): ident = asyncio_run( probe_tcp_server(host, port, SERVER_REPLY_TIMEOUT)) if ident: if ident.endswith(servername): echo( 'A server of type "%s" already exists on %s:%i.' % (servername, host, port) + ' Use --port option to start a secondary server on a different port.' ) sys.exit(1) if ports: echo('"%s" already occupies %s:%i. Trying port %i' % (ident, host, port, ports[-1])) continue else: echo('"%s" already occupies %s:%i. No more ports to try.' % (ident, host, port)) sys.exit(1) if overwrite: try: with open(cfg_filename, 'w') as f: debug('Storing host and port value %s:%i in file "%s".' % (host, port, cfg_filename)) f.write(host + ' ' + str(port)) except (PermissionError, IOError) as e: echo('%s: Could not write temporary config file: "%s"' % (str(e), cfg_filename)) ports = [] else: echo( 'Configuration file "%s" already existed and was not overwritten. ' 'Use option "--port %i" to stop this server!' % (cfg_filename, port)) try: debug('Starting server on %s:%i' % (host, port)) atf_server.run_tcp_server( host, port) # returns only after server has stopped! ports = [] except OSError as e: if not (ports and e.errno == 98): echo(e) echo('Could not start server. Shutting down!') sys.exit(1) elif ports: echo('Could not start server on %s:%i. Trying port %s' % (host, port, ports[-1])) else: echo('Could not start server on %s:%i. No more ports to try.' % (host, port)) finally: if not ports: echo('Server on %s:%i stopped' % (host, port)) if overwrite: try: os.remove(cfg_filename) debug('removing temporary config file: ' + cfg_filename) except FileNotFoundError: pass
def setup(self): self.pipe = MockStream() self.reader = StreamReaderProxy(self.pipe) self.writer = StreamWriterProxy(self.pipe)
class TestStreamProxies: def setup(self): self.pipe = MockStream() self.reader = StreamReaderProxy(self.pipe) self.writer = StreamWriterProxy(self.pipe) def teardown(self): self.writer.close() def test_pipe(self): message = b"alpha\nbeta\ngamma\n" def writer(pipe: MockStream): nonlocal message for i in range(0, len(message), 2): pipe.write(message[i:i + 2]) pipe.flush() def reader(pipe: MockStream): nonlocal message received = [] for i in range(3): received.append(pipe.readline()) return b''.join(received) with ThreadPoolExecutor() as executor: future = executor.submit(reader, self.pipe) executor.submit(writer, self.pipe) assert future.result() == message def test_reader_writer_simple(self): async def main(): self.writer.write(b'Hello\n') await self.writer.drain() data = await self.reader.read() self.writer.close() return data data = asyncio_run(main()) assert data == b'Hello\n', str(data) assert self.pipe.closed def test_reader_writer(self): async def write(writer): writer.write(JSONRPC_HEADER_BYTES % len(IDENTIFY_REQUEST_BYTES) + IDENTIFY_REQUEST_BYTES) await writer.drain() async def read(reader): return await read_full_content(reader) async def main(): if sys.version_info >= (3, 7): read_task = asyncio.create_task(read(self.reader)) write_task = asyncio.create_task(write(self.writer)) else: read_task = asyncio.ensure_future(read(self.reader)) write_task = asyncio.ensure_future(write(self.writer)) data = await read_task await write_task self.writer.close() return data data = asyncio_run(main()) assert data == b'Content-Length: 10\r\n\r\nidentify()', str(data) assert self.pipe.closed