diff --git a/src/testium/interpreter/process.py b/src/testium/interpreter/process.py index 2762ba5..9432d3b 100644 --- a/src/testium/interpreter/process.py +++ b/src/testium/interpreter/process.py @@ -88,10 +88,10 @@ class TestProcess(Process): test_set.report_path = locate_report_file(test_set.report_path) # Python & lua functions call subprocess initialization - py_fproc = py_func_call_init(tm.gd("python_path", ""), api_request) + py_fproc = py_func_call_init(tm.gd("python_path", ""), api_request, 10) lua_fproc = None if test_set.isTestTypePresent(cst_type.TYPE_LUA_FUNCTION): - lua_fproc = lua_func_call_init(tm.gd("lua_path", ""), api_request) + lua_fproc = lua_func_call_init(tm.gd("lua_path", ""), api_request, 10) self.__loaded = True diff --git a/src/testium/interpreter/utils/jrpc.py b/src/testium/interpreter/utils/jrpc.py index d1ffa35..83d85cf 100644 --- a/src/testium/interpreter/utils/jrpc.py +++ b/src/testium/interpreter/utils/jrpc.py @@ -321,26 +321,23 @@ class JsonRpcSrv(JsonRpcBase): # Link of the socket at the configured port sock.bind((self._host, self._port)) - sock.settimeout(self._timeout) - # Listens incoming connections sock.listen(1) self.print_info(f"listening on {self._host}:{self._port}") - self.print_info("awaiting connection") + self.print_info(f"awaiting connection for {self._timeout} secs") tslice = 0.2 + sock.settimeout(tslice) t = self._timeout while True: try: conn, addr = sock.accept() self.print_info("Client connected") + break except socket.timeout: - if t >= 0: - sleep(tslice) - continue - else: + t -= tslice + if t < 0: raise ETUMRuntimeError(f"{self.name}: Timeout") - break self.print_info("Client connected") with conn: @@ -380,13 +377,21 @@ class JsonRpcClient(JsonRpcBase): # TCP/IP socket creation try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - sock.settimeout(self._timeout) + tslice = 0.5 + t = self._timeout + sock.settimeout(tslice) # Link of the socket at the configured port - try: - sock.connect((self._host, self._port)) - except OSError: - raise ETUMRuntimeError(f"{self.name}: failed to connect") - + while True: + try: + sock.connect((self._host, self._port)) + break + except OSError as e: + t -= tslice + if t < 0: + raise ETUMRuntimeError(f"{self.name}: failed to connect : {e}") + else: + sleep(tslice) + self.print_info("Connected to server") self.connect(sock) diff --git a/src/testium/interpreter/utils/lua_func_exec.py b/src/testium/interpreter/utils/lua_func_exec.py index 9a190ed..6629bcf 100644 --- a/src/testium/interpreter/utils/lua_func_exec.py +++ b/src/testium/interpreter/utils/lua_func_exec.py @@ -11,9 +11,9 @@ from interpreter.test_items.test_result import TestValue function_call_process = None -def lua_func_call_init(lua_path, request_handler): +def lua_func_call_init(lua_path, request_handler, timeout): global function_call_process - function_call_process = LuaFuncExecEngine(lua_path, request_handler) + function_call_process = LuaFuncExecEngine(lua_path, request_handler, timeout) return function_call_process @@ -33,7 +33,7 @@ def is_lua_interpreter(path: str, timeout=2) -> bool: class LuaFuncExecEngine: - def __init__(self, lua_path="", request_handler=None): + def __init__(self, lua_path="", request_handler=None, timeout=10): if lua_path != "": if shutil.which(lua_path) is None: raise ETUMRuntimeError( @@ -56,6 +56,7 @@ class LuaFuncExecEngine: self._req_handler = request_handler self._process = None self._port = 0 + self._timeout = timeout self._rpc = None def start(self): @@ -74,7 +75,7 @@ class LuaFuncExecEngine: lua_env = tm.gd("lua_env", {}) tm.print_debug(f"lua_env : {lua_env}") - params = [self._lpath, "main.lua", "--timeout", "10", "--host", "127.0.0.1", "--port", f"{self._port}"] + params = [self._lpath, "main.lua", "--timeout", f"{self._timeout}", "--host", "127.0.0.1", "--port", f"{self._port}"] if tm.debug_enabled(): params.append("--verbose") diff --git a/src/testium/interpreter/utils/paths.py b/src/testium/interpreter/utils/paths.py index c8285c0..2e16953 100644 --- a/src/testium/interpreter/utils/paths.py +++ b/src/testium/interpreter/utils/paths.py @@ -48,10 +48,10 @@ def _python_version(path: str): cmd = f'"{path}" -c "import sys; print(sys.version_info[:3])"' try: result = subprocess.run( - cmd, - shell=True, - capture_output=True, - text=True, + cmd, + shell=True, + capture_output=True, + text=True, encoding=sys_encoding(), timeout=10 ) @@ -63,13 +63,13 @@ def _python_version(path: str): def _lua_version(path: str): - cmd = f'"{path}" -v"' + cmd = f'"{path}" -v' try: result = subprocess.run( cmd, shell=True, - capture_output=True, - text=True, + capture_output=True, + text=True, encoding=sys_encoding(), timeout=10 ) @@ -79,9 +79,11 @@ def _lua_version(path: str): data = "" try: vers = ((data.split(" "))[1]).split(".") + if len(vers) != 3: + vers = (0,0,0) except: - vers = (0, 0, 0) - return (vers[0], vers[1], vers[2]) + vers = (0,0,0) + return tuple(vers) def is_python3(python_path): @@ -91,7 +93,7 @@ def is_python3(python_path): res = True except: res = False - + return res @@ -106,10 +108,10 @@ def is_lua51(lua_path): def _sys_app_path_win(app_name): try: result = subprocess.run( - f"where {app_name}", - shell=True, - capture_output=True, - text=True, + f"where {app_name}", + shell=True, + capture_output=True, + text=True, encoding="oem", timeout=10 ) @@ -127,10 +129,10 @@ def _sys_app_path_win(app_name): def _sys_app_path_lin(app_name): try: result = subprocess.run( - f"which {app_name}", - shell=True, - capture_output=True, - text=True, + f"which {app_name}", + shell=True, + capture_output=True, + text=True, timeout=10 ) data = result.stdout diff --git a/src/testium/interpreter/utils/py_func_exec.py b/src/testium/interpreter/utils/py_func_exec.py index 9e04bf8..8aa4854 100644 --- a/src/testium/interpreter/utils/py_func_exec.py +++ b/src/testium/interpreter/utils/py_func_exec.py @@ -11,9 +11,9 @@ from interpreter.test_items.test_result import TestValue function_call_process = None -def py_func_call_init(python_path, request_handler): +def py_func_call_init(python_path, request_handler, timeout): global function_call_process - function_call_process = PyFuncExecEngine(python_path, request_handler) + function_call_process = PyFuncExecEngine(python_path, request_handler, timeout) return function_call_process @@ -33,7 +33,7 @@ def is_python_interpreter(path: str, timeout=2) -> bool: class PyFuncExecEngine: - def __init__(self, python_path="", request_handler=None): + def __init__(self, python_path="", request_handler=None, timeout=10): if python_path != "": if shutil.which(python_path) is None: @@ -58,6 +58,7 @@ class PyFuncExecEngine: self._req_handler = request_handler self._process = None self._port = 0 + self._timeout = timeout self._rpc = None def start(self): @@ -74,7 +75,7 @@ class PyFuncExecEngine: func_proc_path = tm.gd("testium_path") - params = [self._ppath, "-m", "py_func", "-p", f"{self._port}"] + params = [self._ppath, "-m", "py_func", "-p", f"{self._port}", "-t", f"{self._timeout}"] if tm.debug_enabled(): params.append("-v") diff --git a/src/testium/lua_func/main.lua b/src/testium/lua_func/main.lua index 5c51356..2b405bc 100644 --- a/src/testium/lua_func/main.lua +++ b/src/testium/lua_func/main.lua @@ -74,7 +74,7 @@ end server_sock:listen(1) local ip, port = server_sock:getsockname() -utils.log("listening on %s:%d", ip, port) +utils.log("listening on %s:%d for %.1f secs", ip, port, config.timeout) server_sock:settimeout(config.timeout) -- Prevents hanging on dead connections diff --git a/src/testium/py_func/__init__.py b/src/testium/py_func/__init__.py index b8414d4..d6c4513 100755 --- a/src/testium/py_func/__init__.py +++ b/src/testium/py_func/__init__.py @@ -26,15 +26,19 @@ def main(): default="localhost") parser.add_argument("-p", "--port", type=int, help="port to listen to", default=9000) + parser.add_argument("-t", "--timeout", type=float, help="Timeout waiting for connection", + default=10) parser.add_argument("-v", "--verbose", action='store_true', help="port to listen to") args = parser.parse_args() - thrd_api = _init_api(args.ip, args.port) + thrd_api = _init_api(args.ip, args.port, args.timeout) + # redirect I/O outstream = TcpStdOut() stdio_redir.redirect(outstream) # debug the server if args.verbose: thrd_api.dbg_out = stdio_redir.ini_stdout + thrd_api.start() try: while thrd_api.is_alive(): thrd_api.join(1) diff --git a/src/testium/py_func/tm.py b/src/testium/py_func/tm.py index 4c3010b..2d0ebf9 100644 --- a/src/testium/py_func/tm.py +++ b/src/testium/py_func/tm.py @@ -49,7 +49,7 @@ def _make_api(name): for k in SUPPORTED_API: setattr(thismodule, k, _make_api(k)) -def _init_api(host, port): +def _init_api(host, port, timeout): """Start and initialize the remote function handler. Starts a ``FuncHandler`` bound to ``port``, runs it and blocks until @@ -63,9 +63,7 @@ def _init_api(host, port): ``_func_call_thread``. """ global _func_call_thread - _func_call_thread = FuncHandler(host, port) - _func_call_thread.start() - _func_call_thread.wait_ready() + _func_call_thread = FuncHandler(host, port, timeout=timeout) return _func_call_thread