Skip to content

blackbull.fault_injection.scenario_h2

blackbull.fault_injection.scenario_h2

HTTP/2 server-side fault scenarios.

WaitForClientFrame match dictionaries accept type, stream_id, flags_set flags_unset and error_code. JSON Lines supports only ROUND_TRIP_FRAME_CLASSES for SendFrame; use SendRawBytes for other or malformed frame encodings.

Abort dataclass

Hard-close the connection (transport.abort → RST on Linux).

CloseGracefully dataclass

Send a GOAWAY then close cleanly.

Subsequent scenario steps short-circuit (this is a terminator just like Abort). error_code is one of the ErrorCodes values; last_stream_id advertises the last stream the server is willing to process — pass 0 to refuse all client streams, or the highest accepted stream ID otherwise.

ExpectClientFrame dataclass

Consume exactly one frame and record whether it matched; never filter.

HalfClose dataclass

Shut down the sending direction only (FIN), keep reading.

Not terminal — later steps still run, which is the whole point. Abort is not a substitute: it sends RST, discarding what is buffered and leaving nothing to read.

ScenarioH2 dataclass

Sequence of steps a programmable H2 server walks per connection.

Two control knobs sit outside the step list because they apply to the whole connection, not to one step:

  • send_preface: whether the server sends the standard SERVER_PREFACE_BYTES + initial SETTINGS at handshake time. Most catalogue scenarios want this (real H2 clients require it before proceeding); set False to exercise client behaviour against a server that skips the handshake.
  • initial_settings: tuple of (setting_id, value) pairs the server advertises in its initial SETTINGS frame. Used by the "exhausted window" and "illegal SETTINGS" catalogue entries to inject a hostile starting state before the first step runs.

ScenarioH2Result dataclass

Outcome of one ScenarioH2 run.

Mirrors ScenarioResult's shape so callers can write uniform pytest assertions across protocols.

SendFrame dataclass

Emit a typed frame; use SendRawBytes for unsupported or malformed encodings.

A declared_length override changes only the header, not the emitted payload.

SendRawBytes dataclass

Push arbitrary bytes onto the connection.

Escape hatch for malformed frames (illegal type byte, length exceeding SETTINGS_MAX_FRAME_SIZE, etc.) that the typed SendFrame path will not produce.

byte_interval > 0 transmits one byte at a time with that delay — useful for stalled-handshake patterns where the client is expected to enforce a preface-completion timeout.

Sleep dataclass

Idle for duration seconds without reading or writing.

StepOpH2

Bases: str, Enum

Tag used by the JSON serialiser.

WaitForClientFrame dataclass

Consume until a frame matches, skipping nonmatches.

Timeout records a miss and proceeds to the next step.

frame_matches(frame, match)

Return True iff frame satisfies every key in match.

Recognised keys: type, stream_id, flags_set, flags_unset, error_code. Unknown keys fail closed — an unrecognised match key is almost certainly a typo in a catalogue entry, and silently matching on a missing key would hide the bug.

error_code is what turns "a GOAWAY arrived" into "the peer rejected this for that reason", and a frame carrying no error code never matches it. Both HTTP/2 roles share this function, so the key is available to the broken server and the broken client alike.

require_canonical(frame)

Refuse a frame the record cannot describe.

The record carries fields and the executor re-encodes from them, so a frame whose type, length, payload or stream identifier they cannot reproduce would replay as something other than it is. Those octets go through SendRawBytes instead.

scenario_from_json(src)

Parse JSON Lines back to a ScenarioH2.

scenario_to_json(scenario)

Serialize JSON Lines; the first HEADER carries send_preface and initial_settings.