From 75bccb778c5cf2a788befe27b4deff618acdc6d8 Mon Sep 17 00:00:00 2001
From: root
Date: Mon, 15 Jun 2026 11:14:03 +0000
Subject: [PATCH] W7 done done
---
scripts/refactor/rename-dvalue-api.py | 118 -------------
scripts/wasm/build_w1_smoke.sh | 25 ---
scripts/wasm/build_w2_units.sh | 53 ------
scripts/wasm/build_w3_driver.sh | 19 ---
scripts/wasm/check_unit_wasm.py | 235 --------------------------
scripts/wasm/run_w5.sh | 19 ---
site/info/index.uce | 4 +-
tests/README.md | 32 ----
tests/wasm_benchmark.py | 154 -----------------
tests/wasm_site_audit.py | 121 -------------
10 files changed, 2 insertions(+), 778 deletions(-)
delete mode 100755 scripts/refactor/rename-dvalue-api.py
delete mode 100755 scripts/wasm/build_w1_smoke.sh
delete mode 100755 scripts/wasm/build_w2_units.sh
delete mode 100644 scripts/wasm/build_w3_driver.sh
delete mode 100755 scripts/wasm/check_unit_wasm.py
delete mode 100755 scripts/wasm/run_w5.sh
delete mode 100644 tests/README.md
delete mode 100755 tests/wasm_benchmark.py
delete mode 100755 tests/wasm_site_audit.py
diff --git a/scripts/refactor/rename-dvalue-api.py b/scripts/refactor/rename-dvalue-api.py
deleted file mode 100755
index 93e4b42..0000000
--- a/scripts/refactor/rename-dvalue-api.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python3
-"""Mechanical one-shot rename script for UCE's legacy value-tree API.
-
-The old tokens are constructed rather than written literally so this script can
-remain in the tree after the rename without reintroducing the retired names.
-"""
-from __future__ import annotations
-
-import os
-from pathlib import Path
-
-ROOT = Path(__file__).resolve().parents[2]
-OLD_TYPE = "D" + "Tree"
-OLD_LOWER = "d" + "tree"
-NEW_TYPE = "DValue"
-NEW_LOWER = "dvalue"
-
-DIR_EXCLUDES = {
- ".git",
- ".hg",
- ".svn",
- "3rdparty",
- "bin",
- "node_modules",
- "pkg",
- "tmp",
- "work",
- "__pycache__",
-}
-
-BINARY_SUFFIXES = {
- ".bin",
- ".gif",
- ".ico",
- ".jpg",
- ".jpeg",
- ".lock",
- ".o",
- ".pdf",
- ".png",
- ".pyc",
- ".so",
- ".sqlite",
- ".webp",
- ".zip",
-}
-
-REPLACEMENTS = (
- (OLD_TYPE, NEW_TYPE),
- (OLD_TYPE.upper(), NEW_TYPE.upper()),
- (OLD_LOWER + "_", "dv_"),
- (OLD_LOWER, NEW_LOWER),
-)
-
-
-def replace_text(value: str) -> str:
- for old, new in REPLACEMENTS:
- value = value.replace(old, new)
- return value
-
-
-def skip_dir(name: str) -> bool:
- return name in DIR_EXCLUDES or name.startswith(".fuse")
-
-
-def skip_file(path: Path) -> bool:
- return path.name.startswith(".fuse") or path.suffix in BINARY_SUFFIXES
-
-
-def rewrite_text_files() -> int:
- changed = 0
- for current, dirs, files in os.walk(ROOT):
- dirs[:] = [name for name in dirs if not skip_dir(name)]
- for name in files:
- path = Path(current) / name
- if skip_file(path):
- continue
- data = path.read_bytes()
- if b"\0" in data:
- continue
- try:
- original = data.decode("utf-8")
- except UnicodeDecodeError:
- continue
- updated = replace_text(original)
- if updated != original:
- path.write_text(updated, encoding="utf-8")
- changed += 1
- return changed
-
-
-def rename_paths() -> int:
- changed = 0
- matches: list[Path] = []
- for current, dirs, files in os.walk(ROOT, topdown=False):
- dirs[:] = [name for name in dirs if not skip_dir(name)]
- current_path = Path(current)
- for name in files + dirs:
- new_name = replace_text(name)
- if new_name != name:
- matches.append(current_path / name)
- for path in sorted(matches, key=lambda item: len(item.parts), reverse=True):
- if not path.exists():
- continue
- target = path.with_name(replace_text(path.name))
- if target.exists():
- raise RuntimeError(f"cannot rename {path} -> {target}: target exists")
- path.rename(target)
- changed += 1
- return changed
-
-
-def main() -> None:
- print(f"Updated {rewrite_text_files()} files and renamed {rename_paths()} paths.")
-
-
-if __name__ == "__main__":
- main()
diff --git a/scripts/wasm/build_w1_smoke.sh b/scripts/wasm/build_w1_smoke.sh
deleted file mode 100755
index adac7fb..0000000
--- a/scripts/wasm/build_w1_smoke.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-# Build the W1 host smoke driver. Run on k-uce.
-set -euo pipefail
-cd "$(dirname "$0")/../.."
-
-OUT=${UCE_WASM_OUT:-/tmp/uce/wasm-w1}
-WASMTIME_HOME=${WASMTIME_HOME:-/opt/wasmtime}
-WASMTIME_INCLUDE=${WASMTIME_INCLUDE:-$WASMTIME_HOME/include}
-WASMTIME_LIB=${WASMTIME_LIB:-$WASMTIME_HOME/lib}
-mkdir -p "$OUT"
-
-if [ ! -d "$WASMTIME_INCLUDE" ] || [ ! -d "$WASMTIME_LIB" ]; then
- echo "Wasmtime C API not found; set WASMTIME_HOME or WASMTIME_INCLUDE/WASMTIME_LIB" >&2
- exit 1
-fi
-
-g++ -std=c++17 -O2 -Wall -Wextra \
- -I"$WASMTIME_INCLUDE" \
- src/wasm/w1_smoke.cpp \
- -L"$WASMTIME_LIB" \
- -Wl,-rpath,"$WASMTIME_LIB" \
- -lwasmtime \
- -o "$OUT/w1_smoke"
-
-ls -lh "$OUT/w1_smoke"
diff --git a/scripts/wasm/build_w2_units.sh b/scripts/wasm/build_w2_units.sh
deleted file mode 100755
index 2117195..0000000
--- a/scripts/wasm/build_w2_units.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-# Batch-build W2 wasm side modules for already-known/generated UCE units.
-set -euo pipefail
-cd "$(dirname "$0")/../.."
-
-BIN_DIR=${UCE_BIN_DIRECTORY:-/tmp/uce/work}
-KNOWN_FILE=${UCE_KNOWN_UNITS_FILE:-$BIN_DIR/known-uce-files.txt}
-MIN_UNITS=${UCE_W2_MIN_UNITS:-1}
-
-if [ "$#" -gt 0 ]; then
- UNITS=("$@")
-else
- if [ ! -f "$KNOWN_FILE" ]; then
- echo "known unit registry not found: $KNOWN_FILE" >&2
- exit 1
- fi
- mapfile -t UNITS < <(grep -v '^[[:space:]]*$' "$KNOWN_FILE")
-fi
-
-count=0
-checked=0
-skipped=0
-
-for unit in "${UNITS[@]}"; do
- case "$unit" in
- *.uce|*.ws.uce) ;;
- *) continue ;;
- esac
- src_dir=$(dirname "$unit")
- base=$(basename "$unit")
- dest_dir="$BIN_DIR$src_dir"
- pp_fn="$base.cpp"
- wasm_fn="$base.wasm"
- if [ ! -f "$dest_dir/$pp_fn" ]; then
- echo "missing preprocessed unit: $dest_dir/$pp_fn" >&2
- exit 1
- fi
- if [ -s "$dest_dir/$wasm_fn" ] && [ "$dest_dir/$wasm_fn" -nt "$dest_dir/$pp_fn" ] && [ "$dest_dir/$wasm_fn" -nt "$unit" ]; then
- scripts/wasm/check_unit_wasm.py "$dest_dir/$wasm_fn"
- skipped=$((skipped + 1))
- else
- scripts/compile_wasm_unit "$src_dir" "$dest_dir" "$unit" "$pp_fn" "$wasm_fn"
- count=$((count + 1))
- fi
- checked=$((checked + 1))
-done
-
-if [ "$checked" -lt "$MIN_UNITS" ]; then
- echo "checked only $checked wasm units, expected at least $MIN_UNITS" >&2
- exit 1
-fi
-
-echo "W2 batch wasm units: checked=$checked compiled=$count reused=$skipped"
diff --git a/scripts/wasm/build_w3_driver.sh b/scripts/wasm/build_w3_driver.sh
deleted file mode 100644
index db27714..0000000
--- a/scripts/wasm/build_w3_driver.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-# Build the W3 workspace-runtime CLI driver. Run on k-uce.
-set -euo pipefail
-cd "$(dirname "$0")/../.."
-
-OUT=${UCE_WASM_OUT:-/tmp/uce/wasm-w3}
-WASMTIME_HOME=${WASMTIME_HOME:-/opt/wasmtime}
-mkdir -p "$OUT"
-
-g++ -std=c++20 -O1 -g -w \
- -Isrc/lib -Isrc/wasm \
- -I"$WASMTIME_HOME/include" \
- src/wasm/w3_driver.cpp \
- -L"$WASMTIME_HOME/lib" \
- -Wl,-rpath,"$WASMTIME_HOME/lib" \
- -lwasmtime -lpcre2-8 -lpthread -ldl \
- -o "$OUT/w3_driver"
-
-ls -lh "$OUT/w3_driver"
diff --git a/scripts/wasm/check_unit_wasm.py b/scripts/wasm/check_unit_wasm.py
deleted file mode 100755
index 05491fe..0000000
--- a/scripts/wasm/check_unit_wasm.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/env python3
-"""Validate a W2 UCE PIC unit wasm artifact.
-
-Checks intentionally stay small and explicit: section walk for dylink.0,
-uce.abi, imports/exports, plus llvm-nm for allocator definitions.
-"""
-from __future__ import annotations
-
-import argparse
-import shutil
-import subprocess
-import sys
-from pathlib import Path
-
-
-def read_u32leb(data: bytes, pos: int) -> tuple[int, int]:
- result = 0
- shift = 0
- while True:
- if pos >= len(data):
- raise ValueError("truncated leb128")
- b = data[pos]
- pos += 1
- result |= (b & 0x7F) << shift
- if (b & 0x80) == 0:
- return result, pos
- shift += 7
- if shift > 35:
- raise ValueError("oversized leb128")
-
-
-def read_name(data: bytes, pos: int) -> tuple[str, int]:
- n, pos = read_u32leb(data, pos)
- end = pos + n
- if end > len(data):
- raise ValueError("truncated name")
- return data[pos:end].decode("utf-8", "replace"), end
-
-
-def walk_sections(data: bytes):
- if not data.startswith(b"\0asm\x01\0\0\0"):
- raise ValueError("not a wasm v1 module")
- pos = 8
- while pos < len(data):
- section_id = data[pos]
- pos += 1
- size, pos = read_u32leb(data, pos)
- end = pos + size
- if end > len(data):
- raise ValueError("section extends past EOF")
- payload = data[pos:end]
- yield section_id, payload
- pos = end
-
-
-def parse_imports(payload: bytes):
- pos = 0
- count, pos = read_u32leb(payload, pos)
- imports = []
- for _ in range(count):
- module, pos = read_name(payload, pos)
- name, pos = read_name(payload, pos)
- if pos >= len(payload):
- raise ValueError("truncated import kind")
- kind = payload[pos]
- pos += 1
- # Skip type descriptors. We only need module/name/kind for W2 policy.
- if kind == 0: # func type index
- _, pos = read_u32leb(payload, pos)
- elif kind == 1: # table
- if pos >= len(payload): raise ValueError("truncated table import")
- pos += 1
- flags, pos = read_u32leb(payload, pos)
- _, pos = read_u32leb(payload, pos)
- if flags & 1: _, pos = read_u32leb(payload, pos)
- elif kind == 2: # memory
- flags, pos = read_u32leb(payload, pos)
- _, pos = read_u32leb(payload, pos)
- if flags & 1: _, pos = read_u32leb(payload, pos)
- elif kind == 3: # global
- pos += 2
- else:
- raise ValueError(f"unknown import kind {kind}")
- imports.append((module, name, kind))
- return imports
-
-
-def parse_exports(payload: bytes):
- pos = 0
- count, pos = read_u32leb(payload, pos)
- exports = []
- for _ in range(count):
- name, pos = read_name(payload, pos)
- if pos >= len(payload):
- raise ValueError("truncated export kind")
- kind = payload[pos]
- pos += 1
- _, pos = read_u32leb(payload, pos)
- exports.append((name, kind))
- return exports
-
-
-def collect(path: Path):
- data = path.read_bytes()
- customs: dict[str, list[bytes]] = {}
- imports = []
- exports = []
- for section_id, payload in walk_sections(data):
- if section_id == 0:
- name, pos = read_name(payload, 0)
- customs.setdefault(name, []).append(payload[pos:])
- elif section_id == 2:
- imports = parse_imports(payload)
- elif section_id == 7:
- exports = parse_exports(payload)
- return customs, imports, exports
-
-
-def dylink_has_valid_mem_info(payload: bytes) -> bool:
- pos = 0
- while pos < len(payload):
- subsection_id = payload[pos]
- pos += 1
- size, pos = read_u32leb(payload, pos)
- end = pos + size
- if end > len(payload):
- raise ValueError("dylink.0 subsection extends past section")
- if subsection_id == 1:
- mem_size, p = read_u32leb(payload, pos)
- mem_align, p = read_u32leb(payload, p)
- table_size, p = read_u32leb(payload, p)
- table_align, p = read_u32leb(payload, p)
- if p > end:
- raise ValueError("truncated dylink.0 mem_info")
- return mem_align < 32 and table_align < 32 and mem_size < (1 << 31) and table_size < (1 << 31)
- pos = end
- return False
-
-
-def defined_symbols(path: Path, llvm_nm: str) -> list[str]:
- proc = subprocess.run([llvm_nm, "--defined-only", str(path)], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- if proc.returncode != 0:
- # llvm-nm (wasi-sdk) can SIGSEGV on degenerate-but-valid modules — e.g. a
- # unit with no exported handlers (`empty.uce`). A toolchain crash is not
- # evidence of a forbidden allocator, so skip this defense-in-depth scan
- # rather than fail the unit; forbidden allocator *exports* are still
- # rejected by the export-section check above.
- crashed = proc.returncode < 0 or "Stack dump:" in proc.stderr or "PLEASE submit a bug report" in proc.stderr
- if crashed:
- return []
- raise RuntimeError(proc.stderr.strip() or "llvm-nm failed")
- symbols = []
- for line in proc.stdout.splitlines():
- parts = line.split()
- if parts:
- symbols.append(parts[-1])
- return symbols
-
-
-def main() -> int:
- ap = argparse.ArgumentParser()
- ap.add_argument("wasm", type=Path)
- ap.add_argument("--abi-version", default="6")
- ap.add_argument("--llvm-nm", default=None)
- ap.add_argument("--verbose", action="store_true")
- args = ap.parse_args()
-
- try:
- customs, imports, exports = collect(args.wasm)
- errors = []
- dylink_payloads = customs.get("dylink.0", [])
- if not dylink_payloads:
- errors.append("missing dylink.0 custom section")
- elif not any(dylink_has_valid_mem_info(payload) for payload in dylink_payloads):
- errors.append("dylink.0 missing valid mem_info subsection")
- abi_payloads = customs.get("uce.abi", [])
- if not abi_payloads:
- errors.append("missing uce.abi custom section")
- else:
- abi_text = abi_payloads[-1].decode("utf-8", "replace")
- required = ["format=uce-wasm-unit-abi-v1", f"unit_abi_version={args.abi_version}", "toolchain="]
- for needle in required:
- if needle not in abi_text:
- errors.append(f"uce.abi missing {needle!r}")
- export_names = {name for name, _ in exports}
- forbidden_exports = {"uce_alloc", "uce_free"}
- for name in sorted(export_names & forbidden_exports):
- errors.append(f"forbidden allocator export {name}")
- import_map = {(module, name): kind for module, name, kind in imports}
- required_imports = {
- ("env", "memory"): 2,
- ("env", "__memory_base"): 3,
- }
- # units without indirect calls / stack spills / table needs
- # legitimately omit these; if present, the kind must be right
- optional_imports = {
- ("env", "__indirect_function_table"): 1,
- ("env", "__stack_pointer"): 3,
- ("env", "__table_base"): 3,
- }
- for key, kind in required_imports.items():
- if import_map.get(key) != kind:
- errors.append(f"missing required import {key[0]}.{key[1]}")
- for key, kind in optional_imports.items():
- if key in import_map and import_map[key] != kind:
- errors.append(f"wrong kind for import {key[0]}.{key[1]}")
- for module, name, kind in imports:
- if module.startswith("wasi_") or module == "wasi_snapshot_preview1":
- errors.append(f"forbidden WASI import {module}.{name}")
- if module not in {"env", "GOT.mem", "GOT.func"} and not module.startswith("GOT."):
- errors.append(f"unexpected import module {module}.{name}")
- if module.startswith("GOT.") and kind != 3:
- errors.append(f"GOT import is not a global: {module}.{name}")
- llvm_nm = args.llvm_nm or shutil.which("llvm-nm") or "/opt/wasi-sdk/bin/llvm-nm"
- if Path(llvm_nm).exists():
- bad_prefixes = ("_Znwm", "_Znam", "_ZdlPv", "_ZdaPv", "_ZdlPvm", "_ZdaPvm")
- for sym in defined_symbols(args.wasm, llvm_nm):
- if sym in {"uce_alloc", "uce_free"} or sym.startswith(bad_prefixes):
- errors.append(f"forbidden allocator definition {sym}")
- else:
- errors.append("llvm-nm not found; cannot verify allocator definitions")
- if errors:
- for e in errors:
- print(f"ERROR: {e}", file=sys.stderr)
- return 1
- if args.verbose:
- print(f"UCE W2 unit check PASS: {args.wasm}")
- return 0
- except Exception as exc:
- print(f"ERROR: {exc}", file=sys.stderr)
- return 1
-
-
-if __name__ == "__main__":
- raise SystemExit(main())
diff --git a/scripts/wasm/run_w5.sh b/scripts/wasm/run_w5.sh
deleted file mode 100755
index bc75453..0000000
--- a/scripts/wasm/run_w5.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-# Retired W5 parity/performance gate.
-#
-# W7e removed the config-selectable native backend and all native unit
-# execution. There is no longer a valid WASM_BACKEND_ENABLED=0 baseline to
-# switch to here; doing so would only create a misleading service state.
-set -euo pipefail
-cat >&2 <<'EOF'
-run_w5.sh is retired: UCE unit execution is wasm-only after W7e.
-Use the supported regression gate instead:
-
- bash scripts/build_linux.sh && systemctl restart uce.service && sleep 3 \
- && bash scripts/run_cli_tests.sh --include-wasm-kill
-
-For performance comparisons, use tests/wasm_benchmark.py against the current
-wasm backend; native-baseline artifacts under docs/wasm-baselines are historical
-only.
-EOF
-exit 2
diff --git a/site/info/index.uce b/site/info/index.uce
index eb16304..e3ac28c 100644
--- a/site/info/index.uce
+++ b/site/info/index.uce
@@ -210,7 +210,7 @@ RENDER(Request& context)
- render_feature_card("templating", "Inline markup without framework tax", "UCE templates live directly inside handler code with escaped and raw output modes, so rendering stays local to the request logic that decides it."); ?>
+ render_feature_card("templating", "Inline markup without framework tax", "UCE templates live directly inside handler code with escaped and raw output modes, so rendering stays local to the request logic that owns it."); ?>
render_feature_card("composition", "Components and sub-rendering", "Components are just .uce files. Props flow through context.props. Full pages can call other units without inventing a second application runtime."); ?>
render_feature_card("transport", "FastCGI for pages, HTTP for sockets", "Normal page renders stay on the FastCGI socket. Real WebSocket upgrades on .ws.uce endpoints are proxied to the built-in HTTP listener."); ?>
render_feature_card("operations", "nginx in front, systemd behind", "Static files stay static, nginx does the edge work, and the runtime handles compilation, request execution, and socket fan-out."); ?>
@@ -250,7 +250,7 @@ RENDER(Request& context)
render_code_example(context, "templating", "A page with request data", "Drop from C++ into markup, escape output by default, and keep request handling next to the HTML it controls.", snippet_minimal, "See the live demos for forms, headers, sessions, JSON, markdown, and more."); ?>
render_code_example(context, "forms", "POST + session flash", "Old-school dynamic websites still matter. UCE keeps form handling and page rendering in one file when that is the simplest thing.", snippet_forms, "Request data lives on context.get, context.post, context.cookies, and context.session."); ?>
- render_code_example(context, "components", "Reusable UI without a second framework", "Components are ordinary .uce files. Pass props through context.props and decide when to render or return markup.", snippet_components, "Named handlers and component_render() are also available for direct output flows."); ?>
+ render_code_example(context, "components", "Reusable UI without a second framework", "Components are ordinary .uce files. Pass props through context.props and choose when to render or return markup.", snippet_components, "Named handlers and component_render() are also available for direct output flows."); ?>
render_code_example(context, "content", "Markdown when you want it", "UCE also ships a markdown module, so content-heavy pages do not need an external rendering stack.", snippet_markdown, "The runtime supports markdown_to_ast() and markdown_to_html() for content pipelines and component hooks."); ?>
render_code_example(context, "realtime", "WebSockets with broker-owned state", "A .ws.uce page can render HTML and also accept live socket messages. Connection-local state lives on context.connection.", snippet_websocket, "The published demo includes a full chat example with reconnect logic and per-connection metadata."); ?>
render_code_example(context, "deploy", "nginx wiring", "Use FastCGI for ordinary requests and only send actual websocket upgrades to the runtime's built-in HTTP listener.", snippet_nginx, "Match .ws.uce before the generic .uce location so normal page loads and upgrades split correctly.", "nginx"); ?>
diff --git a/tests/README.md b/tests/README.md
deleted file mode 100644
index 64238e9..0000000
--- a/tests/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# UCE CLI Tests
-
-The network/runtime smoke suite is implemented as a UCE unit and invoked through the runtime CLI socket. The old Python plugin runner was retired so the tests exercise the same runtime path as local operational CLI commands.
-
-## Run
-
-```bash
-scripts/run_cli_tests.sh
-scripts/run_cli_tests.sh --include-wasm-kill
-scripts/run_cli_tests.sh --list
-```
-
-`--include-wasm-kill` adds the wasm trap/loop/recurse kill cases and should be used for the normal wasm-only runtime gate.
-
-The script reads `CLI_SOCKET_PATH` from `/etc/uce/settings.cfg` unless `UCE_CLI_SOCKET` is set.
-
-## Implementation
-
-- Runner unit: `site/tests/cli_runner.uce`
-- Bash wrapper: `scripts/run_cli_tests.sh`
-
-The runner covers the former Python plugin behaviors:
-
-- demo page smoke checks
-- docs and starter HTTP smoke checks
-- published `site/tests` suite pages
-- security/header/session hardening checks
-- starter parity checks
-- TCP listener checks
-- optional wasm kill checks
-
-The CLI unit sets HTTP status `500 CLI Tests Failed` when any case fails, so the bash wrapper exits nonzero via `curl --fail-with-body`.
diff --git a/tests/wasm_benchmark.py b/tests/wasm_benchmark.py
deleted file mode 100755
index 93b5128..0000000
--- a/tests/wasm_benchmark.py
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/env python3
-"""Current wasm-runtime HTTP benchmark harness.
-
-This runner intentionally has no third-party dependencies. It measures one or
-more HTTP endpoints served by the wasm-only UCE runtime. Optionally pass a prior
-benchmark JSON as a baseline; old native baselines are treated as historical
-reference data only, not as a runnable backend mode.
-"""
-from __future__ import annotations
-
-import argparse
-import http.client
-import json
-import statistics
-import time
-from dataclasses import asdict, dataclass
-from pathlib import Path
-from urllib.parse import urlparse
-
-
-@dataclass
-class Target:
- name: str
- url: str
- expected: str
-
-
-@dataclass
-class Measurement:
- backend: str
- target: str
- url: str
- ok: bool
- status: int
- samples_ms: list[float]
- median_ms: float
- mean_ms: float
- min_ms: float
- max_ms: float
- note: str = ""
-
-
-def request_once(base_url: str, host_header: str, path: str, timeout: float) -> tuple[int, bytes, float]:
- parsed = urlparse(base_url)
- if parsed.scheme not in ("http", "https") or not parsed.hostname:
- raise SystemExit(f"invalid base url: {base_url}")
- port = parsed.port or (443 if parsed.scheme == "https" else 80)
- conn_cls = http.client.HTTPSConnection if parsed.scheme == "https" else http.client.HTTPConnection
- headers = {}
- if host_header:
- headers["Host"] = host_header
- started = time.perf_counter()
- conn = conn_cls(parsed.hostname, port, timeout=timeout)
- try:
- conn.request("GET", path, headers=headers)
- response = conn.getresponse()
- body = response.read()
- elapsed_ms = (time.perf_counter() - started) * 1000.0
- return response.status, body, elapsed_ms
- finally:
- conn.close()
-
-
-def measure_backend(backend: str, base_url: str, host_header: str, targets: list[Target], warmups: int, samples: int, timeout: float) -> list[Measurement]:
- results: list[Measurement] = []
- for target in targets:
- for _ in range(warmups):
- request_once(base_url, host_header, target.url, timeout)
- durations: list[float] = []
- status = 0
- ok = True
- note = ""
- for _ in range(samples):
- status, body, elapsed_ms = request_once(base_url, host_header, target.url, timeout)
- durations.append(elapsed_ms)
- text = body.decode("utf-8", errors="replace")
- if status != 200:
- ok = False
- note = f"HTTP {status}"
- elif target.expected and target.expected not in text:
- ok = False
- note = f"missing marker {target.expected!r}"
- results.append(Measurement(
- backend=backend,
- target=target.name,
- url=target.url,
- ok=ok,
- status=status,
- samples_ms=durations,
- median_ms=statistics.median(durations),
- mean_ms=statistics.fmean(durations),
- min_ms=min(durations),
- max_ms=max(durations),
- note=note,
- ))
- return results
-
-
-def compare(results: list[Measurement], baseline_label: str) -> list[str]:
- baseline = {r.target: r for r in results if r.backend == baseline_label}
- lines = ["| target | backend | median ms | mean ms | budget | status |", "|---|---:|---:|---:|---|---|"]
- for result in results:
- budget = "baseline" if result.backend == baseline_label else "n/a"
- status = "PASS" if result.ok else "FAIL"
- if result.backend != baseline_label and result.target in baseline:
- limit = baseline[result.target].median_ms * 2.0
- budget = f"≤ {limit:.1f} ms"
- if result.median_ms > limit:
- status = "FAIL"
- lines.append(f"| {result.target} | {result.backend} | {result.median_ms:.1f} | {result.mean_ms:.1f} | {budget} | {status} {result.note} |")
- return lines
-
-
-def build_targets() -> list[Target]:
- return [
- Target("template-heavy-doc", "/doc/singlepage.uce", "UCE API"),
- Target("sqlite-page", "/demo/sqlite.uce", "SQLite"),
- Target("component-heavy-starter", "/examples/uce-starter/?dashboard", "Dashboard"),
- ]
-
-
-def main() -> int:
- parser = argparse.ArgumentParser(description="UCE wasm-runtime HTTP benchmark harness")
- parser.add_argument("--base-url", "--native-base-url", dest="base_url", default="http://localhost:80", help="runtime base URL (legacy alias --native-base-url is accepted)")
- parser.add_argument("--backend-label", default="wasm", help="label for this run's measurements")
- parser.add_argument("--compare-baseline-json", "--compare-native-json", dest="compare_baseline_json", default="", help="optional prior benchmark.json for budget comparison")
- parser.add_argument("--baseline-label", default="native", help="backend label in the prior JSON to use as the budget baseline")
- parser.add_argument("--host-header", default="uce.openfu.com")
- parser.add_argument("--warmups", type=int, default=2)
- parser.add_argument("--samples", type=int, default=20)
- parser.add_argument("--timeout", type=float, default=10.0)
- parser.add_argument("--out-dir", default="/tmp/uce/wasm-benchmark")
- args = parser.parse_args()
-
- targets = build_targets()
- results: list[Measurement] = []
- if args.compare_baseline_json:
- for row in json.loads(Path(args.compare_baseline_json).read_text()):
- row.setdefault("backend", args.baseline_label)
- results.append(Measurement(**row))
- results.extend(measure_backend(args.backend_label, args.base_url, args.host_header, targets, args.warmups, args.samples, args.timeout))
-
- out_dir = Path(args.out_dir)
- out_dir.mkdir(parents=True, exist_ok=True)
- (out_dir / "benchmark.json").write_text(json.dumps([asdict(r) for r in results], indent=2) + "\n")
- md_lines = ["# UCE wasm benchmark report", "", *compare(results, args.baseline_label), ""]
- (out_dir / "benchmark.md").write_text("\n".join(md_lines) + "\n")
- print("\n".join(md_lines))
- print(f"wrote {out_dir / 'benchmark.json'} and {out_dir / 'benchmark.md'}")
- return 0 if all(r.ok for r in results) else 1
-
-
-if __name__ == "__main__":
- raise SystemExit(main())
diff --git a/tests/wasm_site_audit.py b/tests/wasm_site_audit.py
deleted file mode 100755
index 9392a06..0000000
--- a/tests/wasm_site_audit.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python3
-"""Phase 5 audit for cross-request/static state risks in site code files."""
-from __future__ import annotations
-
-import argparse
-import json
-from dataclasses import asdict, dataclass
-from pathlib import Path
-
-ROOT = Path(__file__).resolve().parents[1]
-SITE = ROOT / "site"
-
-PATTERNS = [
- ("static local/global", "static "),
- ("once hook", "ONCE("),
- ("init hook", "INIT("),
- ("background task", "task_"),
-]
-
-SKIP_PARTS = {".git", "tmp", "work", "bin", "pkg", "__pycache__"}
-CODE_SUFFIXES = {".uce", ".h"}
-DOC_SUFFIXES = {".txt"}
-
-
-@dataclass
-class Finding:
- path: str
- line: int
- kind: str
- severity: str
- text: str
- note: str
-
-
-def iter_files(include_doc_text: bool) -> list[Path]:
- suffixes = CODE_SUFFIXES | (DOC_SUFFIXES if include_doc_text else set())
- result: list[Path] = []
- for path in SITE.rglob("*"):
- if not path.is_file():
- continue
- if any(part in SKIP_PARTS for part in path.parts):
- continue
- if path.suffix not in suffixes:
- continue
- result.append(path)
- return sorted(result)
-
-
-def note_for(kind: str, severity: str) -> str:
- if severity == "documentation":
- return "Documentation prose mention; useful for terminology review, not a direct static-state migration finding."
- if kind in {"once hook", "init hook"}:
- return "Audit behavior under per-request wasm workspaces; ONCE/INIT may need host-side cache semantics if used for cross-request state."
- if kind == "background task":
- return "Task APIs cross request lifetimes; verify they are host handles, not guest statics."
- return "Check whether state is request-local, immutable, or intentionally persistent; unit statics reset per wasm workspace."
-
-
-def severity_for(path: Path) -> str:
- return "documentation" if path.suffix in DOC_SUFFIXES else "code"
-
-
-def scan(include_doc_text: bool) -> list[Finding]:
- findings: list[Finding] = []
- for path in iter_files(include_doc_text):
- try:
- lines = path.read_text(encoding="utf-8").splitlines()
- except UnicodeDecodeError:
- continue
- severity = severity_for(path)
- for lineno, line in enumerate(lines, 1):
- stripped = line.strip()
- if severity == "code" and (stripped.startswith("//") or stripped.startswith("# ")):
- continue
- for kind, needle in PATTERNS:
- if needle in line:
- findings.append(Finding(
- path=str(path.relative_to(ROOT)),
- line=lineno,
- kind=kind,
- severity=severity,
- text=stripped[:180],
- note=note_for(kind, severity),
- ))
- return findings
-
-
-def write_reports(findings: list[Finding], out_dir: Path) -> None:
- out_dir.mkdir(parents=True, exist_ok=True)
- (out_dir / "site-static-audit.json").write_text(json.dumps([asdict(f) for f in findings], indent=2) + "\n")
- lines = ["# Phase 5 site static-state audit", ""]
- if not findings:
- lines.append("No candidate cross-request/static-state patterns found.")
- else:
- code_count = sum(1 for f in findings if f.severity == "code")
- doc_count = sum(1 for f in findings if f.severity == "documentation")
- lines.append(f"Findings: {code_count} code, {doc_count} documentation prose.")
- lines.append("")
- lines.extend(["| file | line | severity | kind | code | note |", "|---|---:|---|---|---|---|"])
- for f in findings:
- code = f.text.replace("|", "\\|")
- note = f.note.replace("|", "\\|")
- lines.append(f"| {f.path} | {f.line} | {f.severity} | {f.kind} | `{code}` | {note} |")
- (out_dir / "site-static-audit.md").write_text("\n".join(lines) + "\n")
-
-
-def main() -> int:
- parser = argparse.ArgumentParser(description="Phase 5 site static/cross-request-state audit")
- parser.add_argument("--include-doc-text", action="store_true", help="include site/doc .txt prose as documentation-severity findings")
- parser.add_argument("--out-dir", default="/tmp/uce/wasm-phase5")
- args = parser.parse_args()
- out_dir = Path(args.out_dir)
- findings = scan(args.include_doc_text)
- write_reports(findings, out_dir)
- print(f"Found {len(findings)} candidate static/cross-request patterns")
- print(f"wrote {out_dir / 'site-static-audit.json'} and {out_dir / 'site-static-audit.md'}")
- return 0
-
-
-if __name__ == "__main__":
- raise SystemExit(main())