many changes. Still not working lua server.

This commit is contained in:
2026-01-03 02:31:56 +01:00
parent b268918f40
commit fd1e602960
12 changed files with 228 additions and 65 deletions

View File

@@ -9,9 +9,21 @@ global_loop_param_num: [1, 2, 3]
# Plot parameters # Plot parameters
plot_log_path: /tmp/testium_plot/$(testrun_date)/$(testrun_time)/ plot_log_path: /tmp/testium_plot/$(testrun_date)/$(testrun_time)/
# python_path: $(home)/tmp/tum_venv/bin/python3 python_path_Windows: C:\Users\François\Applications\Python313\python.exe
python_path_Linux: $(home)/tmp/tum_venv/bin/python3
# lua_path_Windows: C:\Lua\5.1
# lua_path_Linux: /usr/bin/lua
LUA_PATH_Linux: /usr/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;/usr/share/lua/5.4/?/init.lua;/usr/local/lib/lua/5.4/?.lua;/usr/local/lib/lua/5.4/?/init.lua;/usr/lib/lua/5.4/?.lua;/usr/lib/lua/5.4/?/init.lua;./?.lua;./?/init.lua;/home/francois/.luarocks/share/lua/5.4/?.lua;/home/francois/.luarocks/share/lua/5.4/?/init.lua
LUA_CPATH_Linux: /usr/local/lib/lua/5.4/?.so;/usr/lib/lua/5.4/?.so;/usr/local/lib/lua/5.4/loadall.so;/usr/lib/lua/5.4/loadall.so;./?.so;/home/francois/.luarocks/lib/lua/5.4/?.so
PATH_Linux: ""
LUA_PATH_Windows: ;.\?.lua;C:\Lua\5.1\lua\?.lua;C:\Lua\5.1\lua\?\init.lua;C:\Lua\5.1\?.lua;C:\Lua\5.1\?\init.lua;C:\Lua\5.1\lua\?.luac
LUA_CPATH_Windows: .\?.dll;C:\Lua\5.1\?.dll;C:\Lua\5.1\loadall.dll;C:\Lua\5.1\clibs\?.dll;C:\Lua\5.1\clibs\loadall.dll;.\?51.dll;C:\Lua\5.1\?51.dll;C:\Lua\5.1\clibs\?51.dll
PATH_Windows: ""
# lua_path: /usr/bin/lua
lua_env: lua_env:
LUA_PATH: /usr/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;/usr/share/lua/5.4/?/init.lua;/usr/local/lib/lua/5.4/?.lua;/usr/local/lib/lua/5.4/?/init.lua;/usr/lib/lua/5.4/?.lua;/usr/lib/lua/5.4/?/init.lua;./?.lua;./?/init.lua;/home/francois/.luarocks/share/lua/5.4/?.lua;/home/francois/.luarocks/share/lua/5.4/?/init.lua PATH: $(PATH_$(os))
LUA_CPATH: /usr/local/lib/lua/5.4/?.so;/usr/lib/lua/5.4/?.so;/usr/local/lib/lua/5.4/loadall.so;/usr/lib/lua/5.4/loadall.so;./?.so;/home/francois/.luarocks/lib/lua/5.4/?.so LUA_PATH: $(LUA_PATH_$(os))
LUA_CPATH: $(LUA_CPATH_$(os))

View File

@@ -122,7 +122,9 @@ python_path = {tm.gd("python_path", "no python path defined")}"""
raise ETUMRuntimeError( raise ETUMRuntimeError(
f"""Impossible to start the external lua execution process. f"""Impossible to start the external lua execution process.
Is the lua path correct ? Is the lua path correct ?
lua_path = {tm.gd("lua_path", "no lua path defined")}""" lua_path = {tm.gd("lua_path", "no lua path defined")}
Are "lua-sockets" and "lua-cjson" installed ?
Is the lua environnment well defined in the "LUA_PATH" and "LUA_CPATH" variables ?"""
) )
test_set.execute() test_set.execute()
finally: finally:

View File

@@ -3,7 +3,7 @@ import os
import importlib import importlib
import traceback import traceback
from libs import testium as tm import libs.testium as tm
from interpreter.utils.tum_except import ETUMSyntaxError from interpreter.utils.tum_except import ETUMSyntaxError
from interpreter.utils.stdout_redirect import stdio_redir from interpreter.utils.stdout_redirect import stdio_redir
from interpreter.test_items.test_item import test_run from interpreter.test_items.test_item import test_run
@@ -58,7 +58,7 @@ class TestItemConsoleOpen(TestItemConsoleAction):
telnet_port = self._prms.getParam("telnet_port", default=69) telnet_port = self._prms.getParam("telnet_port", default=69)
elif self._protocol == "ssh": elif self._protocol == "ssh":
if sys.platform.startswith("win"): if tm.OS() == "Windows":
self.result.set( self.result.set(
TestValue.FAILURE, "SSH protocol not supported on Windows" TestValue.FAILURE, "SSH protocol not supported on Windows"
) )
@@ -112,7 +112,7 @@ class TestItemConsoleOpen(TestItemConsoleAction):
) )
elif self._protocol == "ssh": elif self._protocol == "ssh":
if sys.platform.startswith("win"): if tm.OS() == "Windows":
raise ETUMSyntaxError( raise ETUMSyntaxError(
f"The '{self.cmd()}' test item named '{self.name()}' does not support SSH protocol on Windows", f"The '{self.cmd()}' test item named '{self.name()}' does not support SSH protocol on Windows",
self.seqFilename() self.seqFilename()

View File

@@ -380,23 +380,14 @@ class JsonRpcClient(JsonRpcBase):
# TCP/IP socket creation # TCP/IP socket creation
try: try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(self._timeout)
# Link of the socket at the configured port # Link of the socket at the configured port
tslice = 0.2 try:
t = self._timeout sock.connect((self._host, self._port))
while True: except OSError:
try: raise ETUMRuntimeError(f"{self.name}: failed to connect")
sock.connect((self._host, self._port))
except OSError:
t -= tslice
if t >= 0:
sleep(tslice)
continue
else:
raise ETUMRuntimeError(f"{self.name}: failed to connect")
break
self.print_info("Connected to server") self.print_info("Connected to server")
self.connect(sock) self.connect(sock)
while self._rpc.running: while self._rpc.running:

View File

@@ -3,6 +3,7 @@ import shutil
import subprocess import subprocess
import socket import socket
import libs.testium as tm import libs.testium as tm
from interpreter.utils.paths import sys_lua_path
from interpreter.utils.tum_except import ETUMRuntimeError from interpreter.utils.tum_except import ETUMRuntimeError
from interpreter.utils.jrpc import JsonRpcClient from interpreter.utils.jrpc import JsonRpcClient
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
@@ -16,17 +17,6 @@ def lua_func_call_init(lua_path, request_handler):
return function_call_process return function_call_process
def lua_version(path: str):
result = subprocess.run(
[path, "-v"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
vers = ((result.stdout.split(" "))[1]).split(".")
return (vers[0], vers[1], vers[2])
def is_lua_interpreter(path: str, timeout=2) -> bool: def is_lua_interpreter(path: str, timeout=2) -> bool:
try: try:
result = subprocess.run( result = subprocess.run(
@@ -55,7 +45,11 @@ class LuaFuncExecEngine:
f"The passed executable is not a lua interpreter: '{lua_path}'" f"The passed executable is not a lua interpreter: '{lua_path}'"
) )
else: else:
lua_path = "/usr/bin/lua" lua_path = sys_lua_path()
if lua_path == "":
raise ETUMRuntimeError(
f"No valid lua interpreter found"
)
tm.setgd("lua_path", lua_path) tm.setgd("lua_path", lua_path)
self._lpath = lua_path self._lpath = lua_path
@@ -78,8 +72,9 @@ class LuaFuncExecEngine:
func_proc_path = os.path.join(tm.gd("testium_path"),"lua_func") func_proc_path = os.path.join(tm.gd("testium_path"),"lua_func")
lua_env = tm.gd("lua_env", {}) lua_env = tm.gd("lua_env", {})
tm.print_debug(f"lua_env : {lua_env}")
params = [self._lpath, "main.lua", "--host", "127.0.0.1", "--port", f"{self._port}"] params = [self._lpath, "main.lua", "--timeout", "10", "--host", "127.0.0.1", "--port", f"{self._port}"]
if tm.debug_enabled(): if tm.debug_enabled():
params.append("--verbose") params.append("--verbose")

View File

@@ -1,9 +1,10 @@
import os import os
import sys
import inspect import inspect
from pathlib import Path from pathlib import Path
import testium import testium
from interpreter.utils.params import expanse from interpreter.utils.params import expanse
import subprocess
import libs.testium as tm import libs.testium as tm
@@ -34,3 +35,156 @@ def abs_path_from_file(file):
abs_file_path = abs_file_path.resolve() abs_file_path = abs_file_path.resolve()
return abs_file_path return abs_file_path
def sys_encoding():
if tm.OS() == "Windows":
enc = 'oem'
else:
enc = 'utf-8'
return enc
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,
encoding=sys_encoding(),
timeout=10
)
data = result.stdout
except (FileNotFoundError, PermissionError, subprocess.TimeoutExpired) as e:
tm.print_debug(str(e))
data = ""
return eval(data)
def _lua_version(path: str):
cmd = f'"{path}" -v"'
try:
result = subprocess.run(
cmd,
shell=True,
capture_output=True,
text=True,
encoding=sys_encoding(),
timeout=10
)
# Under windows, the output is on stderr
data = result.stdout or result.stderr
except (FileNotFoundError, PermissionError, subprocess.TimeoutExpired) as e:
data = ""
try:
vers = ((data.split(" "))[1]).split(".")
except:
vers = (0, 0, 0)
return (vers[0], vers[1], vers[2])
def is_python3(python_path):
try:
v = _python_version(python_path)
if v[0] == 3:
res = True
except:
res = False
return res
def is_lua51(lua_path):
res = False
v = _lua_version(lua_path)
if (v[0] == "5") and (v[1] >= "1"):
res = True
return res
def _sys_app_path_win(app_name):
try:
result = subprocess.run(
f"where {app_name}",
shell=True,
capture_output=True,
text=True,
encoding="oem",
timeout=10
)
data = result.stdout
except (FileNotFoundError, PermissionError, subprocess.TimeoutExpired):
data = ""
sys_python_path = data.splitlines()
tm.print_debug("data = ", data)
for l in sys_python_path:
if f"{app_name}.exe" in l:
return l
return ""
def _sys_app_path_lin(app_name):
try:
result = subprocess.run(
f"which {app_name}",
shell=True,
capture_output=True,
text=True,
timeout=10
)
data = result.stdout
except (FileNotFoundError, PermissionError, subprocess.TimeoutExpired):
data = ""
sys_python_path = data.splitlines()
for l in sys_python_path:
if (
(f"{app_name}" in l)
and not l.startswith("which:")
):
return l
return ""
def sys_python_path():
sys_python_path = tm.gd("_sys_python_path", "")
if sys_python_path != "":
return sys_python_path
cur_os = tm.OS()
if cur_os == "Windows":
func = _sys_app_path_win
else:
func = _sys_app_path_lin
exe=["python3", "python"]
for e in exe:
sys_python_path = func(e)
if sys_python_path == "":
continue
if not is_python3(sys_python_path):
sys_python_path = ""
continue
tm.setgd("_sys_python_path", sys_python_path)
return sys_python_path
def sys_lua_path():
sys_lua_path = tm.gd("_sys_lua_path", "")
if sys_lua_path != "":
return sys_lua_path
cur_os = tm.OS()
if cur_os == "Windows":
func = _sys_app_path_win
else:
func = _sys_app_path_lin
sys_lua_path = func("lua")
if (sys_lua_path != "") and not is_lua51(sys_lua_path):
tm.print_debug(f"'{sys_lua_path}' not a lua 5.1 min.")
sys_lua_path = ""
tm.setgd("_sys_lua_path", sys_lua_path)
return sys_lua_path

View File

@@ -3,6 +3,7 @@ import shutil
import subprocess import subprocess
import socket import socket
import libs.testium as tm import libs.testium as tm
from interpreter.utils.paths import sys_python_path
from interpreter.utils.tum_except import ETUMRuntimeError from interpreter.utils.tum_except import ETUMRuntimeError
from interpreter.utils.jrpc import JsonRpcClient from interpreter.utils.jrpc import JsonRpcClient
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
@@ -16,16 +17,6 @@ def py_func_call_init(python_path, request_handler):
return function_call_process return function_call_process
def python_version(path: str):
result = subprocess.run(
[path, "-c", "import sys; print(sys.version_info[:3])"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
return eval(result.stdout.strip())
def is_python_interpreter(path: str, timeout=2) -> bool: def is_python_interpreter(path: str, timeout=2) -> bool:
try: try:
result = subprocess.run( result = subprocess.run(
@@ -56,7 +47,11 @@ class PyFuncExecEngine:
) )
else: else:
python_path = sys.executable python_path = sys_python_path()
if python_path == "":
raise ETUMRuntimeError(
f"No valid python interpreter found"
)
tm.setgd("python_path", python_path) tm.setgd("python_path", python_path)
self._ppath = python_path self._ppath = python_path

View File

@@ -56,6 +56,7 @@ class Console(object):
def __init__(self, name, echoOn=False, write_delay=0): def __init__(self, name, echoOn=False, write_delay=0):
self.stream = sys.stdout self.stream = sys.stdout
self.name = name self.name = name
self.encoding = "utf-8"
self.echo_on = echoOn self.echo_on = echoOn
self.write_delay = write_delay self.write_delay = write_delay
self.string_buffer = '['+str(datetime.now()).split('.')[0].split(' ')[1]+' '+self.name+']' self.string_buffer = '['+str(datetime.now()).split('.')[0].split(' ')[1]+' '+self.name+']'
@@ -117,9 +118,9 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
return True return True
def _compute_char(self, data): def _compute_char(self, data):
c = data.decode('utf-8', errors='replace') c = data.decode(self.encoding, errors='replace')
if not self._is_valid_character(c): # if not self._is_valid_character(c):
c = '' # c = ''
return c return c
def read_until(self, match, timeout=None, return_data=False, mute=False): def read_until(self, match, timeout=None, return_data=False, mute=False):
@@ -234,11 +235,11 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
print(('[>' + self.name + '] : ' + characters), end=ech) print(('[>' + self.name + '] : ' + characters), end=ech)
if self.write_delay != 0: if self.write_delay != 0:
for char in characters: for char in characters:
self.port.write(char.encode('utf-8')) self.port.write(char.encode(self.encoding))
sleep(self.write_delay) sleep(self.write_delay)
return len(characters) return len(characters)
else: else:
return self.port.write(characters.encode('utf-8')) return self.port.write(characters.encode(self.encoding))
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
@@ -296,7 +297,7 @@ class TelnetConsole(Console):
return self.read_until('\n', return_data=True)[1] return self.read_until('\n', return_data=True)[1]
def read_nowait(self, mute=False): def read_nowait(self, mute=False):
st = self.port.read_very_eager().decode('utf-8', errors='replace') st = self.port.read_very_eager().decode(self.encoding, errors='replace')
if not mute: if not mute:
date_str = str(datetime.now()).split('.')[0].split(' ')[1] date_str = str(datetime.now()).split('.')[0].split(' ')[1]
self.stream.write('[{} {}]'.format(date_str, self.name)+st) self.stream.write('[{} {}]'.format(date_str, self.name)+st)
@@ -455,13 +456,13 @@ class SerialConsole(Console):
if not self._thd.is_alive() and not self.stop.isSet(): if not self._thd.is_alive() and not self.stop.isSet():
raise RuntimeError( raise RuntimeError(
"Impossible to read the serial console, it may be already openned") "Impossible to read the serial console, it may be already openned")
st = self.rx_queue.getAll().decode('utf-8', errors='replace') st = self.rx_queue.getAll().decode(self.encoding, errors='replace')
if not mute: if not mute:
date_str = str(datetime.now()).split('.')[0].split(' ')[1] date_str = str(datetime.now()).split('.')[0].split(' ')[1]
self.stream.write('[{} {}]'.format(date_str, self.name)+st) self.stream.write('[{} {}]'.format(date_str, self.name)+st)
return st return st
st = self.port.read(self.port.inWaiting()).decode('utf-8', errors='replace') st = self.port.read(self.port.inWaiting()).decode(self.encoding, errors='replace')
if not mute: if not mute:
date_str = str(datetime.now()).split('.')[0].split(' ')[1] date_str = str(datetime.now()).split('.')[0].split(' ')[1]
self.stream.write('[{} {}]'.format(date_str, self.name)+st) self.stream.write('[{} {}]'.format(date_str, self.name)+st)
@@ -540,7 +541,7 @@ class LoggedConsole(Console):
self.rx_queue.put(data) self.rx_queue.put(data)
else: else:
continue continue
data = data.decode('utf-8', errors='replace') data = data.decode(self.encoding, errors='replace')
# if valid char, write into the file # if valid char, write into the file
if self._is_valid_character(data): if self._is_valid_character(data):
# replace '\r' by '\n' and '\r\n' by '\n' # replace '\r' by '\n' and '\r\n' by '\n'
@@ -583,7 +584,7 @@ class LoggedConsole(Console):
raise ConnectionAbortedError raise ConnectionAbortedError
chars = '' chars = ''
for _ in range(self.rx_queue.qsize()): for _ in range(self.rx_queue.qsize()):
chars = chars + self.rx_queue.get().decode('utf-8', errors='replace') chars = chars + self.rx_queue.get().decode(self.encoding, errors='replace')
if not mute: if not mute:
date_str = str(datetime.now()).split('.')[0].split(' ')[1] date_str = str(datetime.now()).split('.')[0].split(' ')[1]

View File

@@ -59,7 +59,7 @@ class RawTCPConsole(Console):
self.sock.settimeout(0) self.sock.settimeout(0)
self.stimeout = 0 self.stimeout = 0
s = self.sock.recv(4096) s = self.sock.recv(4096)
st = s.decode('utf-8', errors='replace') st = s.decode(self.encoding, errors='replace')
if not mute: if not mute:
date_str = str(datetime.now()).split('.')[0].split(' ')[1] date_str = str(datetime.now()).split('.')[0].split(' ')[1]
self.stream.write('[{} {}]'.format(date_str, self.name)+st) self.stream.write('[{} {}]'.format(date_str, self.name)+st)
@@ -69,5 +69,5 @@ class RawTCPConsole(Console):
if self.echo_on and not mute: if self.echo_on and not mute:
ech = '' if s.strip(' ').endswith('\n') else '\n' ech = '' if s.strip(' ').endswith('\n') else '\n'
print(('[>' + self.name + '] : ' + s), end=ech) print(('[>' + self.name + '] : ' + s), end=ech)
res = self.sock.sendall(s.encode('utf-8')) res = self.sock.sendall(s.encode(self.encoding))
return res return res

View File

@@ -1,5 +1,6 @@
from datetime import datetime from datetime import datetime
import sys import sys
import locale
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
import subprocess import subprocess
else: else:
@@ -16,6 +17,9 @@ class TermConsole(Console):
def __init__(self, name, project_path=None, cust_shell=None, echoOn=False, write_delay=0): def __init__(self, name, project_path=None, cust_shell=None, echoOn=False, write_delay=0):
Console.__init__(self, name, echoOn, write_delay) Console.__init__(self, name, echoOn, write_delay)
if sys.platform.startswith('win'):
self.encoding = 'cp850'
if not project_path: if not project_path:
self.ppath = os.getcwd() self.ppath = os.getcwd()
else: else:
@@ -111,7 +115,7 @@ class TermConsole(Console):
s += self.q.getAll() s += self.q.getAll()
st = s.decode('utf-8', errors='replace') st = s.decode(self.encoding, errors='replace')
ls = st.splitlines() ls = st.splitlines()
if (len(st) > 0) and (st[-1] != '\r') and (st[-1] !='\n'): if (len(st) > 0) and (st[-1] != '\r') and (st[-1] !='\n'):
@@ -129,7 +133,7 @@ class TermConsole(Console):
ech = '' if s.strip(' ').endswith('\n') else '\n' ech = '' if s.strip(' ').endswith('\n') else '\n'
print(('[>' + self.name + '] : ' + s), end=ech) print(('[>' + self.name + '] : ' + s), end=ech)
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
res = self.term.stdin.write(s.encode('utf-8')) res = self.term.stdin.write(s.encode(self.encoding))
else: else:
res = self.term.send(s) res = self.term.send(s)

View File

@@ -64,8 +64,17 @@ local handle = require("handle")
utils.verbose = config.verbose utils.verbose = config.verbose
-- Create the master socket -- Create the master socket
local server_sock = assert(socket.bind(config.host, config.port)) local server_sock = socket.tcp()
utils.log("listening on %s:%d", config.host, config.port)
local ok, err = server_sock:bind(config.host, config.port)
if not ok then
utils.log("error : %s", err)
os.exit(1)
end
server_sock:listen(1)
local ip, port = server_sock:getsockname()
utils.log("listening on %s:%d", ip, port)
server_sock:settimeout(config.timeout) -- Prevents hanging on dead connections server_sock:settimeout(config.timeout) -- Prevents hanging on dead connections

View File

@@ -56,7 +56,7 @@ class QTestTreeItem(QTreeWidgetItem):
self._display_pause = False self._display_pause = False
self.icon_pause = QIcon() self.icon_pause = QIcon()
self.icon_fake = QIcon() self.icon_fake = QIcon()
self.icon_pause.addPixmap(QPixmap(icon_prefix() + "/stop.png")) self.icon_pause.addPixmap(QPixmap(icon_prefix() + "/break.png"))
self.nfailure = 0 self.nfailure = 0
self._timestamp = -1 self._timestamp = -1
self._is_skipped = False self._is_skipped = False