diff --git a/src/testium/interpreter/utils/bins.py b/src/testium/interpreter/utils/bins.py index b08fd1c..796bf77 100644 --- a/src/testium/interpreter/utils/bins.py +++ b/src/testium/interpreter/utils/bins.py @@ -396,9 +396,7 @@ def ensure(*names): f"Set '{gd_key}' in the YAML config to override." ) elif not tm.gd(gd_key): - # Publish the resolved interpreter so test scripts can reference - # $(python_bin) / $(lua_bin) regardless of how testium was launched - # (e.g. GUI, where no -d override is passed). + # Publish resolved path so test scripts can use $(python_bin)/$(lua_bin). tm.setgd(gd_key, path) if missing: raise ETUMRuntimeError( diff --git a/src/testium/interpreter/utils/lua_process.py b/src/testium/interpreter/utils/lua_process.py index 7a30052..59185f0 100644 --- a/src/testium/interpreter/utils/lua_process.py +++ b/src/testium/interpreter/utils/lua_process.py @@ -116,15 +116,13 @@ class LuaProcessBase: restore_signals=False, **popen_kwargs, ) - # Route subprocess stdout/stderr into the parent's log and read the - # startup port sentinel before connecting. + # Forward subprocess output to the log and read the startup port sentinel. holder = drain_and_read_port(self._process, prefix="[lua_func] ") self._port = wait_for_port( self._process, holder, tm.gd("proc_start_timeout", 30) ) if self._port is None: - # Worker died before announcing its port: tear down fully so a - # later start() (e.g. a reused context_id engine) can retry cleanly. + # Worker died before announcing its port: reset so a later start() retries clean. self.stop() self.join() return diff --git a/src/testium/interpreter/utils/proc_drain.py b/src/testium/interpreter/utils/proc_drain.py index d6d039a..c00c4c4 100644 --- a/src/testium/interpreter/utils/proc_drain.py +++ b/src/testium/interpreter/utils/proc_drain.py @@ -77,8 +77,7 @@ def drain_and_read_port(process, prefix=""): pipe.close() except Exception: pass - # Unblock the waiter on EOF even if the sentinel never came. - holder["evt"].set() + holder["evt"].set() # unblock waiter on EOF even without sentinel if process.stdout is not None: threading.Thread( @@ -104,7 +103,6 @@ def wait_for_port(process, holder, deadline): if holder["port"] is not None: break if process.poll() is not None: - # Child exited; give the reader a moment to flush a trailing line. - holder["evt"].wait(0.2) + holder["evt"].wait(0.2) # child exited; let the reader flush a trailing line break return holder["port"] diff --git a/src/testium/interpreter/utils/py_process.py b/src/testium/interpreter/utils/py_process.py index 2248bd3..2991f10 100644 --- a/src/testium/interpreter/utils/py_process.py +++ b/src/testium/interpreter/utils/py_process.py @@ -99,17 +99,13 @@ class PyProcessBase: restore_signals=False, **popen_kwargs, ) - # Route subprocess stdout/stderr into the parent's log and read the - # startup port sentinel. Startup variance (cold start, antivirus) is - # absorbed here: we wait for the worker to announce its port before - # connecting. + # Forward subprocess output to the log and read the startup port sentinel. holder = drain_and_read_port(self._process, prefix="[py_func] ") self._port = wait_for_port( self._process, holder, tm.gd("proc_start_timeout", 30) ) if self._port is None: - # Worker died before announcing its port: tear down fully so a - # later start() (e.g. a reused context_id engine) can retry cleanly. + # Worker died before announcing its port: reset so a later start() retries clean. self.stop() self.join() return diff --git a/src/testium/py_func/__init__.py b/src/testium/py_func/__init__.py index 919d190..3e2b1be 100755 --- a/src/testium/py_func/__init__.py +++ b/src/testium/py_func/__init__.py @@ -39,8 +39,7 @@ def main(): thrd_api.dbg_out = stdio_redir.ini_stdout thrd_api.start() - # Announce the actual bound port on real stdout (before redirection) so the - # parent connects only once we are listening. + # Announce the bound port on real stdout (before redirection) so the parent connects. port = thrd_api.wait_bound(args.timeout) if port is None: print("py_func: failed to bind a listening port", file=sys.stderr, flush=True) diff --git a/src/testium/runtime/jrpc.py b/src/testium/runtime/jrpc.py index c9b8edf..5acab31 100644 --- a/src/testium/runtime/jrpc.py +++ b/src/testium/runtime/jrpc.py @@ -12,9 +12,7 @@ except: from runtime.tum_except import ETUMRuntimeError -# Startup handshake: the subprocess prints this line (followed by the actual -# bound port) on stdout once its server is listening; the parent reads it and -# connects. Avoids guessing the port and connecting before the server is ready. +# Startup handshake: subprocess prints this + its bound port on stdout once listening. RPC_PORT_SENTINEL = "__TESTIUM_RPC_PORT__=" """Lightweight JSON-RPC 2.0 helpers over TCP sockets. @@ -284,8 +282,7 @@ class JsonRpcBase(threading.Thread): self._req_handler = req_handler self._dbg_out = dbg_out self._event_ready = threading.Event() - # Event is set on success AND failure so wait_ready() never hangs; - # _connected carries the actual outcome. + # Set on success AND failure so wait_ready() never hangs; outcome in _connected. self._connected = False def handle_request(self, method, params): @@ -374,11 +371,7 @@ class JsonRpcSrv(JsonRpcBase): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: - # No SO_REUSEADDR: the OS picks a fresh ephemeral port (port 0), - # so there is no TIME_WAIT to override, and on Windows REUSEADDR - # would let another process hijack the port. - - # Bind (port may be 0 -> OS-assigned) then publish the actual port + # No SO_REUSEADDR: fresh ephemeral port; on Windows it enables hijacking. sock.bind((self._host, self._port)) # Listens incoming connections @@ -406,8 +399,7 @@ class JsonRpcSrv(JsonRpcBase): sleep(0.1) finally: - # Unblock wait_bound() even if bind/accept failed. - self._bound_evt.set() + self._bound_evt.set() # unblock wait_bound() even on failure if self._rpc is not None: self._rpc.stop() self._rpc.join() @@ -441,13 +433,10 @@ class JsonRpcClient(JsonRpcBase): except Exception as e: self.print_info(f"connection failed: {e}") finally: - # Settle wait_ready() whatever the outcome (_connected stays False - # on failure). - self._event_ready.set() + self._event_ready.set() # settle wait_ready() whatever the outcome def run_win(self): - # Server is already listening (port handshake), so connect succeeds on - # the first attempt; retry on refused/timeout until the deadline anyway. + # Server already listening (handshake); retry on refused/timeout until deadline. deadline = monotonic() + self._timeout sock = None try: