Complete sim config boundary coverage
This commit is contained in:
189
wasm-port/tests/native/probe_python_remap_runtime.sh
Executable file
189
wasm-port/tests/native/probe_python_remap_runtime.sh
Executable file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
LINUXCNC_ROOT="${LINUXCNC_ROOT:-$ROOT_DIR/../linuxcnc}"
|
||||
FIXTURE_FAMILY="axis/remap/stop-lookahead/nc_files"
|
||||
FIXTURE_DIR="$LINUXCNC_ROOT/configs/sim/axis/remap/stop-lookahead"
|
||||
FIXTURE_INI="$FIXTURE_DIR/demo.ini"
|
||||
RUN_DIR="$ROOT_DIR/build/native/python-remap-runtime"
|
||||
PYTHON_RUNTIME_STDOUT="$RUN_DIR/python_lifecycle.stdout.log"
|
||||
PYTHON_RUNTIME_STDERR="$RUN_DIR/python_lifecycle.stderr.log"
|
||||
|
||||
required_commands=(python3 linuxcnc)
|
||||
missing_requirements=()
|
||||
|
||||
command_path() {
|
||||
command -v "$1" 2>/dev/null || true
|
||||
}
|
||||
|
||||
csv_join() {
|
||||
local IFS=,
|
||||
printf '%s' "$*"
|
||||
}
|
||||
|
||||
print_kv() {
|
||||
printf '%s=%s\n' "$1" "$2"
|
||||
}
|
||||
|
||||
runtime_requirements=()
|
||||
for command_name in "${required_commands[@]}"; do
|
||||
path="$(command_path "$command_name")"
|
||||
if [[ -n "$path" ]]; then
|
||||
runtime_requirements+=("$command_name:1")
|
||||
print_kv "python_remap_runtime_${command_name}_path" "$path"
|
||||
else
|
||||
runtime_requirements+=("$command_name:0")
|
||||
missing_requirements+=("$command_name")
|
||||
fi
|
||||
done
|
||||
|
||||
source_ready=1
|
||||
for rel in \
|
||||
src/emc/rs274ngc/interp_python.cc \
|
||||
src/emc/pythonplugin/python_plugin.cc \
|
||||
configs/sim/axis/remap/stop-lookahead/demo.ini \
|
||||
configs/sim/axis/remap/stop-lookahead/python/remap.py \
|
||||
configs/sim/axis/remap/stop-lookahead/python/toplevel.py; do
|
||||
if [[ ! -f "$LINUXCNC_ROOT/$rel" ]]; then
|
||||
source_ready=0
|
||||
missing_requirements+=("$rel")
|
||||
print_kv "python_remap_missing_source_${rel//[^A-Za-z0-9]/_}" "$LINUXCNC_ROOT/$rel"
|
||||
fi
|
||||
done
|
||||
|
||||
runtime_ready=0
|
||||
if [[ "${#missing_requirements[@]}" -eq 0 ]]; then
|
||||
runtime_ready=1
|
||||
fi
|
||||
|
||||
print_kv python_remap_runtime_fixture_family "$FIXTURE_FAMILY"
|
||||
print_kv python_remap_runtime_fixture_id "stop_lookahead_python_runtime_lifecycle"
|
||||
print_kv python_remap_runtime_fixture_scope "no_python_callables_no_ngc_only_subpaths"
|
||||
print_kv python_remap_runtime_phases "initialize_python,apply_ini_python_path,execute_toplevel,callable_lookup,pycall_dispatch,callable_invoke,remap_phase_dispatch,generator_finish,execute_python_runtime,reload_on_change"
|
||||
print_kv python_remap_runtime_modules "axis/remap/stop-lookahead/python/remap.py,axis/remap/stop-lookahead/python/toplevel.py"
|
||||
print_kv python_remap_runtime_requirements "$(csv_join "${runtime_requirements[@]}")"
|
||||
if [[ "${#missing_requirements[@]}" -eq 0 ]]; then
|
||||
print_kv python_remap_missing_requirements "-"
|
||||
else
|
||||
print_kv python_remap_missing_requirements "$(csv_join "${missing_requirements[@]}")"
|
||||
fi
|
||||
print_kv python_remap_source_proof_ready "$source_ready"
|
||||
print_kv python_remap_runtime_ready "$runtime_ready"
|
||||
print_kv python_remap_execution_enabled 0
|
||||
print_kv python_remap_promotion_allowed 0
|
||||
|
||||
if [[ "$source_ready" != "1" ]]; then
|
||||
print_kv python_remap_runtime_probe_status "blocked_missing_source"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$runtime_ready" != "1" ]]; then
|
||||
print_kv python_remap_runtime_probe_status "skipped_missing_host_runtime"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${ENABLE_PYTHON_REMAP_RUNTIME_PROBE:-0}" != "1" ]]; then
|
||||
print_kv python_remap_runtime_probe_status "ready_disabled_by_default"
|
||||
print_kv python_remap_runtime_probe_note "set_ENABLE_PYTHON_REMAP_RUNTIME_PROBE_1_to_run_python_lifecycle_probe"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$RUN_DIR"
|
||||
rm -f "$PYTHON_RUNTIME_STDOUT" "$PYTHON_RUNTIME_STDERR"
|
||||
|
||||
print_kv python_remap_runtime_probe_fixture "$FIXTURE_DIR"
|
||||
print_kv python_remap_runtime_probe_ini "$FIXTURE_INI"
|
||||
print_kv python_remap_runtime_probe_stdout "$PYTHON_RUNTIME_STDOUT"
|
||||
print_kv python_remap_runtime_probe_stderr "$PYTHON_RUNTIME_STDERR"
|
||||
|
||||
if python3 - "$LINUXCNC_ROOT" "$FIXTURE_DIR" "$FIXTURE_INI" "$RUN_DIR" \
|
||||
>"$PYTHON_RUNTIME_STDOUT" 2>"$PYTHON_RUNTIME_STDERR" <<'PY'
|
||||
import configparser
|
||||
import importlib
|
||||
import inspect
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
linuxcnc_root = Path(sys.argv[1])
|
||||
fixture_dir = Path(sys.argv[2])
|
||||
fixture_ini = Path(sys.argv[3])
|
||||
run_dir = Path(sys.argv[4])
|
||||
|
||||
def emit(name, value):
|
||||
print(f"{name}={value}")
|
||||
|
||||
def require(condition, message):
|
||||
if not condition:
|
||||
raise RuntimeError(message)
|
||||
|
||||
interp_return = linuxcnc_root / "src/emc/nml_intf/interp_return.hh"
|
||||
match = re.search(
|
||||
r"INTERP_EXECUTE_FINISH\s*=\s*([0-9]+)",
|
||||
interp_return.read_text(encoding="utf-8"),
|
||||
)
|
||||
require(match, "missing_INTERP_EXECUTE_FINISH_source_value")
|
||||
execute_finish = int(match.group(1))
|
||||
emit("python_remap_lifecycle_execute_finish_source_value", execute_finish)
|
||||
|
||||
stub_dir = Path(tempfile.mkdtemp(prefix="python-remap-interpreter-", dir=run_dir))
|
||||
(stub_dir / "interpreter.py").write_text(
|
||||
f"INTERP_EXECUTE_FINISH = {execute_finish}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
parser = configparser.ConfigParser(strict=False)
|
||||
parser.optionxform = str
|
||||
parser.read(fixture_ini)
|
||||
require(parser.has_section("PYTHON"), "missing_PYTHON_section")
|
||||
path_prepend = parser.get("PYTHON", "PATH_PREPEND", fallback="")
|
||||
toplevel = parser.get("PYTHON", "TOPLEVEL", fallback="")
|
||||
require(path_prepend == "python", f"PATH_PREPEND_drift:{path_prepend}")
|
||||
require(toplevel == "python/toplevel.py", f"TOPLEVEL_drift:{toplevel}")
|
||||
emit("python_remap_lifecycle_ini_path_prepend", path_prepend)
|
||||
emit("python_remap_lifecycle_ini_toplevel", toplevel)
|
||||
|
||||
sys.path.insert(0, str(stub_dir))
|
||||
sys.path.insert(0, str(fixture_dir / path_prepend))
|
||||
sys.path.insert(0, str(linuxcnc_root / "lib/python"))
|
||||
|
||||
import interpreter # noqa: E402
|
||||
require(interpreter.INTERP_EXECUTE_FINISH == execute_finish, "interpreter_sentinel_drift")
|
||||
emit("python_remap_lifecycle_interpreter_sentinel_ok", 1)
|
||||
|
||||
toplevel_module = importlib.import_module(Path(toplevel).stem)
|
||||
emit("python_remap_lifecycle_toplevel_imported", int(toplevel_module.__name__ == "toplevel"))
|
||||
remap_module = importlib.import_module("remap")
|
||||
emit("python_remap_lifecycle_remap_imported", int(remap_module.__name__ == "remap"))
|
||||
require(hasattr(remap_module, "queuebuster"), "missing_queuebuster_callable")
|
||||
require(callable(remap_module.queuebuster), "queuebuster_not_callable")
|
||||
emit("python_remap_lifecycle_callable_lookup_ok", 1)
|
||||
|
||||
result = remap_module.queuebuster(object())
|
||||
require(inspect.isgenerator(result), "queuebuster_not_generator")
|
||||
emit("python_remap_lifecycle_generator_returned", 1)
|
||||
first_yield = next(result)
|
||||
require(first_yield == execute_finish, f"queuebuster_yield_drift:{first_yield}")
|
||||
emit("python_remap_lifecycle_generator_first_yield", first_yield)
|
||||
try:
|
||||
next(result)
|
||||
raise RuntimeError("queuebuster_generator_did_not_finish")
|
||||
except StopIteration:
|
||||
emit("python_remap_lifecycle_generator_finish_ok", 1)
|
||||
|
||||
emit("python_remap_runtime_lifecycle_probe_ok", 1)
|
||||
PY
|
||||
then
|
||||
cat "$PYTHON_RUNTIME_STDOUT"
|
||||
print_kv python_remap_runtime_probe_status "runtime_lifecycle_probe_passed"
|
||||
print_kv python_remap_runtime_probe_note "linuxcnc_stop_lookahead_python_lifecycle_probe_passed_without_promotion"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat "$PYTHON_RUNTIME_STDOUT" || true
|
||||
print_kv python_remap_runtime_probe_status "runtime_lifecycle_probe_failed"
|
||||
print_kv python_remap_runtime_probe_note "linuxcnc_stop_lookahead_python_lifecycle_probe_failed"
|
||||
exit 1
|
||||
Reference in New Issue
Block a user