Skip to content

Chaos test coverage gaps: Layer 1 IO + UDP/TLS/DNS/signal/watcher #138

@EdmondDantes

Description

@EdmondDantes

Follow-up to #125 / #127 / #129 / #136. After those, fuzzy-tests/ covers 167/167 of the documented API and most Layer 2 (protocol) faults — but several reactor paths still have no chaos coverage and only happy-path .phpt tests. This issue tracks the remaining gaps.

Layer 1 IO (carried over from fuzzy-tests/IO_PLAN.md)

High priority — race surface where UAF / leak is most likely:

  • io/cancel_during_connect.feature — TCP connect to a blackhole (192.0.2.1:81, RFC 5737), killer cancels mid-wait. Reactor must release the connect request without UAF.
  • io/stream_close_during_read.feature — coroutine A blocked in fread, coroutine B fcloses the same handle. Race on the reactor request list — orthogonal to direct cancel.

Medium — correctness invariants:

  • io/concurrent_readers.feature — N readers on one pipe, cancel half. Invariant received_total + recv_failed_total == N.
  • io/stream_select_chaos.featurestream_select over a set; data arrives mid-select; cancel the selecting coroutine. Not exercised by anything beyond fixed-output .phpt.
  • io/connect_with_timeout.feature — TCP connect to unreachable with explicit timeout; no leaked watcher.

Low — file/IO consistency:

  • io/file_concurrent_writes.feature — 10 coroutines writing distinct payloads to one file. Chaos regression for the 083 / php_stdiop_write fix (I/O chaos follow-up: write-path toxics, real RST, forked peer, failure-freeze #129); right now only the single fixed-output tests/io/083 pins that.
  • io/dns_slow.feature — async DNS resolver under slow / timing-out upstream; resolver must stay interruptible.
  • io/evil_peer_garbage.feature — well-formed framing with garbage payloads; client reports parse error, no crash.

Other reactor surfaces with no chaos coverage

  • UDPtests/socket/028–030 happy-path only. Reactor UDP path never exercised under a randomised scheduler.
  • SSL/TLS — handshake under Toxiproxy slicer / latency / reset. Today only tests/stream/025–027 async-TLS happy-path.
  • FileSystemWatcher — event stream + cancel/close race. Class is in COVERAGE (3/3) but no chaos feature.
  • Async\signal() regression (signal(): delivery is non-deterministic in multi-thread programs #109) — fix landed (zend_signal_activate / deactivate skip when reactor enabled). No chaos regression test; the original bug was a multi-thread race on concurrent signal() + cancel.
  • Zombie-timer loop (Zombie coroutine in a long delay() keeps the event loop alive until the timer expires #132) — currently a design question with no failing test. A disposeAfterTimeout scope with a child parked in a long delay() would pin the behaviour and become the regression for the eventual fix.

DB / protocol follow-ups (came up during #136)

  • pdo_pgsql LISTEN/NOTIFY + COPY IN/OUT under reset_peer. Today only synchronous COPY is hit.
  • mysqlnd E_WARNING on pool dropped-connectFINDINGS.md flags it as a loose end (raw warning leaks under ERRMODE_EXCEPTION in the pool path only). A failing-tagged scenario would close it when the fix lands.
  • Pool max_size + Toxiproxy reset_peer — race between retiring a broken connection and a concurrent acquire under the limit. Today pdo_pool_max_size_enforced.phpt is happy-path only.
  • Prepared-statement cache (PDO MySQL pool, 050–054) — LRU eviction racing cancel mid-prepare; current 050–054 are happy-path.

Suggested first pass

  1. io/stream_close_during_read.feature + io/concurrent_readers.feature — directly target the structural class that produced I/O chaos follow-up: write-path toxics, real RST, forked peer, failure-freeze #129 (broadcast event on the handle).
  2. io/cancel_during_connect.feature + io/connect_with_timeout.feature — connect-watcher UAF/leak is not exercised by anything today.
  3. io/file_concurrent_writes.feature — chaos regression for the 083 fix.
  4. signal_chaos.feature — the only php-src fix shipped without a chaos backstop.

Metadata

Metadata

Assignees

Labels

testsTest coverage task

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions