Move src/lib/ → src/testium/runtime/ (internal plumbing)
Move src/testium/libs/ → src/testium/api/ (public SDK for test scripts)
Move src/py_func/ → src/testium/py_func/ (Python subprocess)
Move src/lua_func/ → src/testium/lua_func/ (Lua subprocess data)
The package now ships as a single coherent unit instead of four sibling
top-level packages (testium, lib, py_func, lua_func) — pip install
gives a clean site-packages/testium/ with no namespace pollution; .lua
files travel with the wheel via package_data; the wheel installs
cleanly and `testium -b` runs end-to-end including py_func subprocesses
and entry-point exporter plugins.
Naming:
- runtime/ (internal, no API guarantees) clearer than lib/
- api/ (public SDK consumed as `import api.testium as tm`) clearer than libs/
Imports updated en masse: from lib. → from runtime. and from libs. →
from api., plus the importlib.import_module("libs.*") strings in
test_item_console.py and test_item_runtime_plot.py. Test/example
scripts (helper_lib.py, parallel.py, post_execution.py) and the
fake_exporter test suite migrated too.
paths.py: subproc_path() now returns testium_path() — both point at
the testium package directory since the subprocesses live inside.
pyproject.toml: removed exclude=["lua_func", "py_func"] (no longer
needed), added package-data for testium.lua_func/*.lua, removed the
license classifier (PEP 639 conflict with license expression).
Subprocess isolation contract: py_func/ and lua_func/ may only import
runtime/ and their own modules — never interpreter/, main_win/, api/,
or testium/. Enforced by test/validation/items/isolation/ which runs a
py_func that statically scans subprocess source files for forbidden
imports. The contract holds today; the test prevents future drift.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
from runtime.tum_except import (ETUMRuntimeError)
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
import json
|
|
|
|
class TestValue(Enum):
|
|
SUCCESS = 0
|
|
FAILURE = -1
|
|
NORUN = -2
|
|
|
|
def __str__(self):
|
|
r = ''
|
|
if self == self.SUCCESS:
|
|
r = 'PASS'
|
|
if self == self.FAILURE:
|
|
r = 'FAIL'
|
|
if self == self.NORUN:
|
|
r = 'SKIP'
|
|
return r
|
|
|
|
class TestResult:
|
|
def __init__(self, test=None, result=None, message=''):
|
|
|
|
self.test_name = ''
|
|
self.id = -1
|
|
self.test_id = -1
|
|
self.value = None # Optional : used to handle values to
|
|
# be evaluated if success of failure (function item for ex.)
|
|
|
|
if test is not None:
|
|
self.test_name = test.name()
|
|
self.test_id = test.id()
|
|
|
|
self.__reported_values = {}
|
|
self.set(result, message)
|
|
|
|
def set(self, result, message = ''):
|
|
self.test_result = result
|
|
if not (message == ''):
|
|
self.message = message
|
|
else:
|
|
self.message = str(self.test_result)
|
|
|
|
@property
|
|
def success(self):
|
|
return TestValue.SUCCESS == self.test_result
|
|
|
|
@property
|
|
def test_result(self):
|
|
return self._result
|
|
|
|
@test_result.setter
|
|
def test_result(self, result):
|
|
if (isinstance(result, TestValue)) or (result is None):
|
|
self._result = result
|
|
else:
|
|
raise(ETUMRuntimeError('Test result (for reporting) must be a "TestValue" class instance'))
|
|
|
|
@property
|
|
def reported(self):
|
|
return self.__reported_values
|
|
|
|
@reported.setter
|
|
def reported(self, value):
|
|
self.__reported_values.update(value)
|
|
|
|
def reportedJSON(self):
|
|
return json.dumps(self.__reported_values)
|
|
|
|
def sendStatus(self, status_queue):
|
|
date_str = str(datetime.now()).split('.')[0].split(' ')[1]
|
|
date_str = '[{}]'.format(date_str)
|
|
status = {'id':self.test_id,
|
|
'name':self.test_name,
|
|
'value':self.test_result.value,
|
|
'message':self.message,
|
|
'date':date_str}
|
|
if status_queue is not None:
|
|
status_queue.put(status)
|
|
else:
|
|
raise(ETUMRuntimeError("TestResult can't send status. status_queue is 'None'"))
|
|
|