Follow-up to #127 — the I/O chaos foundation (EvilPeer, the io/ topic, transport×logic crossing, the chaos event log, the _FUZZ CI build) landed in #128. Remaining work tracked here.
1. Write-path / backpressure coverage
The harness currently exercises only the client read path (downloads from peer). The write path is untested:
never-read EvilPeer toxic — the peer accepts the connection and never reads.
- a client
upload step — fills SO_SNDBUF, so fwrite() blocks waiting for the socket to become writable.
- exercises the reactor's writable-wait and partial-write handling.
2. Real RST (in-process, no external tool)
EvilPeer currently closes with a graceful FIN. Add a true RST via ext/sockets — socket_set_option(SO_LINGER, {l_onoff:1, l_linger:0}) then close. Lets the suite cover the ECONNRESET path, which is distinct reactor code from a clean EOF.
3. Forked-peer mode
A ... as forked peer step that runs the EvilPeer in a separate process (real OS boundary, real TCP stack) instead of an in-process coroutine. The harness was designed for both modes (coroutine default + forked via a dedicated step).
4. cancel-during-download
A killer coroutine cancels the client mid-I/O — cancellation racing live reads/writes is exactly where reactor use-after-free / leak bugs live. Adds a logic-axis alternative to combined_chaos.feature.
5. Turn-key failure freeze
Make a chaos failure reproducible as a deterministic, non-chaos regression test ("every found bug becomes a fixed scenario"):
- log
TRUE_ASYNC_SCHED + CHAOS_GEN_SEED in the chaos event log;
- emit a machine-readable replay descriptor on failure (feature, scenario, mutation combo, seeds);
- a
_harness/freeze.php generator that turns a descriptor into a frozen .phpt — mutation flattened to the failing combo, seeds pinned via the phpt --ENV-- section.
6. Optional external-tool layer (stretch)
Toxiproxy in front of the EvilPeer for transport toxics PHP cannot do precisely (bandwidth throttling, runtime-controlled toxics); tc netem for packet loss/reorder/duplication. Opt-in / nightly only — they break per-test determinism and need external setup, so they must not gate per-PR CI.
Reference
FUZZ_TESTING.md Layers 2–4. Related: #127, #128, #125, #102.
Follow-up to #127 — the I/O chaos foundation (EvilPeer, the
io/topic, transport×logic crossing, the chaos event log, the_FUZZCI build) landed in #128. Remaining work tracked here.1. Write-path / backpressure coverage
The harness currently exercises only the client read path (
downloads from peer). The write path is untested:never-readEvilPeer toxic — the peer accepts the connection and never reads.uploadstep — fillsSO_SNDBUF, sofwrite()blocks waiting for the socket to become writable.2. Real RST (in-process, no external tool)
EvilPeercurrently closes with a gracefulFIN. Add a trueRSTviaext/sockets—socket_set_option(SO_LINGER, {l_onoff:1, l_linger:0})then close. Lets the suite cover theECONNRESETpath, which is distinct reactor code from a clean EOF.3. Forked-peer mode
A
... as forked peerstep that runs the EvilPeer in a separate process (real OS boundary, real TCP stack) instead of an in-process coroutine. The harness was designed for both modes (coroutine default + forked via a dedicated step).4. cancel-during-download
A killer coroutine cancels the client mid-I/O — cancellation racing live reads/writes is exactly where reactor use-after-free / leak bugs live. Adds a logic-axis alternative to
combined_chaos.feature.5. Turn-key failure freeze
Make a chaos failure reproducible as a deterministic, non-chaos regression test ("every found bug becomes a fixed scenario"):
TRUE_ASYNC_SCHED+CHAOS_GEN_SEEDin the chaos event log;_harness/freeze.phpgenerator that turns a descriptor into a frozen.phpt— mutation flattened to the failing combo, seeds pinned via the phpt--ENV--section.6. Optional external-tool layer (stretch)
Toxiproxy in front of the EvilPeer for transport toxics PHP cannot do precisely (bandwidth throttling, runtime-controlled toxics);
tc netemfor packet loss/reorder/duplication. Opt-in / nightly only — they break per-test determinism and need external setup, so they must not gate per-PR CI.Reference
FUZZ_TESTING.mdLayers 2–4. Related: #127, #128, #125, #102.