Commit 72f4531d authored by Eckhart Arnold's avatar Eckhart Arnold

test_server.py: fix spwaning test

parent 020af6fb
......@@ -42,7 +42,7 @@ from DHParser.syntaxtree import Node, RootNode, ZOMBIE_TAG, StrictResultType
from DHParser.transform import TransformationFunc
from DHParser.parse import Grammar
from DHParser.error import adjust_error_locations, is_error, is_fatal, Error
from DHParser.log import log_parsing_history, log_ST, is_logging, logfile_basename
from DHParser.log import log_parsing_history, log_ST, is_logging
from DHParser.toolkit import load_if_file, get_config_value
......@@ -126,7 +126,7 @@ class Compiler:
self.context = [] # type: List[Node]
self._None_check = True # type: bool
self._dirty_flag = False
self._debug = get_config_value('debug') # type: bool
self._debug = get_config_value('debug_compiler') # type: bool
self._debug_already_compiled = set() # type: Set[Node]
self.finalizers = [] # type: List[Callable, Tuple]
......@@ -221,6 +221,21 @@ class Compiler:
return result
def logfile_basename(filename_or_text, function_or_class_or_instance) -> str:
"""Generates a reasonable logfile-name (without extension) based on
the given information.
"""
if is_filename(filename_or_text):
return os.path.basename(os.path.splitext(filename_or_text)[0])
else:
try:
name = function_or_class_or_instance.__qualname.__
except AttributeError:
name = function_or_class_or_instance.__class__.__name__
i = name.find('.')
return name[:i] + '_out' if i >= 0 else name
def compile_source(source: str,
preprocessor: Optional[PreprocessorFunc], # str -> str
parser: Grammar, # str -> Node (concrete syntax tree (CST))
......@@ -261,7 +276,7 @@ def compile_source(source: str,
"""
ast = None # type: Optional[Node]
original_text = load_if_file(source) # type: str
log_file_name = logfile_basename(source, compiler) # type: str
log_file_name = logfile_basename(source, compiler) if is_logging() else '' # type: str
# preprocessing
......
......@@ -173,9 +173,10 @@ CONFIG_PRESET['server_default_port'] = 8888
#
########################################################################
# Turn on (costly) debugging functionality.
# Default value: False
CONFIG_PRESET['debug'] = False
# Turn on (costly) debugging functionality for any of the respective
# modules or subsystems.
# Default value: always False
CONFIG_PRESET['debug_compiler'] = False
########################################################################
......
......@@ -62,7 +62,7 @@ from DHParser.toolkit import is_filename, escape_control_characters, GLOBALS
__all__ = ('log_dir',
'logging',
'is_logging',
'logfile_basename',
'append_log',
'clear_logs',
'HistoryRecord',
'log_ST',
......@@ -151,19 +151,13 @@ def is_logging() -> bool:
return False
def logfile_basename(filename_or_text, function_or_class_or_instance) -> str:
"""Generates a reasonable logfile-name (without extension) based on
the given information.
def append_log(log_name: str, text: str) -> None:
"""Appends text to the log-file with the name 'log_name' if logging is on.
"""
if is_filename(filename_or_text):
return os.path.basename(os.path.splitext(filename_or_text)[0])
else:
try:
name = function_or_class_or_instance.__qualname.__
except AttributeError:
name = function_or_class_or_instance.__class__.__name__
i = name.find('.')
return name[:i] + '_out' if i >= 0 else name
ldir = log_dir()
if ldir:
with open(os.path.join(ldir, log_name), 'a') as f:
f.write(text)
def clear_logs(logfile_types=frozenset(['.cst', '.ast', '.log'])):
......
......@@ -54,7 +54,8 @@ from typing import Callable, Coroutine, Optional, Union, Dict, List, Tuple, Sequ
cast
from DHParser.syntaxtree import DHParser_JSONEncoder
from DHParser.toolkit import get_config_value, re
from DHParser.log import is_logging
from DHParser.toolkit import get_config_value, GLOBALS, re
from DHParser.versionnumber import __version__
......@@ -146,15 +147,10 @@ def asyncio_run(coroutine: Coroutine, loop=None) -> Any:
return asyncio.run(coroutine)
else:
if loop is None:
myloop = asyncio.new_event_loop()
asyncio.set_event_loop(myloop)
loop = asyncio.get_event_loop()
else:
myloop = loop
result = myloop.run_until_complete(coroutine)
if loop is None:
asyncio.set_event_loop(None)
myloop.run_until_complete(myloop.shutdown_asyncgens())
myloop.close()
result = loop.run_until_complete(coroutine)
return result
......@@ -212,6 +208,8 @@ class Server:
self.pp_executor = None # type: Optional[ProcessPoolExecutor]
self.tp_executor = None # type: Optional[ThreadPoolExecutor]
self.log_file = (self.__class__.__name__ + '.log') if is_logging() else '' # type: str
self.loop = None # just for python 3.5 compatibility...
async def handle_request(self,
......
......@@ -178,6 +178,14 @@ class TestServer:
RUN_SERVER_SCRIPT = """
import os
import sys
path = '.'
while not 'DHParser' in os.listdir(path) and len(path) < 20:
path = os.path.join('..', path)
sys.path.append(path)
def dummy(s: str) -> str:
return s
......@@ -191,22 +199,28 @@ if __name__ == '__main__':
run_server('127.0.0.1', 8888)
"""
def asyncio_run(coroutine):
"""Backward compatible version of Pyhon 3.7's `asyncio.run()`"""
if sys.version_info >= (3, 7):
return asyncio.run(coroutine)
else:
loop = asyncio.get_event_loop()
return loop.run_until_complete(coroutine)
class TestSpawning:
"""Tests spawning a server by starting a script via subprocess.Popen."""
def stop_server(self):
async def send_stop_server():
try:
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write(STOP_SERVER_REQUEST)
_ = await reader.read(1024)
writer.close()
except ConnectionRefusedError:
pass
asyncio.run(send_stop_server())
def setup(self):
self.tmpdir = 'tmp_' + concurrent_ident()
os.mkdir(self.tmpdir)
self.stop_server()
def teardown(self):
self.stop_server()
for fname in os.listdir(self.tmpdir):
os.remove(os.path.join(self.tmpdir, fname))
os.rmdir(self.tmpdir)
......@@ -215,26 +229,32 @@ class TestSpawning:
scriptname = os.path.join(self.tmpdir, 'spawn_server.py')
with open(scriptname, 'w') as f:
f.write(RUN_SERVER_SCRIPT)
subprocess.Popen(['python', scriptname])
countdown = 20
delay = 0.05
connected = False
reader, writer = None, None
while countdown > 0:
try:
reader, writer = asyncio_run(asyncio.open_connection('127.0.0.1', 8888))
countdown = 0
connected = True
except ConnectionRefusedError:
time.sleep(delay)
delay += 0.0
countdown -= 1
if connected:
writer.write(IDENTIFY_REQUEST.encode())
data = asyncio_run(reader.read(500))
writer.close()
print(data.decode())
subprocess.Popen(['python3', scriptname])
async def identify():
countdown = 20
delay = 0.05
connected = False
reader, writer = None, None
while countdown > 0:
try:
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
print(countdown)
countdown = 0
connected = True
except ConnectionRefusedError:
time.sleep(delay)
delay += 0.0
countdown -= 1
if connected:
writer.write(IDENTIFY_REQUEST.encode())
data = await reader.read(500)
writer.close()
return data.decode()
return ''
result = asyncio.run(identify())
print(result)
if __name__ == "__main__":
......
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