diff --git a/docs/wasm-runtime-architecture.md b/docs/wasm-runtime-architecture.md index 578ec8e..be3a020 100644 --- a/docs/wasm-runtime-architecture.md +++ b/docs/wasm-runtime-architecture.md @@ -359,7 +359,13 @@ header free-functions are `inline`. The wasm backend exposes only declarations - **Regression gate**: `scripts/run_cli_tests.sh --include-wasm-kill` runs the in-runtime CLI suite (`site/tests/cli_runner.uce`) plus the site test pages and - `scripts/test_dependency_invalidation.sh`. The latter changes a transitive + `scripts/test_dependency_invalidation.sh`. The shell helper runs the CLI suite + as named groups (`demo`, `http`, `site`, `doc-gate`, `security`, + `task-lifetime`, `starter`, `tcp`, and optional `wasm-kill`) so a slow or + failing group is visible before the rest of the gate runs. `doc-gate` can take + several minutes on a cold runtime because it compiles generated documentation + examples; `UCE_CLI_TEST_TIMEOUT` controls the per-group curl timeout and + defaults to 900 seconds. The dependency-invalidation gate changes a transitive `#load`, then replaces a warmed worker artifact while preserving its whole-second mtime to prove both compiler and worker caches invalidate it. It also rejects an unreadable unit without publishing a wasm artifact, restores diff --git a/scripts/run_cli_tests.sh b/scripts/run_cli_tests.sh index d5f4902..309173f 100755 --- a/scripts/run_cli_tests.sh +++ b/scripts/run_cli_tests.sh @@ -3,6 +3,7 @@ set -euo pipefail cd "$(dirname "$0")/.." socket_path="${UCE_CLI_SOCKET:-/run/uce/cli.sock}" +curl_timeout="${UCE_CLI_TEST_TIMEOUT:-900}" if [[ -z "${UCE_CLI_SOCKET:-}" && -r /etc/uce/settings.cfg ]]; then configured_socket=$(awk -F= '/^[[:space:]]*CLI_SOCKET_PATH[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' /etc/uce/settings.cfg) if [[ -n "${configured_socket:-}" ]]; then @@ -32,6 +33,9 @@ while [[ $# -gt 0 ]]; do Usage: scripts/run_cli_tests.sh [--include-wasm-kill] [--skip-local-service-pages] [--list] Runs the UCE unit-based test suite through the runtime CLI socket. + +Environment: + UCE_CLI_TEST_TIMEOUT Per CLI runner group curl timeout in seconds (default: 900). USAGE exit 0 ;; @@ -47,9 +51,21 @@ if [[ ! -S "$socket_path" ]]; then exit 1 fi -url="http://localhost/tests/cli_runner.uce?action=${action}&include_kill=${include_kill}&skip_local_service_pages=${skip_local_service_pages}" -curl -sS --fail-with-body --unix-socket "$socket_path" "$url" +base_url="http://localhost/tests/cli_runner.uce?action=${action}&include_kill=${include_kill}&skip_local_service_pages=${skip_local_service_pages}" +if [[ "$action" == "list" ]]; then + curl -sS --max-time "$curl_timeout" --fail-with-body --unix-socket "$socket_path" "$base_url" + exit 0 +fi + if [[ "$action" == "run" ]]; then + groups=(demo http site doc-gate security task-lifetime starter tcp) + if [[ "$include_kill" == "1" ]]; then + groups+=(wasm-kill) + fi + for group in "${groups[@]}"; do + echo "== UCE CLI group: $group ==" + curl -sS --max-time "$curl_timeout" --fail-with-body --unix-socket "$socket_path" "${base_url}&group=${group}" + done scripts/test_dependency_invalidation.sh scripts/test_cold_component_deadline.sh scripts/test_password_hashing.sh diff --git a/site/tests/cli_runner.uce b/site/tests/cli_runner.uce index 3911bbe..2fcb25b 100644 --- a/site/tests/cli_runner.uce +++ b/site/tests/cli_runner.uce @@ -401,12 +401,47 @@ void cli_run_wasm_kill(bool include_kill) void cli_print_list(bool include_kill) { print("UCE CLI test groups:\n"); - print(" demo, http, site, security, starter, tcp"); + print(" demo, http, site, doc-gate, security, task-lifetime, starter, tcp"); if(include_kill) print(", wasm-kill"); print("\n"); } +bool cli_run_group(String group, bool skip_local_service_pages, bool include_kill) +{ + f64 group_start = time_precise(); + if(group == "demo") + cli_run_demo_smoke(); + else if(group == "http") + cli_run_http_smoke(); + else if(group == "site") + cli_run_site_suite(skip_local_service_pages); + else if(group == "doc-gate") + cli_run_doc_pages_gate(); + else if(group == "security") + cli_run_security_smoke(); + else if(group == "task-lifetime") + cli_run_task_lifetime_smoke(); + else if(group == "starter") + cli_run_starter_parity(); + else if(group == "tcp") + { + cli_run_tcp_smoke(); + String repo_root = process_start_directory(); + String cli_arg_out = shell_exec("cd " + shell_escape(repo_root) + " && bash scripts/uce-cli /tests/cli.uce action=arg message=hello-cli 2>&1"); + cli_test_case("uce_cli_fixture:cli_arg", contains(cli_arg_out, "hello-cli") && contains(cli_arg_out, "fallback"), cli_truncate(cli_arg_out)); + } + else if(group == "wasm-kill") + cli_run_wasm_kill(include_kill); + else + { + cli_test_case("uce_cli_runner:known group", false, "unknown group: " + group); + return(false); + } + print("[GROUP] ", group, " ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); + return(true); +} + CLI(Request& context) { context.header["Content-Type"] = "text/plain; charset=utf-8"; @@ -420,36 +455,15 @@ CLI(Request& context) } print("Running UCE CLI tests\n"); - f64 group_start = time_precise(); - cli_run_demo_smoke(); - print("[GROUP] demo ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_http_smoke(); - print("[GROUP] http ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_site_suite(input["skip_local_service_pages"].to_bool()); - print("[GROUP] site ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_doc_pages_gate(); - print("[GROUP] doc-gate ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_security_smoke(); - print("[GROUP] security ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_task_lifetime_smoke(); - print("[GROUP] task-lifetime ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_starter_parity(); - print("[GROUP] starter ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_tcp_smoke(); - String repo_root = process_start_directory(); - String cli_arg_out = shell_exec("cd " + shell_escape(repo_root) + " && bash scripts/uce-cli /tests/cli.uce action=arg message=hello-cli 2>&1"); - cli_test_case("uce_cli_fixture:cli_arg", contains(cli_arg_out, "hello-cli") && contains(cli_arg_out, "fallback"), cli_truncate(cli_arg_out)); - print("[GROUP] tcp ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); - group_start = time_precise(); - cli_run_wasm_kill(include_kill); - print("[GROUP] wasm-kill ", std::to_string((u64)((time_precise() - group_start) * 1000)), " ms\n"); + String group = input["group"].to_string(); + if(group != "") + cli_run_group(group, input["skip_local_service_pages"].to_bool(), include_kill); + else + { + for(String item : { "demo", "http", "site", "doc-gate", "security", "task-lifetime", "starter", "tcp" }) + cli_run_group(item, input["skip_local_service_pages"].to_bool(), include_kill); + cli_run_group("wasm-kill", input["skip_local_service_pages"].to_bool(), include_kill); + } print("\nSummary: ", std::to_string(cli_tests_passed), " passed, ", std::to_string(cli_tests_failed), " failed, ", std::to_string(cli_tests_skipped), " skipped\n"); if(cli_tests_failed != 0) {