Commit 7226f78b authored by eckhart's avatar eckhart

sync commit

parent 6c236e48
......@@ -177,15 +177,21 @@ def asyncio_run(coroutine: Coroutine, loop=None) -> Any:
if loop is None:
try:
loop = asyncio.get_event_loop()
myloop = loop
except RuntimeError:
loop = asyncio.new_event_loop()
myloop = asyncio.new_event_loop()
asyncio.set_event_loop(myloop)
else:
myloop = loop
try:
result = loop.run_until_complete(coroutine)
except ConnectionResetError:
result = None
return result
return myloop.run_until_complete(coroutine)
finally:
if loop is None:
try:
loop.run_until_complete(loop.shutdown_asyncgens())
finally:
asyncio.set_event_loop(None)
loop.close()
async def asyncio_connect(host: str = USE_DEFAULT_HOST, port: int = USE_DEFAULT_PORT,
......@@ -539,8 +545,8 @@ class Server:
except KeyError:
pass # task might have been finished even before it has been registered
async def connection(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
# print("connection")
while not self.exit_connection and not self.kill_switch:
if self.data_buffer:
data = self.data_buffer # type: bytes
......@@ -560,6 +566,8 @@ class Server:
data = data[:k + l]
append_log(self.log_file, 'RECEIVE: ', data.decode(), '\n', echo=self.echo_log)
# if data:
# print(data)
if not data and reader.at_eof():
break
......@@ -655,6 +663,8 @@ class Server:
# self.server_messages.put(SERVER_ONLINE)
await self.server.serve_forever()
finally:
if self.server is not None:
await self.server.wait_closed()
if self.tp_executor is not None:
self.tp_executor.shutdown(wait=True)
self.tp_executor = None
......@@ -688,12 +698,17 @@ class Server:
# self.server_messages.put(SERVER_ONLINE)
self.loop.run_forever()
finally:
if loop is None:
asyncio.set_event_loop(None)
self.loop.run_until_complete(self.loop.shutdown_asyncgens())
self.loop.close()
self.server.close()
asyncio_run(self.server.wait_closed())
try:
self.loop.run_until_complete(self.server.wait_closed())
finally:
if loop is None:
try:
self.loop.run_until_complete(self.loop.shutdown_asyncgens())
finally:
asyncio.set_event_loop(None)
self.loop.close()
self.loop = None
# def _empty_message_queue(self):
# while not self.server_messages.empty():
......@@ -720,7 +735,6 @@ class Server:
pass
self.pp_executor = None
self.tp_executor = None
asyncio_run(self.server.wait_closed())
# self.server_messages.put(SERVER_OFFLINE)
self.stage.value = SERVER_OFFLINE
......@@ -729,7 +743,7 @@ RUN_SERVER_SCRIPT_TEMPLATE = """
import os
import sys
sys.path.append(os.path.abspath("{IMPORT_PATH}"))
sys.path.append(os.path.abspath('{IMPORT_PATH}'))
path = '.'
while not 'DHParser' in os.listdir(path) and len(path) < 20:
path = os.path.join('..', path)
......@@ -741,7 +755,7 @@ if len(path) < 20:
def run_server(host, port):
from DHParser.server import asyncio_run, Server, stop_server, has_server_stopped
stop_server(host, port)
asyncio_run(has_server_stopped(host, port))
# asyncio_run(has_server_stopped(host, port))
server = Server({PARAMETERS})
server.run_server(host, port)
......@@ -768,7 +782,9 @@ def spawn_server(host: str = USE_DEFAULT_HOST,
if python_interpreter_name_cached:
interpreter = python_interpreter_name_cached
else:
interpreter = 'python3' if os.system('python3 -V' + null_device) == 0 else 'python'
# interpreter = 'python3' if os.system('python3 -V' + null_device) == 0 else 'python'
interpreter = '/home/eckhart/.local/bin/python3.5'
# interpreter = "pypy3"
python_interpreter_name_cached = interpreter
run_server_script = RUN_SERVER_SCRIPT_TEMPLATE.format(
HOST=host, PORT=port, INITIALIZATION=initialization,
......@@ -776,36 +792,12 @@ def spawn_server(host: str = USE_DEFAULT_HOST,
subprocess.Popen([interpreter, '-c', run_server_script])
def stop_server(host: str = USE_DEFAULT_HOST, port: int = USE_DEFAULT_PORT) \
-> Optional[Exception]:
"""Sends a STOP_SERVER_REQUEST to a running server. Returns any exceptions
that occurred."""
async def send_stop_server(host: str, port: int) -> Optional[Exception]:
try:
reader, writer = await asyncio.open_connection(host, port)
writer.write(STOP_SERVER_REQUEST)
await writer.drain()
_ = await reader.read(1024)
writer.write_eof()
writer.close()
if sys.version_info >= (3, 7):
await writer.wait_closed()
except ConnectionRefusedError as error:
return error
except ConnectionResetError as error:
return error
return None
host, port = substitute_default_host_and_port(host, port)
return asyncio_run(send_stop_server(host, port))
async def has_server_stopped(host: str = USE_DEFAULT_HOST,
port: int = USE_DEFAULT_PORT,
timeout: float = 1.0) -> bool:
"""
Returns True, if no server is running or any server that is running
stops within the given timeout.
has stopped within the given timeout.
"""
host, port = substitute_default_host_and_port(host, port)
delay = timeout / 2**7 if timeout > 0.0 else timeout - 0.001
......@@ -821,8 +813,36 @@ async def has_server_stopped(host: str = USE_DEFAULT_HOST,
delay = timeout # exit while loop
return False
except ConnectionRefusedError:
return True
def stop_server(host: str = USE_DEFAULT_HOST, port: int = USE_DEFAULT_PORT,
timeout: float = 1.0) -> Optional[Exception]:
"""Sends a STOP_SERVER_REQUEST to a running server. Returns any exceptions
that occurred."""
async def send_stop_server(host: str, port: int) -> Optional[Exception]:
try:
reader, writer = await asyncio.open_connection(host, port)
writer.write(STOP_SERVER_REQUEST)
await writer.drain()
_ = await reader.read(1024)
writer.write_eof()
writer.close()
if sys.version_info >= (3, 7):
await writer.wait_closed()
if timeout > 0.0:
await has_server_stopped(host, port)
except ConnectionRefusedError as error:
return error
except ConnectionResetError as error:
return error
return None
host, port = substitute_default_host_and_port(host, port)
return asyncio_run(send_stop_server(host, port))
#######################################################################
#
# Language-Server-Protocol support
......
......@@ -713,29 +713,32 @@ def create_test_templates(symbols_or_ebnf: Union[str, SymbolsDictType],
#######################################################################
def run_tests_in_class(test, namespace):
def run_tests_in_class(cls_name, namespace, methods=()):
"""
Runs all tests in test-class `test` in the given namespace.
Runs tests in test-class `test` in the given namespace.
"""
def instantiate(cls_name, namespace):
exec("obj = " + cls_name + "()", namespace)
obj = namespace["obj"]
if "setup" in dir(obj):
obj.setup()
return obj
def instantiate(cls, nspace):
"""Instantiates class name `cls` within name-space `nspace` and
returns the instance."""
exec("instance = " + cls + "()", nspace)
instance = nspace["instance"]
if "setup" in dir(instance):
instance.setup()
return instance
obj = None
try:
if test.find('.') >= 0:
cls_name, method_name = test.split('.')
if methods:
obj = instantiate(cls_name, namespace)
print("Running " + cls_name + "." + method_name)
exec('obj.' + method_name + '()')
for name in methods:
print("Running " + cls_name + "." + name)
exec('obj.' + name + '()')
else:
obj = instantiate(test, namespace)
obj = instantiate(cls_name, namespace)
for name in dir(obj):
if name.lower().startswith("test"):
print("Running " + test + "." + name)
print("Running " + cls_name + "." + name)
exec('obj.' + name + '()')
finally:
if "teardown" in dir(obj):
......@@ -783,7 +786,7 @@ def runner(tests, namespace):
from DHParser.testing import runner
runner("", globals())
"""
test_classes = []
test_classes = collections.OrderedDict()
test_functions = []
if tests:
......@@ -791,17 +794,22 @@ def runner(tests, namespace):
tests = tests.split(' ')
assert all(test.lower().startswith('test') for test in tests)
else:
tests = namespace.keys()
tests = [name for name in sys.argv[1:] if name.lower().startswith('test')]
if not tests:
tests = [name for name in namespace.keys() if name.lower().startswith('test')]
for name in tests:
if name.lower().startswith('test'):
if inspect.isclass(namespace[name]):
test_classes.append(name)
elif inspect.isfunction(namespace[name]):
test_functions.append(name)
for test in test_classes:
run_tests_in_class(test, namespace)
func_or_class, method = (name.split('.') + [''])[:2]
if inspect.isclass(namespace[func_or_class]):
if func_or_class not in test_classes:
test_classes[func_or_class] = []
if method:
test_classes[func_or_class].append(method)
elif inspect.isfunction(namespace[name]):
test_functions.append(name)
for cls_name, methods in test_classes.items():
run_tests_in_class(cls_name, namespace, methods)
for test in test_functions:
run_test_function(test, namespace)
......
......@@ -76,6 +76,7 @@ def send_request(request: str, expect_response: bool = True) -> str:
jrpc_id = 0
def json_rpc(method: str, params: dict) -> str:
global jrpc_id
jrpc_id += 1
......@@ -94,7 +95,6 @@ class TestServer:
def teardown(self):
stop_server('127.0.0.1', TEST_PORT)
asyncio_run(has_server_stopped('127.0.0.1', TEST_PORT))
def test_server_process(self):
"""Basic Test of server module."""
......@@ -240,7 +240,6 @@ class TestSpawning:
def teardown(self):
stop_server('127.0.0.1', TEST_PORT)
asyncio_run(has_server_stopped('127.0.0.1', TEST_PORT))
def test_spawn(self):
spawn_server('127.0.0.1', TEST_PORT, import_path=scriptpath)
......@@ -345,11 +344,9 @@ class TestLanguageServer:
def teardown(self):
stop_server('127.0.0.1', TEST_PORT)
asyncio_run(has_server_stopped('127.0.0.1', TEST_PORT))
def start_server(self):
stop_server('127.0.0.1', TEST_PORT)
asyncio_run(has_server_stopped('127.0.0.1', TEST_PORT))
spawn_server('127.0.0.1', TEST_PORT,
'from test_server import LSP, gen_lsp_table\n'
'lsp = LSP()\n'
......@@ -363,9 +360,7 @@ class TestLanguageServer:
{'processId': 701,
'rootUri': 'file://~/tmp',
'capabilities': {}}))
i = response.find('"jsonrpc"') - 1
while i > 0 and response[i] in ('{', '['):
i -= 1
i = response.find('{') - 1
res = json.loads(response[i:])
assert 'result' in res and 'capabilities' in res['result'], str(res)
......@@ -392,16 +387,15 @@ class TestLanguageServer:
def test_initializion_sequence(self):
self.start_server()
async def initialization_seuquence():
async def initialization_sequence():
reader, writer = await asyncio_connect('127.0.0.1', TEST_PORT)
writer.write(json_rpc('initialize',
{'processId': 702,
'rootUri': 'file://~/tmp',
'capabilities': {}}).encode())
response = (await reader.read(8192)).decode()
i = response.find('"jsonrpc"') - 1
while i > 0 and response[i] in ('{', '['):
i -= 1
i = response.find('{')
print(len(response), response)
res = json.loads(response[i:])
assert 'result' in res and 'capabilities' in res['result'], str(res)
......@@ -411,10 +405,9 @@ class TestLanguageServer:
response = (await reader.read(8192)).decode()
assert response.find('test') >= 0
asyncio_run(initialization_seuquence())
asyncio_run(initialization_sequence())
if __name__ == "__main__":
from DHParser.testing import runner
runner("", globals())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment