14 Commits

Author SHA1 Message Date
91341b74e2 Adding a some TUM template used to validate the JSON schema 2026-05-24 15:28:54 +02:00
2a5e0bebd4 Adding many items to the JSON parser 2026-05-24 15:26:11 +02:00
8791a2e3f3 Adding some schema for validation and AI generation 2026-05-22 22:51:15 +02:00
6f832cd67b validation: cover nil/None return from lua_func/py_func
Two new steps per language: function returning nothing and function
returning explicit nil/None. Both tagged $(test)_PASS — they would
have failed before the lua nil fix (Lua side reported nil result as
error). Python side already worked but is covered for parity.
2026-05-17 18:13:03 +02:00
ff46886865 lua_func: nil return is not an error
_handle_request was using the 1st pcall return as the error
discriminator, so any Lua function returning nothing (e.g. long_wait
in the example) was reported as failed. Discriminate on the 2nd
return (err) instead, and encode nil result as cjson.null so the
returned_value field stays present in the JSON-RPC response.
2026-05-17 18:04:51 +02:00
50d183d191 removed lua param, useless. 2026-05-17 10:43:25 +02:00
2177715641 examples: long_wait py_func/lua_func to exercise Stop
Two extra steps in example_simple.tum that sleep for 10s, used to
verify that pressing Stop interrupts engaged blocking steps.
2026-05-17 10:42:49 +02:00
a728f561be Make Stop interrupt blocking steps promptly
console.read_until polls a should_stop callback in 0.2s chunks across
all protocols. py_func/lua_func override stop() to tear down the worker
and wake the parent RPC wait. json_rpc adapters honor should_stop too.
Engaged leaf steps now report FAILURE on stop (sleep no-dialog was
silently SUCCESS).
2026-05-17 10:42:40 +02:00
116e528a7d Simplify the Start Stop Pause process (v-and-v/testium#20) 2026-05-16 13:36:18 +02:00
cc744e17a1 Adding ensurepip verification for the build environnement (required by venv) 2026-05-16 13:29:37 +02:00
ab39b49558 now the release note and the manual are copied into dist with build_all 2026-05-13 21:24:35 +02:00
95275c4418 Merge branch 'main' of ssh://git.beafrancois.fr:8328/v-and-v/testium 2026-05-13 14:09:41 +02:00
dee8d4a682 generic design elements 2026-05-10 17:41:43 +02:00
e726d47547 generic design elements 2026-05-10 17:40:52 +02:00
44 changed files with 4317 additions and 162 deletions

View File

@@ -1,4 +1,4 @@
# Testium — Claude Context
# Testium — Design Context
## What is testium

View File

@@ -1,13 +1,17 @@
#!/bin/bash
# Build every distribution channel of testium, in order:
# 1. Wheel -> dist/testium-<v>-py3-none-any.whl (PEP 427 name)
# 2. PyInstaller binary -> dist/testium-<v>
# 3. Flatpak bundle -> dist/testium-<v>.flatpak
# 4. AppImage -> dist/Testium-<v>-x86_64.AppImage (original name)
# 1. Manual PDF -> dist/testium-manual-<v>.pdf
# 2. Wheel -> dist/testium-<v>-py3-none-any.whl (PEP 427 name)
# 3. PyInstaller binary -> dist/testium-<v>
# 4. Flatpak bundle -> dist/testium-<v>.flatpak
# 5. AppImage -> dist/Testium-<v>-x86_64.AppImage (original name)
# release_note.txt is copied to dist/ up front (with a warning if it has no
# entry for the current version).
#
# All artifacts are collected (copied) under <repo>/dist/. Original outputs in
# src/dist/, package/*/dist/ are left in place. The wheel and AppImage keep
# their original names (which already contain the version); pyinstaller and
# flatpak are renamed to a normalized testium-<version>(.suff) form.
# src/dist/, package/*/dist/, doc/manual/ are left in place. Wheel and AppImage
# keep their original names (which already contain the version); manual,
# pyinstaller and flatpak are renamed to testium(-manual)-<version>(.suff).
#
# Re-uses scripts/build_env.sh and scripts/set_env.sh — the same pair invoked
# by run.sh — so the venv at test/tmp/.venv stays the single source of Python
@@ -22,6 +26,15 @@ VERSION=$(cat "$SCRIPT_DIR/src/VERSION")
DIST_DIR="$SCRIPT_DIR/dist"
mkdir -p "$DIST_DIR"
# Release note: copy it to dist/ and warn (but don't fail) if it has no entry
# for the current version.
RELEASE_NOTE_SRC="$SCRIPT_DIR/release_note.txt"
RELEASE_NOTE="$DIST_DIR/release_note.txt"
cp -f "$RELEASE_NOTE_SRC" "$RELEASE_NOTE"
if ! grep -qE "^version $VERSION([^.0-9]|$)" "$RELEASE_NOTE_SRC"; then
echo "WARNING: release_note.txt has no entry for version $VERSION." >&2
fi
export PY_VENV_NAME=".venv"
export PY_VENV_DIR="$SCRIPT_DIR/test/tmp/$PY_VENV_NAME"
export REQ_PATH="$SCRIPT_DIR/src/requirements.txt"
@@ -39,8 +52,15 @@ step() {
echo "================================================================"
}
# 1. Wheel — PEP 427 name kept (already contains version)
step "1/4 Wheel (version $VERSION)"
# 1. Manual PDF
step "1/5 Manual PDF (version $VERSION)"
bash "$SCRIPT_DIR/doc/manual/sphinx/build_doc.sh"
MANUAL_SRC="$SCRIPT_DIR/doc/manual/testium_manual.pdf"
MANUAL="$DIST_DIR/testium-manual-${VERSION}.pdf"
cp -f "$MANUAL_SRC" "$MANUAL"
# 2. Wheel — PEP 427 name kept (already contains version)
step "2/5 Wheel (version $VERSION)"
(
cd "$SCRIPT_DIR/src"
rm -rf dist build *.egg-info
@@ -50,15 +70,15 @@ WHEEL_SRC=$(ls -1t "$SCRIPT_DIR/src/dist"/*.whl | head -1)
WHEEL="$DIST_DIR/$(basename "$WHEEL_SRC")"
cp -f "$WHEEL_SRC" "$WHEEL"
# 2. PyInstaller binary
step "2/4 PyInstaller binary (version $VERSION)"
# 3. PyInstaller binary
step "3/5 PyInstaller binary (version $VERSION)"
bash "$SCRIPT_DIR/package/pyinstaller/build.sh"
PYI_SRC="$SCRIPT_DIR/package/pyinstaller/dist/testium"
PYI_BIN="$DIST_DIR/testium-${VERSION}"
cp -f "$PYI_SRC" "$PYI_BIN"
# 3. Flatpak bundle
step "3/4 Flatpak bundle (version $VERSION)"
# 4. Flatpak bundle
step "4/5 Flatpak bundle (version $VERSION)"
(
cd "$SCRIPT_DIR/package/flatpak"
bash build.sh
@@ -67,8 +87,8 @@ FLATPAK_SRC="$SCRIPT_DIR/package/flatpak/testium.flatpak"
FLATPAK_BUNDLE="$DIST_DIR/testium-${VERSION}.flatpak"
cp -f "$FLATPAK_SRC" "$FLATPAK_BUNDLE"
# 4. AppImage
step "4/4 AppImage (version $VERSION)"
# 5. AppImage
step "5/5 AppImage (version $VERSION)"
(
cd "$SCRIPT_DIR/package/appimage"
bash build.sh
@@ -79,7 +99,9 @@ cp -f "$APPIMAGE_SRC" "$APPIMAGE"
chmod +x "$APPIMAGE"
step "All packages built"
printf " wheel : %s\n" "$WHEEL"
printf " pyinstaller : %s\n" "$PYI_BIN"
printf " flatpak : %s\n" "$FLATPAK_BUNDLE"
printf " appimage : %s\n" "$APPIMAGE"
printf " manual : %s\n" "$MANUAL"
printf " wheel : %s\n" "$WHEEL"
printf " pyinstaller : %s\n" "$PYI_BIN"
printf " flatpak : %s\n" "$FLATPAK_BUNDLE"
printf " appimage : %s\n" "$APPIMAGE"
printf " release_note : %s\n" "$RELEASE_NOTE"

View File

@@ -20,6 +20,22 @@ main:
param:
- 123
- py_func:
name: python long wait
doc: The purpose of this step is to try the tasks "stop" interruption
file: utils.py
func_name: long_wait
param:
- 10
- lua_func:
name: lua long wait
doc: The purpose of this step is to try the tasks "stop" interruption
file: lua_func.lua
func_name: long_wait
param:
- 10
- sleep:
name: sleep item
dialog: true

View File

@@ -1,4 +1,5 @@
tm = require("tm")
socket = require("socket")
local module = {}
@@ -7,4 +8,8 @@ function module.func_to_be_executed(param)
return param
end
function module.long_wait(sec)
socket.sleep(sec)
end
return module

View File

@@ -17,18 +17,3 @@ plot_log_path: /tmp/testium_plot/$(testrun_date)/$(testrun_time)/
python_path_Windows: C:\Users\François\Applications\Python313\python.exe
python_path_Linux: $(home)/tmp/tum_venv/bin/python3
# lua_bin_Windows: C:\Lua\5.1
# lua_bin_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_env:
PATH: $(PATH_$(os))
LUA_PATH: $(LUA_PATH_$(os))
LUA_CPATH: $(LUA_CPATH_$(os))

View File

@@ -1,3 +1,5 @@
from time import sleep
def dummy_exit(useless1, useless2):
return True
@@ -10,4 +12,7 @@ def funcToBeExecuted (bla):
def funcToBeExecuted2 (bla):
print(bla)
return blo
return blo
def long_wait (sec):
sleep(sec)

Binary file not shown.

73
schema/test.tum Normal file
View File

@@ -0,0 +1,73 @@
config_file:
- premier
- saluT
main:
name: Main file
steps:
- group:
name: Test
doc: Une peitite documentation
no_fail: true
steps:
- let:
values:
- my_var: <| ${salut} |>
- check:
values:
- <| ${salut} |>
- dialog_message:
question: c'est quoi?
- lua_func:
file: c'est quoi?
func_name: c'est quoi?
- console:
console_name: cons_1
steps:
- open:
protocol: telnet
terminal_path: ijfeifj
- read_until : {expected: "tutu", timeout: -4.5, mute: true}
- write: something
- writeln: tutu
- close :
- json_rpc:
name: JSONRPC console Query
doc: JSONRPC console Query not waiting (only send)
console:
name : jsonrpc_server
prompt: "@@>"
timeout: 1
version: "2.0"
steps:
- query:
method: echo
params:
- Hello world
- [0, 1, 2, 3]
id: 3095372
no_wait: true
- json_rpc:
name: JSONRPC console Reception
doc: JSONRPC console reception of the previous request
console: {name : jsonrpc_server}
timeout: 1
steps:
- receive:
id: 3095372
timeout: 0.5
report:
enabled: true
log_stored: true
export:
junit:
path: $(validation_report_path)
file_name: $(validation_report_file).junit
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)

View File

@@ -0,0 +1,96 @@
config_file:
- param.yaml
- items/check/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: check test constants
values:
- test: check
- test_path: items/$(test)
- group:
name: check test
steps:
- sequence:
steps:
- py_func:
file: $(test_path)$(psep)check.py
func_name: echo
key: $(test)_PASS
name: Dummy_int
param:
- 2
- py_func:
file: $(test_path)$(psep)check.py
func_name: echo
key: $(test)_PASS
name: Dummy_str
param:
- my taylor is rich
- check:
key: $(test)_PASS
name: Check condition on existing variable (PASS)
values:
- <| $(pfn_Dummy_int) > 1 |>
- check:
key: $(test)_FAIL
name: Check condition on existing variable (FAIL)
values:
- <| "tailor" in "$(pfn_Dummy_str)" |>
filename: /home/renish/workspace/testium/code/test/validation/items/check/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,453 @@
config_file:
- param.yaml
- items/common/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: common test constants
values:
test: common
test_path: items/$(test)
- group:
name: common test
steps:
- sequence:
steps:
- group:
name: Results
steps:
- sequence:
steps:
- group:
name: Expected Result
steps:
- py_func:
expected_result: true
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Return True expect True
param:
- true
- py_func:
expected_result: false
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_FAIL
name: Return True expect False (must
fail)
param:
- true
- py_func:
expected_result: None
file: $(test_path)$(psep)results$(psep)results.py
func_name: return_none
key: $(test)_PASS
name: Return None expect None
- py_func:
expected_result: PASS
file: $(test_path)$(psep)results$(psep)results.py
func_name: return_none
key: $(test)_PASS
name: Return None expect PASS
- py_func:
expected_result: 14
file: $(test_path)$(psep)results$(psep)results.py
func_name: return_none
key: $(test)_FAIL
name: Return None expect 14 (must fail)
- group:
name: Expected Result Last test result
steps:
- py_func:
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: result is 28
param:
- 28
- py_func:
expected_result: $(last_step_result)
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: check that the last test result
is 28
param:
- 28
- group:
name: Expected result Failure raised issue
steps:
- py_func:
file: $(test_path)$(psep)results$(psep)results.py
func_name: raise_issue
key: $(test)_FAIL
name: Raise an issue (must fail)
param:
- $(str_example)
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)results$(psep)results.py
func_name: raise_issue
key: $(test)_PASS
name: Raise an issue and expected the
test to be FAIL
param:
- $(str_example)
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_FAIL
name: Return a String expect a FAILURE
(must fail)
param:
- $(str_example)
- group:
name: process result
steps:
- py_func:
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Process result equal String
param:
- $(str_example)
process_result: '''$(str_example)'' ==
''$(result)'''
- py_func:
expected_result: true
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_FAIL
name: Process result string in the result
(must fail)
param:
- $(str_example)
process_result: '''44'' in ''$(result)'''
- py_func:
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Save the result in a global variable
param:
- 44
store_result: process_result_value
- py_func:
expected_result: $(process_result_value)
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Check the saved global variable
param:
- 44
- py_func:
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: store_result with process_result
param:
- $(str_example)
process_result: '''$(result)''.upper()'
store_result: upper_str_example
- py_func:
expected_result: $(upper_str_example)
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Check store_result with process_result
param:
- $(str_example)
process_result: '''$(result)''.upper()'
- let:
key: $(test)_PASS
name: "store_result on let item (None\
\ value \u2192 stores PASS)"
store_result: let_store_result
values:
- dummy: 0
- py_func:
expected_result: $(let_store_result)
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Check store_result on let stores
PASS
param:
- PASS
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)results$(psep)results.py
func_name: return_none
key: $(test)_FAIL
name: "store_result on failing test (None\
\ value \u2192 stores FAIL)"
store_result: none_fail_store_result
- py_func:
expected_result: $(none_fail_store_result)
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Check store_result on failing test
stores FAIL
param:
- FAIL
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)results$(psep)results.py
func_name: return_none
key: $(test)_PASS
name: "store_result with no_fail (None\
\ value \u2192 stores real FAIL, not\
\ forced PASS)"
no_fail: true
store_result: none_nofail_store_result
- py_func:
expected_result: $(none_nofail_store_result)
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Check store_result with no_fail
stores real FAIL
param:
- FAIL
- py_func:
file: $(test_path)$(psep)results$(psep)results.py
func_name: return_none
key: $(test)_FAIL
name: Process result when result is None
(must fail)
process_result: $(result) is None
- group:
name: no_fail result
steps:
- py_func:
expected_result: false
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Return True expect False but no_fail=True
no_fail: true
param:
- true
- py_func:
expected_result: false
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_FAIL
name: Return True expect False but no_fail=False
(must fail)
no_fail: false
param:
- true
- py_func:
expected_result: false
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_PASS
name: Return True expect False but no_fail
expansed
no_fail: <| bool(0) == False |>
param:
- true
- py_func:
expected_result: false
file: $(test_path)$(psep)results$(psep)results.py
func_name: echo
key: $(test)_FAIL
name: Return True expect False but no_fail
expansed (must fail)
no_fail: <| bool(1) == False |>
param:
- true
filename: /home/renish/workspace/testium/code/test/validation/items/common/results/test.tum
- group:
name: Conditional
steps:
- sequence:
steps:
- loop:
doc: This loop illustrate the way to exit on
a condition.
exit_condition:
value: <| $(pfn_Echo function) > 3 |>
key: $(test)_PASS
name: Infine loop with conditional exit
steps:
- sleep:
name: small wait
timeout: 0.2
- py_func:
file: $(test_path)$(psep)conditional$(psep)conditional.py
func_name: echo
key: $(test)_PASS
name: Echo function
param:
- $(loop_param)
stop_on_failure: false
- let:
key: $(test)_PASS
name: let
values:
- conditional_exec: <| random.randint(1, 2) |>
- console:
condition: <| $(conditional_exec) == 1 |>
console_name: consname
doc: Opening the console
key: $(test)_PASS
name: Console creation
steps:
- open:
protocol: terminal
terminal_path: $(test_directory)
- writeln: echo "terminal loaded"
- console:
condition: <| $(conditional_exec) == 1 |>
console_name: consname
key: $(test)_PASS
name: Console read_until with timeout
steps:
- read_until:
expected: terminal loaded
timeout: 5
- console:
condition: <| $(conditional_exec) == 1 |>
console_name: consname
key: $(test)_PASS
name: Console write
steps:
- writeln: echo 0
- sleep:
condition: <| $(conditional_exec) == 1 |>
name: sleep item
timeout: 1
- console:
condition: <| $(conditional_exec) == 1 |>
console_name: consname
key: $(test)_PASS
name: Console read_until immediate
steps:
- read_until:
expected: '0'
timeout: 0
- console:
condition: <| $(conditional_exec) == 1 |>
console_name: consname
key: $(test)_PASS
name: Console read_until immediate (2)
steps:
- read_until:
expected: $(terminal_prompt)
timeout: 0
- console:
condition: <| $(conditional_exec) == 1 |>
console_name: consname
key: $(test)_PASS
name: Console closure
steps:
- close: consname
- sleep:
condition: <| $(conditional_exec) == 2 |>
name: sleep item
timeout: 1
filename: /home/renish/workspace/testium/code/test/validation/items/common/conditional/test.tum
- group:
name: Various syntax robustness
steps:
- sequence:
steps:
- sleep:
key: $(test)_PASS
timeout: 0.2
- sleep:
key: $(test)_PASS
name: null
timeout: 0.2
- sleep:
doc: null
key: $(test)_PASS
name: Empty "doc:" declared (must PASS)
timeout: 0.2
filename: /home/renish/workspace/testium/code/test/validation/items/common/syntax_robustness/test.tum
- group:
name: Helper lib functions
steps:
- py_func:
file: $(test_path)$(psep)helper_lib.py
func_name: check_os
key: $(test)_PASS
name: OS
param:
- $(os)
- py_func:
file: $(test_path)$(psep)helper_lib.py
func_name: check_get_main_dir
key: $(test)_PASS
name: get_main_dir
- py_func:
file: $(test_path)$(psep)helper_lib.py
func_name: check_timestamp_as_sec_conversion
key: $(test)_PASS
name: timestamp_as_sec conversion
- py_func:
file: $(test_path)$(psep)helper_lib.py
func_name: check_timestamp
key: $(test)_PASS
name: timestamp and timestamp_as_sec
filename: /home/renish/workspace/testium/code/test/validation/items/common/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,164 @@
config_file:
- param.yaml
- items/console/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: console test constants
values:
- test: console
- test_path: items/$(test)
- group:
name: console test
steps:
- sequence:
steps:
- console:
console_name: term
doc: Opening the console
key: $(test)_PASS
name: Console creation
steps:
- open:
protocol: terminal
terminal_path: $(test_directory)
- writeln: echo "endOfOpen"
- console:
console_name: term
key: $(test)_PASS
name: Console read_until with timeout
steps:
- read_until:
expected: endOfOpen
timeout: 5
- console:
console_name: term
key: $(test)_PASS
name: Console write
steps:
- writeln: echo 0
- sleep:
name: sleep item
timeout: 1
- console:
console_name: term
key: $(test)_PASS
name: Console read_until immediate
steps:
- read_until:
expected: '0'
timeout: 0
- console:
console_name: term
key: $(test)_PASS
name: Console write
steps:
- writeln: echo "HelloConsole"
- console:
console_name: term
key: $(test)_FAIL
name: Console read_until fail
steps:
- read_until:
expected: Something never prints
timeout: 1
- console:
console_name: term
key: $(test)_PASS
name: Console write
steps:
- writeln: echo "HelloConsole"
- console:
console_name: term
key: $(test)_PASS
name: Console read_until no_fail
steps:
- read_until:
expected: Something never prints
no_fail: true
timeout: 1
- console:
console_name: term
key: $(test)_PASS
name: Console read_until muted
steps:
- writeln: echo "HelloConsole"
- read_until:
expected: HelloConsole
mute: true
timeout: 1
- console:
console_name: term
key: $(test)_PASS
name: Console read_until muted
steps:
- writeln: echo "HelloConsole is PASS" && echo "endOfCmd"
- read_until:
expected: endOfCmd
process_result: '''Hello'' in r''''''$(result)''''''
and ''PASS'' in r''''''$(result)'''''' '
timeout: 1
- console:
console_name: term
execute_on_stop: true
key: $(test)_PASS
name: Console closure
steps:
- close: term
filename: /home/renish/workspace/testium/code/test/validation/items/console/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,106 @@
config_file:
- param.yaml
- items/cycle/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
terminal_prompt: $(linux_prompt)
psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: cycle test constants
values:
- test: cycle
- test_path: items/$(test)
- group:
name: cycle test
steps:
- sequence:
steps:
- loop:
iterator: 10
key: $(test)_PASS
name: Cycle number of loops
steps:
- py_func:
file: $(test_path)$(psep)cycle.py
func_name: donothing
name: do nothing
- loop:
iterator:
- 12
- 20
- 30
key: $(test)_PASS
name: Cycle iterating on list
steps:
- py_func:
file: $(test_path)$(psep)cycle.py
func_name: checkloopparam
name: check loop param
param:
- $(loop_param)
- loop:
exit_condition:
file: $(test_path)$(psep)cycle.py
func_name: exitcondition
key: $(test)_PASS
name: Infinite loop with exit condition
steps:
- py_func:
file: $(test_path)$(psep)cycle.py
func_name: donothing
name: do nothing
filename: /home/renish/workspace/testium/code/test/validation/items/cycle/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,135 @@
config_file:
- param.yaml
- items/dialogs/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: dialogs test constants
values:
test: dialogs
test_path: items/$(test)
- group:
name: dialogs test
steps:
- sequence:
steps:
- dialog_image:
auto_result: ok
condition: $(validation_dialogs)
filename: $(test_path)$(psep)IMG_20140213_171455.jpg
key: $(test)_PASS
name: dialog image PASS
question: click ok if you see the image
- dialog_image:
auto_result: cancel
condition: $(validation_dialogs)
filename: $(test_path)$(psep)IMG_20140213_171455.jpg
key: $(test)_FAIL
name: dialog image FAIL
question: click cancel
- dialog_references:
auto_result: ok
condition: $(validation_dialogs)
key: $(test)_PASS
name: dialog_reference PASS
question: click ok
- dialog_references:
auto_result: cancel
condition: $(validation_dialogs)
key: $(test)_FAIL
name: dialog_reference FAIL
question: click cancel
- dialog_value:
auto_result: ok
auto_value: '123'
condition: $(validation_dialogs)
key: $(test)_PASS
name: dialog_value PASS
question: enter 123 and click ok
- dialog_value:
auto_result: ok
condition: $(validation_dialogs)
key: $(test)_FAIL
name: dialog_value empty FAIL
question: enter nothing and click ok
- dialog_value:
auto_result: cancel
condition: $(validation_dialogs)
key: $(test)_FAIL
name: dialog_value canceled FAIL
question: enter nothing and click cancel
- dialog_message:
auto_result: ok
condition: $(validation_dialogs)
key: $(test)_PASS
name: dialog_message PASS
question: click ok
- dialog_question:
auto_result: 'yes'
condition: $(validation_dialogs)
key: $(test)_PASS
name: dialog_question PASS
question: click yes
- dialog_question:
auto_result: 'no'
condition: $(validation_dialogs)
key: $(test)_FAIL
name: dialog_question FAIL
question: click no
filename: /home/renish/workspace/testium/code/test/validation/items/dialogs/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,130 @@
config_file:
- param.yaml
- items/expanse/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: expanse test constants
values:
test: expanse
test_path: items/$(test)
- group:
name: expanse test
steps:
- sequence:
steps:
- check:
key: $(test)_PASS
name: Check variables expansion is correct (PASS)
values:
- <| $(expanse_index) == 1 |>
- <| $(expanse_table)[$(expanse_index)] == 9012 |>
- <| $(expanse_eval) == True |>
- let:
key: $(test)_PASS
name: Dynamic variables expansion
values:
- expanse_select: <|"$(expanse_select)".replace("o", "a")|>
- expanse_index: $(expanse_index_$(expanse_select))
- expanse_table: $(expanse_table_$(expanse_select))
- expanse_eval: <|$(expanse_index) == 1|>
- check:
key: $(test)_PASS
name: Check variables expansion is correct (PASS)
values:
- <| $(expanse_index) == 0 |>
- <| $(expanse_table)[$(expanse_index)] == "abcd" |>
- <| $(expanse_eval) == False |>
- let:
key: $(test)_PASS
name: Complex variables expansion
values:
- var1: expanse
- var2: var
- var3: bla
- var4: blo
- expanse_var_bla: 3
- expanse_blo_var: 5
- expanse_complex: <|<|$(expanse_$(var2)_$(var3))*6|>
+ <|4*$($(var1)_$(var4)_$(var2))|>|>
- check:
key: $(test)_PASS
name: Check complex variables expansion is correct (PASS)
values:
- <| $(expanse_complex) == 38 |>
- let:
key: $(test)_PASS
name: Variables expansion in object
values:
- expanse_key: b
- expanse_var: 3
- expanse_var_2: 6
- expanse_object:
- $(expanse_key): <|2**3|>
a: $(expanse_var_2)
- <|"bla".replace("a", "o")|>:
- <|$(expanse_var)*$(expanse_var_2)|>
- 25
- check:
key: $(test)_PASS
name: Check complex variables expansion is correct (PASS)
values:
- '<| $(expanse_object) == [{"a": 6, "b": 8}, {"blo": [18,
25]}] |>'
filename: /home/renish/workspace/testium/code/test/validation/items/expanse/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,82 @@
config_file:
- param.yaml
- items/git/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: git test constants
values:
test: git
test_path: items/$(test)
- group:
name: git test
steps:
- sequence:
steps:
- git:
key: $(test)_PASS
name: Testium repo
repo: $(test_directory)
- git:
key: $(test)_PASS
name: Testium repo
repo:
- $(test_directory)
- $(test_directory)
filename: /home/renish/workspace/testium/code/test/validation/items/git/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,129 @@
config_file:
- param.yaml
- items/include/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: include test constants
values:
test: include
test_path: items/$(test)
- group:
name: include test
steps:
- sequence:
steps:
- sequence:
steps:
- py_func:
file: $(test_path)$(psep)include.py
func_name: ValidationTest
key: $(test)_PASS
name: My first include test
param:
- $(test parameter)
filename: /home/renish/workspace/testium/code/test/validation/items/include/inc
no template/my first include.tum
- sequence:
steps:
- py_func:
file: $(test_path)$(psep)include.py
func_name: ValidationTest
key: $(test)_PASS
name: My first include test
param:
- $(test parameter)
filename: /home/renish/workspace/testium/code/test/validation/items/include/inc
no template/my first include.tum
- sequence:
steps:
- py_func:
file: $(test_path)$(psep)include.py
func_name: ValidationTest
key: $(test)_PASS
name: My second include test
param:
- My second include test parameter
filename: /home/renish/workspace/testium/code/test/validation/items/include/inc
with template/my second include.tum
- sequence:
steps:
- py_func:
file: $(test_path)$(psep)include.py
func_name: ValidationTest
key: $(test)_PASS
name: My second include test
param:
- My second include test parameter
filename: /home/renish/workspace/testium/code/test/validation/items/include/inc
with template/my second include.tum
- let:
name: Declare param for inclusion
values:
- inc: Dali
- Dali_inc: Dalida
- sequence:
steps:
- let:
name: Test param inclusion 1
values:
- inclusion: $($(inc)_inc)
filename: /home/renish/workspace/testium/code/test/validation/items/include/inc
with template/my_3d_include.tum
filename: /home/renish/workspace/testium/code/test/validation/items/include/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,80 @@
config_file:
- param.yaml
- items/isolation/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: isolation test constants
values:
test: isolation
test_path: items/$(test)
- group:
name: isolation test
steps:
- sequence:
steps:
- py_func:
expected_result: true
file: $(test_path)$(psep)check_isolation.py
func_name: check_isolation
key: $(test)_PASS
name: py_func/lua_func do not depend on testium internals
param:
- $(testium_path)
filename: /home/renish/workspace/testium/code/test/validation/items/isolation/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,490 @@
config_file:
- param.yaml
- items/jsonrpc/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: jsonrpc test constants
values:
test: jsonrpc
test_path: items/$(test)
- group:
name: jsonrpc test
steps:
- sequence:
steps:
- console:
console_name: jrpces
doc: check if jrpc_echo_server.py is available
key: $(test)_PASS
name: json rpc echo server
steps:
- open:
protocol: terminal
- read_until:
expected: $(terminal_prompt)
no_fail: true
timeout: 1
- writeln: test -f /home/renish/workspace/testium/code/test/validation/items/jsonrpc/jrpc_echo_server.py
&& echo JRPC_OK
- read_until:
expected: JRPC_OK
no_fail: true
timeout: 2
- group:
condition: <| 'JRPC_OK' in r'''$(cn_json rpc echo server)''' |>
name: jsonrpc tests
steps:
- console:
console_name: jrpces
key: $(test)_PASS
name: Start the json rpc echo server
steps:
- writeln: python3 /home/renish/workspace/testium/code/test/validation/items/jsonrpc/jrpc_echo_server.py
-c /home/renish/workspace/testium/code/test/validation/items/jsonrpc/jrpces.ini
- read_until:
expected: ready
timeout: 5
- console:
console_name: jsonrpc_server
doc: Opening the RAW TCP console
key: $(test)_PASS
name: Open the raw tcp Console
skipped: $(skip_tcp)
steps:
- open:
protocol: rawtcp
tcp_host: localhost
tcp_port: 4321
- json_rpc:
console:
name: jsonrpc_server
key: $(test)_PASS
name: JSONRPC console Query waiting for reception
skipped: $(skip_tcp)
steps:
- query:
method: echo
params:
- Hello World
- a: 1
b: hello
timeout: 1
- json_rpc:
console:
name: jsonrpc_server
key: $(test)_PASS
name: JSONRPC console Query not waiting (only send)
skipped: $(skip_tcp)
steps:
- query:
id: 3095372
method: echo
no_wait: true
params:
- a: -1
b: olleh
- World Hello
timeout: 1
- sleep:
name: Small delay for the test
skipped: $(skip_tcp)
timeout: 1
- json_rpc:
console:
name: jsonrpc_server
key: $(test)_PASS
name: JSONRPC console Reception
skipped: $(skip_tcp)
steps:
- receive:
id: 3095372
timeout: 1
- console:
console_name: jsonrpc_server
doc: Opening the RAW TCP console
execute_on_stop: true
key: $(test)_PASS
name: Close the raw tcp console
skipped: $(skip_tcp)
steps:
- close: null
- json_rpc:
key: $(test)_PASS
name: JSONRPC UDP query waiting for reception
steps:
- open: null
- query:
method: echo
name: echo
params:
- Hello World
- a: 1
b: hello
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- json_rpc:
key: $(test)_FAIL
name: Failing JSONRPC UDP query waiting for reception
(returning an error)
steps:
- open: null
- query:
method: echo2
params:
- Hello World
- a: 1
b: hello
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- json_rpc:
key: $(test)_PASS
name: JSONRPC UDP query waiting for reception of
an expected error
steps:
- open: null
- query:
expected_result:
code: -32000
message: function not found
method: echo2
params:
- Hello World
- a: 1
b: hello
- close: null
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- json_rpc:
doc: 'Failing JSONRPC UDP query waiting for reception
and checking result
and timeout elapses (wrong udp port)
'
key: $(test)_FAIL
name: Failing UDP JSONRPC query timeout elapses (wrong
udp port)
steps:
- open: null
- query:
method: echo
params:
- Hello World
- a: 1
b: hello
timeout: 0.5
- close: null
timeout: 1
udp:
rcv_port: 48393
server: localhost
snd_port: 4326
- json_rpc:
key: $(test)_PASS
name: JSONRPC UDP query not waiting (only send)
steps:
- open: null
- query:
id: 3095372
method: echo
no_wait: true
params:
- a: -1
b: olleh
- World Hello
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- sleep:
name: Small delay for the test
timeout: 1
- json_rpc:
key: $(test)_PASS
name: JSONRPC UDP Reception
steps:
- receive:
id: 3095372
- close: null
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- json_rpc:
key: $(test)_PASS
name: JSONRPC UDP query not waiting (only send)
steps:
- open: null
- query:
id: 3095372
method: echo2
no_wait: true
params:
- a: -1
b: olleh
- World Hello
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- sleep:
name: Small delay for the test
timeout: 1
- json_rpc:
key: $(test)_FAIL
name: Failing JSONRPC UDP Reception (returning an
error)
steps:
- receive:
id: 3095372
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 8765
server: localhost
snd_port: 4323
- json_rpc:
doc: JSONRPC UDP query waiting for reception and
checking result
key: $(test)_PASS
name: UDP JSONRPC query waiting and checking
steps:
- open: null
- query:
expected_result:
- - Hello World
- a: 1
b: hello
- {}
method: echo
params:
- Hello World
- a: 1
b: hello
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 48393
server: localhost
snd_port: 4323
- json_rpc:
doc: JSONRPC UDP query waiting for reception and
checking result
key: $(test)_FAIL
name: Failing UDP JSONRPC query waiting and checking
steps:
- open: null
- query:
expected_result:
- []
- {}
method: echo
params:
- Hello World
- a: 1
b: hello
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 48393
server: localhost
snd_port: 4323
- json_rpc:
doc: JSONRPC UDP query not waiting, with the purpose
to check the result at reception
key: $(test)_PASS
name: UDP JSONRPC query not waiting (for checking)
steps:
- open: null
- query:
id: 3095372
method: echo
no_wait: true
params:
- a: -1
b: olleh
- World Hello
timeout: 1
udp:
rcv_port: 9876
server: localhost
snd_port: 4323
- sleep:
name: Small delay for the test
timeout: 1
- json_rpc:
doc: JSONRPC UDP Reception and checking result
key: $(test)_PASS
name: UDP JSONRPC reception checking
steps:
- receive:
expected_result:
- - a: -1
b: olleh
- World Hello
- {}
id: 3095372
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 9876
server: localhost
snd_port: 4323
- json_rpc:
doc: JSONRPC UDP Reception and checking result
key: $(test)_FAIL
name: Failing UDP JSONRPC reception checking
steps:
- receive:
expected_result:
- - a: -1
b: ollhe
- World Hello
- {}
id: 3095372
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 9876
server: localhost
snd_port: 4323
- json_rpc:
doc: 'JSONRPC UDP query waiting for reception and
checking result with
replacing $(result) and evaluating string.
'
key: $(test)_PASS
name: UDP JSONRPC query waiting and evaluating result
steps:
- open: null
- query:
expected_result: 1
method: echo
params:
- Hello World
- a: 1
b: hello
process_result: $(result)[0][1]['a']
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 48393
server: localhost
snd_port: 4323
- json_rpc:
doc: 'JSONRPC UDP query waiting for reception and
checking result with
replacing $(result) and evaluating string.
'
key: $(test)_FAIL
name: Failing UDP JSONRPC query waiting and evaluating
result
steps:
- open: null
- query:
expected_result: $(result)[0][1]['a'] == 0
method: echo
params:
- Hello World
- a: 1
b: hello
timeout: 1
- close: null
timeout: 1
udp:
rcv_port: 48393
server: localhost
snd_port: 4323
- console:
console_name: jrpces
doc: check if the jsonrpc echo server is installed
execute_on_stop: true
key: $(test)_PASS
name: Stop json rpc echo server
steps:
- close:
protocol: terminal
filename: /home/renish/workspace/testium/code/test/validation/items/jsonrpc/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

157
schema/test_schema/let.tum Normal file
View File

@@ -0,0 +1,157 @@
config_file:
- param.yaml
- items/let/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: let test constants
values:
- test: let
- test_path: items/$(test)
- group:
name: let test
steps:
- sequence:
steps:
- loop:
iterator: 10
key: $(test)_PASS
name: Cycle number of loops
steps:
- py_func:
file: $(test_path)$(psep)let.py
func_name: donothing
name: do nothing
- let:
name: Let it be
values:
- be: <| $(loop_param) == $(it) |>
- it: $(loop_param)
- loop:
iterator:
- 12
- 20
- 30
key: $(test)_PASS
name: Cycle iterating on list
steps:
- py_func:
file: $(test_path)$(psep)let.py
func_name: checkloopparam
name: check loop param
param:
- $(loop_param)
- let:
name: Let it be
values:
- it: $(loop_param)
- be: <| $(loop_param) == $(it) |>
- let:
key: $(test)_PASS
name: Get time
values:
- loop_t0: $(ts_start_Cycle iterating on list)
- loop_t1: $(ts_end_Cycle iterating on list)
- loop_duration: $(ts_duration_Cycle iterating on list)
- let:
key: $(test)_PASS
name: Get parameter file value
values:
- test_overwrite_me: <| $(overwrite_me) == True |>
- py_func:
file: $(test_path)$(psep)let.py
func_name: checkGlobalDic
name: Check global dic pass
param:
- test_overwrite_me
- true
- let:
key: $(test)_PASS
name: Overwrite parameter file value
values:
- overwrite_me: false
- py_func:
expected_result: $(overwrite_me) == False
file: $(test_path)$(psep)let.py
func_name: checkGlobalDic
key: $(test)_FAIL
name: Check global dic fail
param:
- overwrite_me
- true
- py_func:
expected_result: fail
file: $(test_path)$(psep)let.py
func_name: checkGlobalDic
key: $(test)_PASS
name: Check global dic fail
param:
- overwrite_me
- true
- let:
key: $(test)_PASS
name: Evaluate Overwriting parameter file value
values:
- test_overwrite_me: <| "$(overwrite_me)" == True |>
- check:
key: $(test)_PASS
name: Check Overwriting parameter file value
values:
- <| $(test_overwrite_me) == False |>
filename: /home/renish/workspace/testium/code/test/validation/items/let/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,297 @@
config_file:
- param.yaml
- items/lua_func/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: lua_func test constants
values:
test: lua_func
test_path: items/$(test)
- group:
name: lua_func test
steps:
- sequence:
steps:
- let:
name: lua_func test constants,
values:
lua_func test parameter: test parameter lua_func
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: assertparam
key: $(test)_FAIL
name: fail lua_func
param:
- false
- lua_func:
expected_result: FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: assertparam
key: $(test)_PASS
name: fail lua_func with expected result FAIL
param:
- false
- lua_func:
expected_result: FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: assertparam
key: $(test)_FAIL
name: pass lua_func with expected result FAIL
param:
- true
- lua_func:
expected_result: -1
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: expected -1
param:
- -1
- lua_func:
expected_result: 354848436 - 354848437
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: expected eval
param:
- -1
- lua_func:
expected_result: '[-1, ''a'', {''toto'': ''tata''}]'
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: expected table
param:
- - -1
- a
- toto: tata
- lua_func:
expected_result: $(lua_func test parameter)
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal
key: $(test)_PASS
name: global param lua_func
param:
- lua_func test parameter
- lua_func:
expected_result: ($(lua_data_to_be_returned))[0]
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
key: $(test)_PASS
name: global param lua_func 1
param:
- 1
- lua_func:
expected_result: ($(lua_data_to_be_returned))[1]
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
key: $(test)_PASS
name: global param lua_func 2
param:
- 2
- lua_func:
expected_result: ($(lua_data_to_be_returned))[2]
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
key: $(test)_PASS
name: global param lua_func 3
param:
- 3
- let:
key: $(test)_PASS
name: python2func
values:
- py: $(test_path)$(psep)lua_func.lua
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: should_not_be_called
name: skipped_checkglobal
param:
- $(test parameter)
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal
name: skipped true
param:
- $(test parameter)
skipped: true
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal
name: skipped 1
param:
- $(test parameter)
skipped: true
- group:
name: Function results check
steps:
- group:
name: Function result failure
steps:
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: int failure
param:
- -1
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: float failure
param:
- -1.3
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: String failure
param:
- FAIL
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: tuple_return
key: $(test)_PASS
name: Tuple int,str failure
param:
- -1
- Got a failure
- group:
name: Functions result success
steps:
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: int success
param:
- 0
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: float success
param:
- 0.3
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: echo
key: $(test)_PASS
name: String success
param:
- Something that is not only strictly FAIL
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: tuple_return
key: $(test)_PASS
name: Tuple int,str success
param:
- 0
- OK
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: test_delgd
key: $(test)_PASS
name: delgd test
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: return_nothing
key: $(test)_PASS
name: function returning nothing should succeed
- lua_func:
file: $(test_path)$(psep)lua_func.lua
func_name: return_explicit_nil
key: $(test)_PASS
name: function returning explicit nil should succeed
- group:
name: context_id tests
steps:
- lua_func:
context_id: lua_ctx_test
expected_result: hello lua
file: $(test_path)$(psep)lua_func.lua
func_name: set_context_value
key: $(test)_PASS
name: set context value
param:
- hello lua
- lua_func:
context_id: lua_ctx_test
expected_result: hello lua
file: $(test_path)$(psep)lua_func.lua
func_name: get_context_value
key: $(test)_PASS
name: get context value (same context_id)
- lua_func:
expected_result: hello lua
file: $(test_path)$(psep)lua_func.lua
func_name: get_context_value
key: $(test)_PASS
name: get context value (no context_id, from main
gd)
- lua_func:
context_id: lua_ctx_other
expected_result: hello lua
file: $(test_path)$(psep)lua_func.lua
func_name: get_context_value
key: $(test)_PASS
name: get context value (different context_id)
filename: /home/renish/workspace/testium/code/test/validation/items/lua_func/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,414 @@
config_file:
- param.yaml
- items/parallel/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: parallel test constants
values:
test: parallel
test_path: items/$(test)
- group:
name: parallel test
steps:
- sequence:
steps:
- parallel:
branches:
- name: Branch A
steps:
- let:
name: Set A done
values:
- branch_a_done: true
- name: Branch B
steps:
- let:
name: Set B done
values:
- branch_b_done: true
key: $(test)_PASS
name: Both branches pass
sync: all
- check:
key: $(test)_PASS
name: Both branches ran
values:
- <| $(branch_a_done) == True |>
- <| $(branch_b_done) == True |>
- parallel:
branches:
- name: Pass branch
steps:
- let:
name: Set pass flag
values:
- pass_branch_ran: true
- name: Fail branch
steps:
- py_func:
expected_result: fail
file: $(test_path)$(psep)parallel.py
func_name: sleep_func
name: Raise exception
param:
- 0
key: $(test)_PASS
name: One branch fails
no_fail: true
sync: all
- check:
key: $(test)_PASS
name: Pass branch still ran
values:
- <| $(pass_branch_ran) == True |>
- let:
name: Reset slow flag
values:
- slow_done: false
- parallel:
branches:
- name: Fast branch
steps:
- let:
name: Fast done
values:
- fast_done: true
- name: Slow branch
steps:
- py_func:
file: $(test_path)$(psep)parallel.py
func_name: sleep_func
name: Sleep 2s
param:
- 2
- let:
name: Slow done
values:
- slow_done: true
key: $(test)_PASS
name: sync any - first wins
sync: any
- check:
key: $(test)_PASS
name: Fast branch ran, slow branch was stopped
values:
- <| $(fast_done) == True |>
- <| $(slow_done) == False |>
- let:
name: Reset sync flag
values:
- sync_flag: ''
- waiter_ran: false
- parallel:
branches:
- name: Setter branch
steps:
- py_func:
file: $(test_path)$(psep)parallel.py
func_name: sleep_func
name: Sleep 0.3s then set flag
param:
- 0.3
- let:
name: Set sync flag
values:
- sync_flag: ready
- name: Waiter branch
steps:
- let:
name: Got flag
values:
- waiter_ran: true
wait_for:
condition: <| "$(sync_flag)" == "ready" |>
timeout: 10
key: $(test)_PASS
name: wait_for synchronization
sync: all
- check:
key: $(test)_PASS
name: Waiter branch ran after flag was set
values:
- <| $(waiter_ran) == True |>
- parallel:
branches:
- name: Sleep A
steps:
- sleep:
name: Sleep 1s A
timeout: 1
- name: Sleep B
steps:
- sleep:
name: Sleep 1s B
timeout: 1
key: $(test)_PASS
name: Timing test
sync: all
- let:
name: Capture parallel duration
values:
- parallel_duration: $(ts_duration_Timing test)
- check:
key: $(test)_PASS
name: Duration < 1.8s (would be 2s if sequential)
values:
- <| float("$(parallel_duration)") < 1.8 |>
- let:
name: Reset N flags
values:
- n_a: false
- n_b: false
- n_c: false
- n_d: false
- parallel:
branches:
- name: NA
steps:
- let:
name: set n_a
values:
- n_a: true
- name: NB
steps:
- let:
name: set n_b
values:
- n_b: true
- name: NC
steps:
- let:
name: set n_c
values:
- n_c: true
- name: ND
steps:
- let:
name: set n_d
values:
- n_d: true
key: $(test)_PASS
name: Four branches
sync: all
- check:
key: $(test)_PASS
name: Four branches all set their flag
values:
- <| $(n_a) == True |>
- <| $(n_b) == True |>
- <| $(n_c) == True |>
- <| $(n_d) == True |>
- let:
name: Reset nested flags
values:
- outer_x: false
- inner_x_1: false
- inner_x_2: false
- parallel:
branches:
- name: Outer X
steps:
- let:
name: set outer_x
values:
- outer_x: true
- parallel:
branches:
- name: Inner X1
steps:
- let:
name: set inner_x_1
values:
- inner_x_1: true
- name: Inner X2
steps:
- let:
name: set inner_x_2
values:
- inner_x_2: true
name: Inner parallel
sync: all
- name: Outer Y
steps:
- sleep:
name: brief sleep
timeout: 0
key: $(test)_PASS
name: Outer parallel
sync: all
- check:
key: $(test)_PASS
name: Nested parallel set all flags
values:
- <| $(outer_x) == True |>
- <| $(inner_x_1) == True |>
- <| $(inner_x_2) == True |>
- let:
name: Reset waiter timeout flag
values:
- waiter_timeout_ran: false
- parallel:
branches:
- name: Quick branch
steps:
- sleep:
name: brief sleep
timeout: 0
- name: Doomed waiter
steps:
- let:
name: should not run
values:
- waiter_timeout_ran: true
wait_for:
condition: <| "never" == "ready" |>
timeout: 1
key: $(test)_PASS
name: wait_for timeout
no_fail: true
sync: all
- check:
key: $(test)_PASS
name: Doomed waiter never ran its steps
values:
- <| $(waiter_timeout_ran) == False |>
- parallel:
branches:
- name: ok branch
steps:
- let:
name: noop
values:
- noop_var: 1
- name: broken branch
steps:
- py_func:
expected_result: fail
file: $(test_path)$(psep)parallel.py
func_name: sleep_func
name: Forced fail
param:
- 0
key: $(test)_FAIL
name: One branch really fails
sync: all
- let:
name: Reset branch condition flag
values:
- cond_branch_ran: false
- other_branch_ran: false
- parallel:
branches:
- condition: <| "always" == "false" |>
name: Skipped branch
steps:
- let:
name: should not run
values:
- cond_branch_ran: true
- name: Other branch
steps:
- let:
name: ran
values:
- other_branch_ran: true
key: $(test)_PASS
name: Condition-skipped branch
sync: all
- check:
key: $(test)_PASS
name: Skipped condition branch did not run
values:
- <| $(cond_branch_ran) == False |>
- <| $(other_branch_ran) == True |>
- let:
name: Reset loop counters
values:
- loop_count_a: 0
- loop_count_b: 0
- loop:
iterator: 3
name: Loop wrapping parallel
steps:
- parallel:
branches:
- name: LA
steps:
- let:
name: bump A
values:
- loop_count_a: <| int("$(loop_count_a)")
+ 1 |>
- name: LB
steps:
- let:
name: bump B
values:
- loop_count_b: <| int("$(loop_count_b)")
+ 1 |>
name: Per-iteration parallel
sync: all
- check:
key: $(test)_PASS
name: Both branches ran 3 times
values:
- <| int("$(loop_count_a)") == 3 |>
- <| int("$(loop_count_b)") == 3 |>
filename: /home/renish/workspace/testium/code/test/validation/items/parallel/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

137
schema/test_schema/plot.tum Normal file
View File

@@ -0,0 +1,137 @@
config_file:
- param.yaml
- items/plot/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: plot test constants
values:
test: plot
test_path: items/$(test)
- group:
name: plot test
steps:
- sequence:
steps:
- group:
condition: <| $(validation_dialogs) and not tm.text_mode()
|>
name: Plot test
steps:
- plot:
key: $(test)_PASS
name: Open the plot
plot_name: Mon Plot
steps:
- open:
log_path: $(validation_report_path)
- plot:
key: $(test)_PASS
name: Add periodic to the plot
plot_name: Mon Plot
steps:
- periodic:
eval: '{"periodic": $(result)}'
file: $(test_path)$(psep)plot.py
func_name: random_value
period: 1
- sleep:
dialog: true
name: sleep
timeout: 3
- loop:
iterator: 10
name: Add of other data in the plot
steps:
- plot:
key: $(test)_PASS
name: Add to the plot
plot_name: Mon Plot
steps:
- add:
value1: $(loop_index)
value2: $(loop_index)+2
- sleep:
name: sleep between values
timeout: 1
- py_func:
file: $(test_path)$(psep)plot.py
func_name: LastValues
key: $(test)_PASS
name: last plot values
param:
- Mon Plot
- plot:
execute_on_stop: true
key: $(test)_PASS
name: Export
plot_name: Mon Plot
steps:
- export: $(validation_report_path)/plot_export.pdf
- export: $(validation_report_path)/plot_export.csv
- plot:
execute_on_stop: true
key: $(test)_PASS
name: Close the plot
plot_name: Mon Plot
steps:
- close:
timeout: 2
wait_dialog_exit: true
filename: /home/renish/workspace/testium/code/test/validation/items/plot/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,326 @@
config_file:
- param.yaml
- items/py_func/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: py_func test constants
values:
test: py_func
test_path: items/$(test)
- group:
name: py_func test
steps:
- sequence:
steps:
- let:
name: py_func test constants,
values:
py_func test parameter: test parameter
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: assertparam
key: $(test)_PASS
name: pass py_func
param:
- true
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: assertparam
key: $(test)_FAIL
name: fail py_func
param:
- false
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)py_func.py
func_name: assertparam
key: $(test)_PASS
name: fail py_func with expected result "FAIL"
param:
- false
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)py_func.py
func_name: assertparam
key: $(test)_FAIL
name: pass py_func with expected result FAIL
param:
- true
- py_func:
expected_result: -1
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: expected -1
param:
- -1
- py_func:
expected_result: 354848436 - 354848437
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: expected eval
param:
- -1
- py_func:
expected_result: '[-1, ''a'', {''toto'': ''tata''}]'
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: expected table
param:
- - -1
- a
- toto: tata
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: checkglobal
key: $(test)_PASS
name: global param py_func
param:
- $(py_func test parameter)
- let:
key: $(test)_PASS
name: python2func
values:
- py: $(test_path)$(psep)py_func.py
- py_func:
expected_result: $(py_func test parameter)
file: $(py)
func_name: checkglobal2
key: $(test)_PASS
name: global param py_func 2
- py_func:
file: $(py)
func_name: checkglobal
key: $(test)_PASS
name: global param py_func
param:
- $(py_func test parameter)
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: should_not_be_called
name: skipped_checkglobal
param:
- $(py_func test parameter)
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: checkglobal
name: skipped true
param:
- $(py_func test parameter)
skipped: true
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: checkglobal
name: skipped 1
param:
- $(py_func test parameter)
skipped: 1
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: ValidationTest
name: FunctionItem test
param:
- $(py_func test parameter)
- group:
name: Function results check
steps:
- group:
name: Function result 1
steps:
- py_func:
expected_result: -1
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: int failure
param:
- -1
- py_func:
expected_result: -1.3
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: float failure
param:
- -1.3
- py_func:
expected_result: FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: String failure
param:
- FAIL
- py_func:
expected_result:
- -1
- Got a failure
file: $(test_path)$(psep)py_func.py
func_name: tuple_return
key: $(test)_PASS
name: Tuple int,str failure
param:
- -1
- Got a failure
- group:
name: Functions result 2
steps:
- py_func:
expected_result: 0
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: int success
param:
- 0
- py_func:
expected_result: 0.3
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: float success
param:
- 0.3
- py_func:
expected_result: Something that is not only
strictly FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
key: $(test)_PASS
name: String success
param:
- Something that is not only strictly FAIL
- py_func:
expected_result:
- 0
- OK
file: $(test_path)$(psep)py_func.py
func_name: tuple_return
key: $(test)_PASS
name: Tuple int,str success
param:
- 0
- OK
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: test_delgd
key: $(test)_PASS
name: delgd test
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: return_nothing
key: $(test)_PASS
name: function returning nothing should succeed
- py_func:
file: $(test_path)$(psep)py_func.py
func_name: return_explicit_none
key: $(test)_PASS
name: function returning explicit None should succeed
- group:
name: context_id tests
steps:
- py_func:
expected_result: hello context
file: $(test_path)$(psep)py_func.py
func_name: set_context_value
key: $(test)_PASS
name: set serializable value
param:
- hello context
- py_func:
context_id: ctx_test
expected_result: hello context
file: $(test_path)$(psep)py_func.py
func_name: get_context_value
key: $(test)_PASS
name: get serializable value (same context_id)
- py_func:
expected_result: hello context
file: $(test_path)$(psep)py_func.py
func_name: get_context_value
key: $(test)_PASS
name: get serializable value (no context_id, from
main gd)
- py_func:
context_id: ctx_other
expected_result: hello context
file: $(test_path)$(psep)py_func.py
func_name: get_context_value
key: $(test)_PASS
name: get serializable value (different context_id)
- py_func:
context_id: ctx_ns_test
expected_result: hello ns
file: $(test_path)$(psep)py_func.py
func_name: set_ns_value
key: $(test)_PASS
name: set non-serializable value
param:
- hello ns
- py_func:
context_id: ctx_ns_test
expected_result: hello ns
file: $(test_path)$(psep)py_func.py
func_name: get_ns_value
key: $(test)_PASS
name: get non-serializable value (same context_id)
filename: /home/renish/workspace/testium/code/test/validation/items/py_func/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,87 @@
config_file:
- param.yaml
- items/sleep/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: sleep test constants
values:
test: sleep
test_path: items/$(test)
- group:
name: sleep test
steps:
- sequence:
steps:
- sleep:
condition: $(validation_dialogs)
dialog: true
key: $(test)_PASS
name: Sleep timeout with dialogs
timeout: 3
- sleep:
key: $(test)_PASS
name: Sleep timeout without dialog
timeout: 3.0
- sleep:
key: $(test)_PASS
name: Sleep timeout in textual format
skipped: true
timeout: 1h 3m 2s
filename: /home/renish/workspace/testium/code/test/validation/items/sleep/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

View File

@@ -0,0 +1,84 @@
config_file:
- param.yaml
- items/unittest/param.yaml
main:
name: Testium validation suite
steps:
- group:
name: Test preparation
steps:
- let:
condition: <| "$(os)" == "Linux" |>
name: Set test variables for Linux
values:
- terminal_prompt: $(linux_prompt)
- psep: /
- let:
condition: <| "$(os)" == "Windows" |>
name: Set test variables for Windows
values:
- terminal_prompt: $(windows_prompt)
- psep: \
- group:
name: Group of tests
steps:
- let:
name: unittest test constants
values:
test: unittest
test_path: items/$(test)
- group:
name: unittest test
steps:
- sequence:
steps:
- unittest:
key: $(test)_PASS
name: Unittest item
test_file: /home/renish/workspace/testium/code/test/validation/items/unittest/unittest.py
test_method: test_01_pass
- unittest:
key: $(test)_FAIL
name: Unittest item
test_file: /home/renish/workspace/testium/code/test/validation/items/unittest/unittest.py
test_method:
- test_04_disabled
- test_03_fail
filename: /home/renish/workspace/testium/code/test/validation/items/unittest/test.tum
- sequence:
steps:
- report:
export:
- text:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.txt
- html:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.html
- junit:
key: $(test)_PASS
path: $(validation_report_path)$(psep)$(test)_PASS.junit
name: Expected PASS $(test) test
- report:
export:
- text:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.txt
- html:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.html
- junit:
key: $(test)_FAIL
path: $(validation_report_path)$(psep)$(test)_FAIL.junit
name: Expected FAIL $(test) test
filename: /home/renish/workspace/testium/code/test/validation/items/report.tum
report:
enabled: true
export:
junit:
file_name: $(validation_report_file).junit
path: $(validation_report_path)
sqlite:
file_name: $(validation_report_file).sqlite
path: $(validation_report_path)
log_stored: true

532
schema/tum.json Normal file
View File

@@ -0,0 +1,532 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"config_file":{
"desciption": "The list of the configuration files",
"type": "array",
"items": {
"type": "string"
}
},
"items":{
"properties": {
"name": { "type": "string" },
"stop_on_failure":{ "type": "boolean" },
"execute_on_stop":{ "type": "boolean" },
"skipped":{ "type": "boolean" },
"no_fail":{ "type": "boolean" },
"doc":{ "type": "string" },
"key":{ "type": "string" },
"report":{ "$ref": "#/$defs/report_export" },
"condition":{ "type": "string" },
"process_result":{ "type": "string" },
"expected_result":{ },
"store_result":{ "type": "string" }
}
},
"steps" : {
"required": ["steps"],
"properties": {
"version": { "type": "string" },
"steps": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties":{
"let": { "$ref": "#/$defs/let" },
"check": { "$ref": "#/$defs/check" },
"dialog_question": { "$ref": "#/$defs/dialog" },
"dialog_message": { "$ref": "#/$defs/dialog" },
"dialog_note": { "$ref": "#/$defs/dialog" },
"dialog_value": { "$ref": "#/$defs/dialog" },
"dialog_image": { "$ref": "#/$defs/dialog" },
"lua_func": { "$ref": "#/$defs/func" },
"py_func": { "$ref": "#/$defs/func" },
"console": { "$ref": "#/$defs/console" },
"sleep": { "$ref": "#/$defs/sleep" },
"json_rpc": { "$ref": "#/$defs/json_rpc" },
"group": { "$ref": "#/$defs/group" },
"sequence": { "$ref": "#/$defs/sequence" },
"report": { "$ref": "#/$defs/report" },
"loop": { "$ref": "#/$defs/loop" },
"git": { "$ref": "#/$defs/git" },
"unittest": { "$ref": "#/$defs/unittest" }
}
}
}
}
},
"cons_open" : {
"type":"object",
"allOf":
[
{ "$ref": "#/$defs/items" },
{
"properties": {
"protocol" : {
"enum": ["telnet", "ssh", "serial", "rawtcp", "terminal"]
},
"telnet_host" : {"type": "string" },
"telnet_port" : {"type": "number" },
"ssh_host": {"type": "string" },
"ssh_user": {"type": "string" },
"ssh_pwd": {"type": "string" },
"serial_port": {"type": "string" },
"serial_baudrate": {"type": "integer" },
"buffered": {"type": "boolean" },
"tcp_host" : {"type": "string" },
"tcp_port" : {"type": "number" },
"terminal_path": {"type":"string" },
"shell": {"type":"string" }
},
"required": ["protocol"]
}
]
},
"cons_read": {
"type":"object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties": {
"protocol" : {
"enum": ["telnet", "ssh", "serial", "rawtcp", "terminal"]
},
"expected" : {"type": "string" },
"timeout": {"type": "number" },
"mute": {"type": "boolean" }
},
"required":["expected"]
}
]
},
"console" : {
"description": "The let items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"required": ["steps", "console_name"],
"properties":{
"console_name": {"type":"string" },
"steps": {
"type": "array",
"items": {
"type": "object",
"properties":{
"open": {
"$ref": "#/$defs/cons_open"
},
"write": { "type": "string" },
"writeln": { "type": "string" },
"read_until": {
"$ref": "#/$defs/cons_read"
},
"close": {
"anyOf": [
{"type": "null"},
{"type": "string"}
]
}
},
"additionalProperties": false
}
}
}
}
]
},
"json_rpc_console": {
"type":"object",
"properties": {
"name" : {"type": "string" },
"prompt" : {"type": "string" }
},
"required":["name"],
"additionalProperties": false
},
"json_rpc_udp": {
"type":"object",
"properties": {
"server" : {"type": "string" },
"udp_snd_port" : {"type": "integer" },
"udp_rcv_port" : {"type": "integer" },
"bufsize" : {"type": "integer" }
},
"required":["name"],
"additionalProperties": false
},
"json_rpc_query": {
"type":"object",
"properties": {
"method" : { "type": "string" },
"params" : { "type": "array" },
"id" : {"type": "integer" },
"no_wait" : {"type": "boolean" }
},
"required":["method"],
"additionalProperties": false
},
"json_rpc_receive": {
"type":"object",
"properties": {
"id" : {"type": "integer" },
"timeout" : {"type": "number" }
},
"required":["id"],
"additionalProperties": false
},
"json_rpc" : {
"description": "The json_rpc items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"required": ["steps"],
"properties":{
"udp" : { "$ref": "#/$defs/json_rpc_udp" },
"console" : { "$ref": "#/$defs/json_rpc_console" },
"timeout": {"type": "number" },
"version": {"enum": ["1.0", "2.0"]},
"steps": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties":{
"open": { "type": "null" },
"query": { "$ref": "#/$defs/json_rpc_query" },
"receive": { "$ref": "#/$defs/json_rpc_receive" },
"writeln": { "type": "string" },
"read_until": { "$ref": "#/$defs/cons_read"
},
"close": { "type": "null" }
}
}
}
}
}
]
},
"group" : {
"description": "The group items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{ "$ref": "#/$defs/steps" }
]
},
"sequence" : {
"description": "The sequence items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{ "$ref": "#/$defs/steps" },
{
"properties": {
"filename": { "type": "string" }
},
"required": ["filename"]
}
]
},
"loop" : {
"description": "The loop items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{ "$ref": "#/$defs/steps" },
{
"properties": {
"iterator": { },
"exit_condition": {
"description": "the posibility to stop the loop",
"type": "object",
"additionalProperties": false,
"properties": {
"time" : {"type":"number"},
"value" : {"type":"number"},
"file" : {"type":"string"},
"func_name" : {"type":"string"},
"eval" : {"type":"string"}
},
"dependentRequired": {
"file" : ["func_name"]
}
}
}
}
]
},
"main" : {
"description": "The Main items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{ "$ref": "#/$defs/steps" },
{
"properties": {
"version": { "type": "string" }
}
}
]
},
"sleep" : {
"description": "Sleep for X time [secondes",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"dialog": { "type": "boolean" },
"timeout": { "type": "number" }
},
"required": ["timeout"]
}
]
},
"let" : {
"description": "The let items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"values": {
"anyOf": [
{
"type": "array",
"items": {"type": "object" }
},
{ "type":"object" }
]
}
},
"required": ["values"]
}
]
},
"check" : {
"description": "The let items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"values": {
"type": "array",
"items": {"type": "string" }
}
},
"required": ["values"]
}
]
},
"git" : {
"description": "The git items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"repo": { "type": "string" }
},
"required": ["repo"]
}
]
},
"unittest" : {
"description": "The unittest items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"test_file": { "type": "string" },
"test_method": {
"anyOf": [
{"type":"string"},
{
"type":"array",
"items": {"type":"string"}
}
]
}
},
"required": ["test_file"]
}
]
},
"dialog" : {
"description": "The let items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"question": { "type": "string" },
"auto_result": { "type": "string" },
"auto_value": { "type": ["number", "string"] },
"filename" : {"type": "string"},
"reference" : {
"type":"array",
"items": { "type":"string"}
}
},
"required": ["question"]
}
]
},
"dialog_choice" : {
"description": "The one choi items",
"type": "object",
"additionalProperties": false,
"properties":{
"name": { "type": "string" },
"description": { "type": "string" },
"icon": { "type": "string"},
"choices": {
"type":"array",
"items": { "$ref": "#/$defs/dialog_choice" }
}
},
"required": ["name", "description"]
},
"dialog_choices" : {
"description": "The dialog choices items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"name": { "type": "string" },
"question": { "type": "string" },
"icon": { "type": "string"},
"choices": {
"type":"array",
"items": { "$ref": "#/$defs/dialog_choice" }
}
},
"required": ["question"]
}
]
},
"func" : {
"description": "The py_fun and lua_func items",
"type": "object",
"unevaluatedProperties": false,
"allOf": [
{ "$ref": "#/$defs/items" },
{
"properties":{
"file": { "type": "string" },
"func_name": { "type": "string" },
"context_id": { "type": "string" },
"param" : {
"anyOf": [
{"type": "array"},
{"type": "object"}
]
}
},
"required": ["file", "func_name"]
}
]
},
"report_export": {
"type": "object",
"properties": {
"path": {"type":"string" },
"file_name": {"type":"string" },
"pattern": {"type":"string" },
"key": {"type":"string" }
}
},
"report":{
"desciption": "The list of the configuration files",
"type": "object",
"additional_properties":false,
"properties": {
"enabled": {"type":"boolean" },
"log_stored": {"type":"boolean" },
"export": {
"anyOf": [
{
"type": "object",
"properties":{
"html": { "$ref": "#/$defs/report_export" },
"sqlite": { "$ref": "#/$defs/report_export" },
"junit": { "$ref": "#/$defs/report_export" }
}
},
{
"type": "array",
"items": {
"type":"object",
"properties":{
"html": { "$ref": "#/$defs/report_export" },
"sqlite": { "$ref": "#/$defs/report_export" },
"junit": { "$ref": "#/$defs/report_export" }
}
}
}
]
}
}
}
},
"type": "object",
"properties": {
"config_file" : { "$ref": "#/$defs/config_file" },
"main": { "$ref": "#/$defs/main" },
"report" : { "$ref": "#/$defs/report" }
},
"required" : ["main"],
"additionalProperties": false
}

View File

@@ -20,6 +20,12 @@ if [ "$?" -ne 0 ]; then
echo "venv must be installed on the host distribution."
exit -1
fi
# Check if venv is installed
python3 -c "import ensurepip"
if [ "$?" -ne 0 ]; then
echo "ensurepip must be installed on the host distribution."
exit -1
fi
# Install the virtual environment if needed
if [ ! -d "$PY_VENV_DIR" ]; then

View File

@@ -11,6 +11,7 @@ import threading
from telnetlib3 import Telnet, DO, WILL, WONT, TTYPE, IAC, SB, SE, theNULL
TIMEOUT_NULL = 0.000001
STOP_POLL_INTERVAL = 0.2
class BytesStore(object):
@@ -123,12 +124,14 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
# 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, should_stop=None):
"""
read until the string 'match is found
If timeout is not set (None), this function runs indefinitely
If timeout is set to zero, this function returns immediately
If mute is set to True the characters read from the console will not be displayed
If should_stop is a callable, it is polled between reads (every STOP_POLL_INTERVAL
at most) and the loop exits early — like a timeout — when it returns True.
If function fails (because of a timeout) it will return a 'status' integer set to -1
otherwise it will return 0.
@@ -139,13 +142,6 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
status = -1
if not match:
raise ValueError('match parameter can not be empty')
# replace all '\r' by '\n' as any '\r' read will undergo the same replacement
# match = match.replace('\r\n', '\n')
# match = match.replace('\r', '')
# update the console timeout in conformity with what is required.
self.set_read_timeout(timeout)
if timeout is None:
timeout = 1000000
@@ -159,6 +155,7 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
# buffer is empty
# Otherwise we are waiting for the timeout to rise
if timeout < TIMEOUT_NULL:
self.set_read_timeout(0)
data = self.readchar(0)
while (status < 0) and ((data is not None) and (data != b'')):
@@ -191,39 +188,45 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
# Timeout different than zero
else:
# Poll in short chunks so a stop request is honored within
# STOP_POLL_INTERVAL, regardless of the per-protocol blocking
# behavior of readchar().
self.set_read_timeout(STOP_POLL_INTERVAL)
time_is_out = threading.Event()
timer = threading.Timer(timeout, lambda: time_is_out.set())
timer.start()
# We are waiting for the timeout to rise
try:
while (status < 0) and (not time_is_out.is_set()):
if should_stop is not None and should_stop():
break
while (status < 0) and (not time_is_out.isSet()):
data = self.readchar(timeout)
if data is not None:
data = self._compute_char(data)
if data != '':
if not mute:
self.string_buffer += data
read_data += data
search_deque.append(data)
if search_deque == match_deque:
timer.cancel()
status = 0
if (not mute) and (data != '\n'):
self.string_buffer += '\n'
if data == '\n' or (status >= 0):
# the datas are written line by line for display optimisation in GUI mode
data = self.readchar(STOP_POLL_INTERVAL)
if data is not None:
data = self._compute_char(data)
if data != '':
if not mute:
self.string_buffer = self.string_buffer.replace('\r\n', '\n')
self.string_buffer = self.string_buffer.replace('\r', '')
self.stream.write(self.string_buffer)
self.string_buffer += data
read_data += data
date_str = str(datetime.now()).split('.')[0].split(' ')[1]
self.string_buffer = '[{} {}]'.format(date_str, self.name)
search_deque.append(data)
if search_deque == match_deque:
status = 0
if (not mute) and (data != '\n'):
self.string_buffer += '\n'
if data == '\n' or (status >= 0):
# the datas are written line by line for display optimisation in GUI mode
if not mute:
self.string_buffer = self.string_buffer.replace('\r\n', '\n')
self.string_buffer = self.string_buffer.replace('\r', '')
self.stream.write(self.string_buffer)
date_str = str(datetime.now()).split('.')[0].split(' ')[1]
self.string_buffer = '[{} {}]'.format(date_str, self.name)
finally:
timer.cancel()
if return_data:
return status, read_data

View File

@@ -20,52 +20,64 @@ class TestItem:
def test_run(f):
@wraps(f)
def wrapper(self):
if not self.skipped:
if self.enabled:
self.run_test_init()
# Conditional execution
raw_condition = self._prms.getParam(
"condition", default=None, processed=False
)
if raw_condition is None:
condition = True
else:
c = self._prms.expanse(raw_condition)
if isinstance(c, bool):
condition = c
else:
condition = False
c = False
if raw_condition == c:
msg = f'"{c}"'
else:
msg = f'"{raw_condition}" --> "{c}"'
# Do we have to skip the test because of a true condition ?
if condition:
if not raw_condition is None:
msg = "condition met: " + msg
self.result.reported = {"input_condition": msg}
print(msg)
# Test preparation
self.run_before_test()
# Test execution
f(self)
else:
msg = "condition not met: " + msg
self.result.set(TestValue.NORUN, msg)
self.result.reported = {"input_condition": msg}
self.run_test_end()
else:
self.result.set(TestValue.NORUN, "test disabled")
print("Test is disabled.")
else:
if self.skipped:
self.result.set(TestValue.NORUN, "test skipped")
print("Test is skipped.")
return self.result
if not self.enabled:
self.result.set(TestValue.NORUN, "test disabled")
print("Test is disabled.")
return self.result
self.run_test_init()
while self._is_paused:
sleep(0.2)
if self.isStopped() :
self.result.set(TestValue.NORUN, "test stopped")
print("Test is Stopped.")
self._is_stopped = False # Restore state for next run
return self.result
# Conditional execution
raw_condition = self._prms.getParam(
"condition", default=None, processed=False
)
if raw_condition is None:
condition = True
else:
c = self._prms.expanse(raw_condition)
if isinstance(c, bool):
condition = c
else:
condition = False
c = False
if raw_condition == c:
msg = f'"{c}"'
else:
msg = f'"{raw_condition}" --> "{c}"'
# Do we have to skip the test because of a true condition ?
if condition:
if not raw_condition is None:
msg = "condition met: " + msg
self.result.reported = {"input_condition": msg}
print(msg)
# Test preparation
self.run_before_test()
# Test execution
f(self)
else:
msg = "condition not met: " + msg
self.result.set(TestValue.NORUN, msg)
self.result.reported = {"input_condition": msg}
self.run_test_end()
return self.result
return wrapper
@@ -255,8 +267,6 @@ class TestItem:
self._sendStatusStarted()
if self._is_breakpoint:
self._is_paused = True
while self._is_paused:
sleep(0.2)
if self.is_container:
self.report.incLevel()
@@ -274,9 +284,6 @@ class TestItem:
if self.is_container:
self.report.decLevel()
while self._is_paused:
sleep(0.2)
# Post evaluation of the test result
self.process_result()
# expected_result treatment
@@ -310,6 +317,7 @@ class TestItem:
self.process_report(self._reported)
self.report.addTest(self, self.result, rk)
self._sendStatusFinished()
def process_result(self):
if self._post_eval is None:

View File

@@ -307,11 +307,17 @@ class TestItemConsoleReadUntil(TestItemConsoleAction):
try:
status, data = cons.read_until(
ru, timeout=read_timeout, return_data=True, mute=mute
ru, timeout=read_timeout, return_data=True, mute=mute,
should_stop=self.isStopped,
)
if status == 0:
self.result.set(TestValue.SUCCESS)
self.result.value = data
elif self.isStopped():
self.result.set(
result=TestValue.FAILURE,
message="Console read aborted on stop request",
)
else:
self.result.set(result=TestValue.FAILURE, message="No matching text")
if mute:

View File

@@ -105,6 +105,7 @@ class TestItemJSRPCActionQuery(TestItemAction):
jrpc_id = randint(1, (2**32) - 1)
send_only = self._prms.expanse(self._send_only)
timeout = self._prms.expanse(self._timeout)
self.token.set_should_stop(self.isStopped)
try:
success, result = self.token.query(
meth, obj, jrpc_id, send_only, timeout=timeout
@@ -146,6 +147,7 @@ class TestItemJSRPCActionReceive(TestItemAction):
def execute(self):
timeout = self._prms.expanse(self._timeout)
jrpc_id = self._prms.expanse(self._jrpc_id)
self.token.set_should_stop(self.isStopped)
try:
success, result = self.token.receive(jrpc_id, timeout)

View File

@@ -2,10 +2,11 @@ import json
import socket
import re
import struct
import time
from runtime.tum_except import ETUMRuntimeError
import api.testium as tm
from api.console import Console
from api.console import Console, STOP_POLL_INTERVAL
def is_ip_address(address):
@@ -45,9 +46,16 @@ class JrpcAdapter:
self._jrpc_version = version
self._mute = mute
self._timeout = timeout
# Optional callable polled by _receive() implementations to abort
# waits early when the test is being stopped. Set by the test item
# action before each query/receive call.
self._should_stop = None
if not (version == "1.0" or version == "2.0"):
raise ETUMRuntimeError("Invalid JSONRPC version passed.")
def set_should_stop(self, cb):
self._should_stop = cb
@property
def timeout(self):
return self._timeout
@@ -249,32 +257,38 @@ class JrpcUdpAdapter(JrpcAdapter):
print(f" | sent to @{self._server}:{self._snd_port}")
def _receive(self, timeout: float) -> str:
# Poll in short chunks so a stop request is honored within
# STOP_POLL_INTERVAL.
self.sock.settimeout(STOP_POLL_INTERVAL)
deadline = time.monotonic() + float(timeout)
data = None
addr = None
while True:
if self._should_stop is not None and self._should_stop():
raise ETUMRuntimeError("JSONRPC udp receive aborted on stop request.")
try:
data, addr = self.sock.recvfrom(self._bufsize)
break
except socket.timeout:
if time.monotonic() >= deadline:
raise ETUMRuntimeError(
"JSONRPC udp answer took too long. Try to increase the timeout."
)
# configures the reception timeout
self.sock.settimeout(timeout)
# Receives the answer from the server
try:
data, addr = self.sock.recvfrom(self._bufsize)
# In case of buffer overload we chose to complain
if len(data) >= self._bufsize:
raise ETUMRuntimeError(
"JSONRPC udp answer size overflow. Try to increase the bufsize"
)
# Converts binary to string
res = data.decode()
# Don't log if mute
if not self._mute:
print(f" | UDP answer: '{res}'")
print(f" | received from @{addr[0]}:{addr[1]}")
except socket.timeout:
# In case of buffer overload we chose to complain
if len(data) >= self._bufsize:
raise ETUMRuntimeError(
"JSONRPC udp answer took too long. Try to increase the timeout."
"JSONRPC udp answer size overflow. Try to increase the bufsize"
)
# Converts binary to string
res = data.decode()
# Don't log if mute
if not self._mute:
print(f" | UDP answer: '{res}'")
print(f" | received from @{addr[0]}:{addr[1]}")
return res
def _build_query(self, method: str, obj, jrpc_id: int):
@@ -339,11 +353,16 @@ class JrpcConsoleAdapter(JrpcAdapter):
def _receive(self, timeout: float) -> str:
status, data = self._cons.read_until(
self._endswith, timeout, return_data=True, mute=self._mute
self._endswith, timeout, return_data=True, mute=self._mute,
should_stop=self._should_stop,
)
# if we did not receive anything, we complain
if not status == 0:
if self._should_stop is not None and self._should_stop():
raise ETUMRuntimeError(
f"JSONRPC console receive aborted on stop request."
)
raise ETUMRuntimeError(
f"The '{self._cons.name}' console did not answer in the requested time."
)

View File

@@ -45,6 +45,18 @@ class TestItemLuaFunc(TestItem):
tm.setgd(_LUA_FUNC_CONTEXTS_KEY, contexts)
return contexts[ctx_id], True
def stop(self):
super().stop()
# Tear down the worker so any in-flight func_call returns promptly.
# join() clears _rpc/_process so a subsequent item reusing the same
# context_id can restart the engine cleanly.
try:
engine, _ = self._get_engine()
engine.stop()
engine.join()
except Exception:
pass
@test_run
def execute(self):
self.result.set(
@@ -96,9 +108,15 @@ Is the lua environnment well defined in the "LUA_PATH" and "LUA_CPATH" variables
return
except ConnectionAbortedError:
self.result.set(TestValue.FAILURE, "lua_func aborted on stop request")
print("lua_func aborted on stop request.")
except:
traceback.print_exception(*sys.exc_info())
self.result.set(
TestValue.FAILURE,
'Unrecoverable "lua_func" item error from {}'.format(self.func_name),
)
if self.isStopped():
self.result.set(TestValue.FAILURE, "lua_func aborted on stop request")
else:
self.result.set(
TestValue.FAILURE,
'Unrecoverable "lua_func" item error from {}'.format(self.func_name),
)

View File

@@ -45,6 +45,18 @@ class TestItemPyFunc(TestItem):
tm.setgd(_PY_FUNC_CONTEXTS_KEY, contexts)
return contexts[ctx_id], True
def stop(self):
super().stop()
# Tear down the worker so any in-flight func_call returns promptly.
# join() clears _rpc/_process so a subsequent item reusing the same
# context_id can restart the engine cleanly.
try:
engine, _ = self._get_engine()
engine.stop()
engine.join()
except Exception:
pass
@test_run
def execute(self):
self.result.set(
@@ -94,9 +106,15 @@ python_bin = {tm.gd("python_bin", "no python path defined")}"""
return
except ConnectionAbortedError:
self.result.set(TestValue.FAILURE, "py_func aborted on stop request")
print("py_func aborted on stop request.")
except:
traceback.print_exception(*sys.exc_info())
self.result.set(
TestValue.FAILURE,
'Unrecoverable "py_func" item error from {}'.format(self.func_name),
)
if self.isStopped():
self.result.set(TestValue.FAILURE, "py_func aborted on stop request")
else:
self.result.set(
TestValue.FAILURE,
'Unrecoverable "py_func" item error from {}'.format(self.func_name),
)

View File

@@ -80,4 +80,7 @@ class TestItemSleep(TestItem):
end_time = _time.time() + float(timeout)
while _time.time() < end_time and not self._is_stopped:
sleep(min(0.05, end_time - _time.time()))
self.result.set(TestValue.SUCCESS, 'Sleep %s sec' % (str(timeout)))
if self._is_stopped:
self.result.set(TestValue.FAILURE, 'Sleep aborted on stop request')
else:
self.result.set(TestValue.SUCCESS, 'Sleep %s sec' % (str(timeout)))

View File

@@ -146,4 +146,12 @@ class LuaProcessBase:
"""
if self._rpc is not None:
self._rpc.stop()
# Force-kill the worker if it's still running. Needed when user code
# in the worker is stuck and won't notice the parent closing the RPC
# socket on its own.
if self._process is not None and self._process.poll() is None:
try:
self._process.terminate()
except Exception:
pass

View File

@@ -123,3 +123,11 @@ class PyProcessBase:
def stop(self):
if self._rpc is not None:
self._rpc.stop()
# Force-kill the worker if it's still running. Needed when user code
# in the worker is stuck (e.g. sleep, blocking I/O) and won't notice
# the parent closing the RPC socket on its own.
if self._process is not None and self._process.poll() is None:
try:
self._process.terminate()
except Exception:
pass

View File

@@ -41,8 +41,7 @@ end
--- INTERNAL: Handle requests from the client
function JSONRPC:_handle_request(req)
local method = self.methods[req.method]
local ok, ret
local res, err
local ok, ret, err
if not method then
if req.id then self:_send_error(req.id, string.format("Method '%s' not registered in lua server")) end
return
@@ -52,15 +51,18 @@ function JSONRPC:_handle_request(req)
-- Only send response if it's not a Notification (notifications have no ID)
if req.id then
if ok then
res = ret
if res == nil then
self:_send_error(req.id, tostring(err))
else
self:_send({ jsonrpc = "2.0", result = { returned_value = res }, id = req.id })
end
else
if not ok then
-- pcall trapped a runtime error in the method itself.
self:_send_error(req.id, tostring(ret))
elseif err ~= nil then
-- Method ran but signaled a logical error via its 2nd return.
self:_send_error(req.id, tostring(err))
else
-- Success. A user function returning nothing yields ret==nil;
-- encode it as JSON null so "returned_value" stays present.
local val = ret
if val == nil then val = json.null end
self:_send({ jsonrpc = "2.0", result = { returned_value = val }, id = req.id })
end
end
end

View File

@@ -176,7 +176,7 @@ class TestRunner:
w.actionOpenTest.setDisabled(True)
w.actionExit.setDisabled(True)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(icon_prefix() + "/pause.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon.addPixmap(QtGui.QPixmap(icon_prefix() + "/pause2.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
w.actionStart_test.setIcon(icon)
w.actionStart_test.setText("Pause test")
w.actionPreferences.setDisabled(True)

View File

@@ -200,6 +200,7 @@ class JsonRpcConnection:
Raises:
TimeoutError: If no response is received within `timeout`.
ConnectionAbortedError: If stop() was called while waiting.
"""
req_id = next(self.id_gen)
@@ -214,7 +215,12 @@ class JsonRpcConnection:
self.pending.pop(req_id, None)
raise TimeoutError("Timeout JSON-RPC")
return self.pending.pop(req_id)["response"]
entry = self.pending.pop(req_id)
if entry["response"] is None:
# Woken by stop() (or by a malformed dispatch) rather than by a
# real response — abort the call so callers don't block further.
raise ConnectionAbortedError("JSON-RPC client stopped")
return entry["response"]
def print_info(self, msg):
if self.dbg_out is not None:
@@ -223,6 +229,10 @@ class JsonRpcConnection:
def stop(self):
if self.running:
self.running = False
# Wake any in-flight call() so it doesn't sit on its (default 1h)
# timeout. The response stays None and call() raises ConnectionAbortedError.
for entry in list(self.pending.values()):
entry["event"].set()
def join(self):
self.recv_thread.join()

View File

@@ -49,4 +49,12 @@ function module.test_delgd()
return 0
end
function module.return_nothing()
-- Returns no value: ret is nil but no error.
end
function module.return_explicit_nil()
return nil
end
return module

View File

@@ -186,6 +186,18 @@
file: $(test_path)$(psep)lua_func.lua
func_name: test_delgd
- lua_func:
name: function returning nothing should succeed
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: return_nothing
- lua_func:
name: function returning explicit nil should succeed
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: return_explicit_nil
- group:
name: context_id tests
steps:

View File

@@ -54,3 +54,10 @@ def test_delgd():
tm.delgd("_py_delgd_test")
assert tm.gd("_py_delgd_test", None) is None
return 0
def return_nothing():
# Falls off the end: implicit None return, no error.
pass
def return_explicit_none():
return None

View File

@@ -196,6 +196,18 @@
file: $(test_path)$(psep)py_func.py
func_name: test_delgd
- py_func:
name: function returning nothing should succeed
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: return_nothing
- py_func:
name: function returning explicit None should succeed
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: return_explicit_none
- group:
name: context_id tests
steps: