﻿# SSE property tests: one event stream under any byte partition

Test an SSE parser with randomized byte boundaries, stable event invariants, Unicode, CRLF cases, minimal counterexamples and bounded execution.

Author: Retrivium team
Updated: 2026-11-01
Canonical URL: https://retrivium.ai/journal/provider-sse-fragmentation-property-tests/
Language: en

## Test a property rather than a convenient example

An ordinary test passes complete data lines to a parser and confirms one correct response. A real network can split a line inside a character or combine several events in one read. A property test changes byte arrival boundaries while preserving the original stream. Its invariant is that parsed events, their order and the final state remain identical across selected partitions. This is stronger than a collection of conveniently hand split chunks, but does not prove correctness for every damaged input. Start with an independently expected result; otherwise two identically broken implementations can repeatedly confirm each other.

## Build a canonical byte corpus

Include a comment, multiple data lines in one event, a blank event separator and text containing multibyte characters. The [SSE specification](https://html.spec.whatwg.org/multipage/server-sent-events.html) defines line processing and event construction; an embedded JSON payload separately follows [RFC 8259](https://www.rfc-editor.org/rfc/rfc8259.html). Test those layers independently. A JSON object is not a network packet, and an event delimiter need not coincide with a read boundary. The manifest should contain exact source bytes and expected events after valid SSE normalization. Put malformed JSON in another case with an explicit application error expectation, rather than mixing it with valid transport fragmentation.

## Generate partitions within a budget

For a short sample, enumerate single cuts and then add reproducible randomized partitions. Dedicated cases place boundaries within a UTF-8 sequence, between CR and LF, inside a field name and immediately before an event separator. Limit the number of variants beforehand, because exhaustive enumeration of all partitions soon becomes impractical. [TextDecoder.decode documentation](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/decode) explains streaming decoding: state must survive between reads and be finalized correctly at the end. Save the random seed, fragment sizes and source fixture. Together these reproduce the failure without retaining real user content or an entire network capture.

## Shrink counterexamples carefully

When a discrepancy appears, reduce the number of cuts and remove unnecessary events while preserving the failure. Next, shorten the payload while retaining any essential multibyte characters. Arbitrary byte deletion can turn valid input into a different error class, so a shrinker must respect the property's preconditions. A minimal example might reveal character loss only when a cut precedes the last UTF-8 byte. The report should include expected and observed events, the last accepted offset and the stopping reason. Do not immediately patch the decoder based on a damaged displayed string: first exclude double normalization or fragment loss inside the test harness.

## Mutate invalid streams separately

After fragmentation checks, add truncated UTF-8, unfinished events and invalid JSON. Define the rejection policy first; equality with a valid stream is no longer the objective. Limit event size, memory and execution time so the generator does not become an unbounded workload source. See the [streaming client guide](/journal/openrouter-streaming-client/) and [vLLM stream test](/journal/vllm-openai-streaming-test/). The result describes one parser's behavior under the examined partitions and mutations. It does not establish correct finish reasons, usage, request retries or intermediary proxy behavior. Those properties need separate integration scenarios with their own observable outcomes.
