Bound every wait that could last for ever
Nine orphaned test processes were found still running from the day before, three of them spinning on a core each for twenty hours. The code they ran is several changes old and the mesh test passes twenty times over now, so the wedge itself is gone — but nothing in the way it was waited on was bounded, which is why a wedge lasted a day instead of failing a run. The harness enforced its deadline only between probes. A probe that never returned — one call into a wedged runtime, which is exactly what a status request is — waited for ever inside the deadline it was supposed to obey. The probe is now bounded too, so the same wedge fails the test in thirty seconds. Shutdown claimed to be bounded and was not. The plugins had a grace period; the network runtimes, the accept loop, the plugin request loop and the endpoint close did not, and a peer that stops reading is enough to hold any of them open. Each now gets a grace period and is aborted after it. The overlay packet loop was not stopped at all: it ends when the device reports end of stream, which a live interface never does, so it outlived the interface it was reading. And a plugin's grace period abandoned the future without stopping the task behind it, so the helper is public and `wg-quic` uses it on its own runtime. The local control socket was unbounded in both directions. A wedged agent left `tsunagi status` hanging with nothing on screen and no way out but Ctrl-C; it now says the agent did not answer, after five seconds, and falls back to the state store as it already did for a socket that refuses a connection. On the serving side, a connection that sends no request no longer holds a task open. Tests cover the mechanism — a task that stops on its own is not aborted, one that ignores the grace is cut off and drops what it held — and both sides of the change in behaviour: a probe that never answers fails its deadline, and a silent agent is reported rather than waited out. Also: the binary opts out of rustdoc, since it shares a name with the library and `cargo doc` cannot put both in one directory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+6
-3
@@ -16,9 +16,12 @@ rights and no changes to OS network settings: endpoints bind `127.0.0.1:0` and
|
||||
disabled, and net-report probing is reduced to its minimum.
|
||||
|
||||
Synchronisation is always "wait for a specific event or condition under one
|
||||
overall deadline" (`wait_event`, `wait_until`, 30 s). `settle()` exists only
|
||||
for asserting that something did *not* happen. Ports are dynamic and
|
||||
directories are isolated, so tests run in parallel.
|
||||
overall deadline" (`wait_event`, `wait_until`, 30 s). The deadline covers the
|
||||
probe as well as the gaps between probes: a call into a wedged agent that
|
||||
never answers fails the test rather than hanging the process, which is the
|
||||
difference between a red run and a test binary still burning a core the next
|
||||
day. `settle()` exists only for asserting that something did *not* happen.
|
||||
Ports are dynamic and directories are isolated, so tests run in parallel.
|
||||
|
||||
Several library instances in one process is exactly that. It is **not** a test
|
||||
of several system processes, and is not presented as one.
|
||||
|
||||
Reference in New Issue
Block a user