Skip to content

blackbull.fault_injection.catalogue

blackbull.fault_injection.catalogue

Canned-misbehaviour catalogue for HTTP/2 client testing.

Each function returns a :class:~blackbull.fault_injection.ScenarioH2 that drives :class:~blackbull.fault_injection.H2FaultServer through one well-known misbehaviour pattern. Catalogue scenarios are deliberately small — one named pathology per scenario — so test suites can stack parametrize over the catalogue to assert client-side resilience across the four spec-grade categories the roadmap calls out:

  • Half-closed streams — server stops mid-stream without END_STREAM / RST_STREAM; client must time out or give up.
  • Exhausted flow-control windows — server advertises a zero-byte window then refuses to grant WINDOW_UPDATE; client must respect backpressure rather than spin.
  • Custom / illegal SETTINGS — server advertises a value below the RFC-mandated minimum or an unknown setting id; client must treat as PROTOCOL_ERROR per RFC 9113 §6.5.2.
  • Weird frame sequences — server emits frames in an out-of-order or unfinished pattern (HEADERS without END_HEADERS and no CONTINUATION, DATA on stream 0); client must close the connection with PROTOCOL_ERROR.

Catalogue entries are pure builders. They allocate nothing at import time, take no I/O, and the returned scenario is immutable; two consecutive calls to the same builder are interchangeable.

exhausted_window_zero_initial()

Server advertises SETTINGS_INITIAL_WINDOW_SIZE = 0.

RFC 9113 §6.9.2 — a zero initial window means the client cannot send any DATA bytes until the server grants WINDOW_UPDATE. This scenario never grants WINDOW_UPDATE, so a client trying to send a request body must respect the zero window rather than spin or flood the wire.

half_closed_stream_no_data()

Server sends HEADERS without END_STREAM, then nothing.

A real H2 server would follow HEADERS with DATA + END_STREAM. This scenario stops mid-stream — flags END_HEADERS but not END_STREAM, then sleeps until the client gives up. Clients must time out or RST_STREAM rather than block forever.

headers_continuation_dropped()

Server sends HEADERS without END_HEADERS, then no CONTINUATION.

RFC 9113 §6.2 / §6.10 — HEADERS without END_HEADERS MUST be followed by CONTINUATION frames for the same stream until one sets END_HEADERS. This scenario sends the partial HEADERS and then nothing, leaving the stream in an unresolved header-block state. Clients must enforce a timeout (or PROTOCOL_ERROR on intervening frame for a different stream) rather than hang indefinitely.

settings_max_frame_size_below_minimum()

Server advertises SETTINGS_MAX_FRAME_SIZE below the legal floor.

RFC 9113 §6.5.2 — SETTINGS_MAX_FRAME_SIZE values below 16_384 are a PROTOCOL_ERROR. The client must close the connection with PROTOCOL_ERROR rather than try to honour the illegal value (e.g. splitting frames into 1-byte chunks).