Source: https://docs.any.org/programs/testing.html # Testing Because a program touches the world only through effects, testing it means faking one function. The kernel-fidelity harness imports the **real** guest kernel host-side and stubs the single host call, so tests exercise the actual curated builtins, import allowlist, span machinery and `use()` loading — not plain CPython. The examples assume a development checkout of anybao with its test dependencies installed. ## The harness `tests/kernelenv.py` in the anybao repo exposes one entry point: ```python from tests.kernelenv import load_kernel def test_remind_posts_to_chat(): sent = [] class FakeAny: def chat_send(self, space, chat_id, body): sent.append((space, chat_id, body)) return {"versionId": "v1", "changeId": "c1", "recordIds": ["m1"]} app = load_kernel(any_client=FakeAny()) remind = app.use("remind@v1") remind.main({"space": "bao", "chatId": "chat1", "text": "stand up"}) assert sent[0][2]["text"] == "⏰ Reminder: stand up" assert sent[0][2]["agent"] == {"name": "bao", "done": True} ``` `load_kernel(effect=None, any_client=None, llm_chat=None, programs_dir=None, module_source=None, shell=None)` returns a fresh kernel app module; `app.use("name@vN")` loads real sources from `repos/_agent/programs` with the runtime's own resolution order (`.py`, then `/program.py`). | Parameter | What it fakes | | --- | --- | | `any_client` | `use("any@v1")` becomes a shim whose every method call crosses the boundary as `test.any` and dispatches to your object; exceptions become guest-catchable `AnyError` (with `status`/`code` when the fake sets them) | | `llm_chat` | `use("llm@v1").chat(...)` crosses as `test.llm` and calls your function | | `effect(name, payload)` | everything else — `http.*`, `config.get`, `time.now`, … | | `programs_dir` | another repo's `programs/` (the connectors repo tests its own) | | `module_source(spec)` | consulted first; return source text or `{"source", "marker"}` — bump the marker to model an edited program and exercise the module cache | | `shell` | what `runtime.get("shell")` answers; set it to model a runtime built with the `shell` feature, so `sh` / `fs` are bound in cells | Alias-qualified specs (`agent:any@v1`) shim identically. `span.begin/end` are absorbed. An unknown effect raises loudly, so a test cannot silently pass over a call it never expected. > **Why it matters.** A stray `import contextlib` that the allowlist rejects fails in the test exactly as it would in the wasm guest. The only thing your test replaces is the boundary — the same seam replay uses. ## Faking HTTP Connectors are tested by recording live replies once and replaying them from fixtures. The shape is just the effect fake: ```python import json from pathlib import Path FIX = {"login": "octocat", "id": 1, "name": "The Octocat", "html_url": "https://github.com/octocat"} def fake_effect(name, payload): if name == "http.get": return {"status": 200, "headers": {}, "body": json.dumps(FIX), "url": payload["url"]} if name == "time.now": return {"epoch": 1_700_000_000.0, "offset_s": 0} raise AssertionError(f"unexpected effect {name}") app = load_kernel(effect=fake_effect, programs_dir=Path("repos/_connectors/programs")) gh = app.use("github@v1") assert gh.whoami()["login"] == "octocat" ``` Fixtures under `tests/fixtures/*.jsonl` are JSONL — one record per line is the parse contract; view them with `jq .` and never reformat the file. ## One-shot runs For an end-to-end check against a real server, run the program from disk with the local resolver, or the deployed copy with the space resolver: ```sh anyrt run remind@v1 --args '{"space":"bao","chatId":"…","text":"hi"}' anyrt run remind@v1 --from-space bao --args '{…}' # the deployed source anyrt run mytool@v1 --secrets-file ./.connectors.env # seeds for this run only ``` Both print `{status, value, error, traceRef, durationMs, fuelUsed}` and write a trace. A `--from-space` run also reads and writes that space's agent config the way serve does. A running `anyrt serve` offers the same through its loopback control API — `POST http://127.0.0.1:7010/run` with `{program, args?}` for a deployed program or `{source, args?, program?}` for inline text (the source is served from the request body; its `use()` imports still resolve through the space). ## Golden replay A recorded trace is a test asset. In strict mode the broker consumes the log as a cursor: the next effect call must match the next record's effect and key, cell and span records are checkpoints, and any drift is a divergence error naming the expected record. Record once, assert forever — no server, no keys. The mechanics and the loose `mock` variant are on [Traces and replay](https://docs.any.org/programs/traces-and-replay.md.txt). ## Running the suite ```sh nix develop # canonical env uv sync make kernel # componentized CPython → bin/kernel.wasm make runtime # runtime/target/release/anyrt uv run pytest # guest-module + wire tests; runtime e2e skips without kernel + binary make test # kernel + cargo test + pytest make lint # ruff + clippy -D warnings + fmt --check ``` Program tests need no kernel build — the harness runs the guest module host-side. The runtime e2e tests need `make kernel` and `make runtime` and skip otherwise.