diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4df452a8..778fd167 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -153,6 +153,32 @@ jobs: (cd clients/mcp && npm install --silent && npx tsc) ORLY_URL=ws://127.0.0.1:8082/ node clients/mcp/smoke/smoke.mjs + # The MCP smoke writes, but it exits as soon as each write answers. The + # v0.1.0 arm64 image passed it while segfaulting just AFTER the first + # write through a POV (#578), so a smoke that never looks back cannot + # see that shape. Write through every POV flavour, five fresh POVs + # each, wait, and assert the server is still the same running process. + - name: Server survives writes through every POV flavour + run: | + pip3 install --break-system-packages --quiet websocket-client + PYTHONPATH=clients/python python3 - <<'PY' + import orly + c = orly.connect("ws://127.0.0.1:8082/") + c.new_session() + c.install("sample", 1) + n = 0 + for _ in range(5): + for kind in ("safe shared", "safe private", "fast shared", "fast private"): + n += 1 + pov = c.send(f"new {kind} pov;") + c.call(pov, "sample", "write_val", {"n": 1000 + n, "x": n}) + print(f"{n} writes answered") + PY + sleep 5 + state=$(docker inspect orly --format '{{.State.Status}} exit={{.State.ExitCode}} restarts={{.RestartCount}}') + echo "container after writes: $state" + test "$state" = "running exit=0 restarts=0" + # The image also claims in-container package compiles (orlyc + g++ + # ORLY_SRC_ROOT). Gate that claim: compile a from-scratch user package # to a loadable .so inside the running container. (This caught a diff --git a/changelog.d/578-image-survives-writes.md b/changelog.d/578-image-survives-writes.md new file mode 100644 index 00000000..d290e627 --- /dev/null +++ b/changelog.d/578-image-survives-writes.md @@ -0,0 +1 @@ +- **Added**: the docker workflow now checks that the server *survives* writes, not just that writes answer. After the MCP smoke, it writes through all four POV flavours (five fresh POVs each) against the running container, waits, and asserts the container is still running with exit 0. The `v0.1.0` arm64 image passed every existing smoke while segfaulting just after the first write (#578). Run locally against the published images, the new step fails on `v0.1.0` arm64 (exit 139) and passes on `v0.1.1`.