一键导入
protocol-testing
How to write deterministic, harness-based H3 engine tests using MockHarness — no real sockets, no timers, script-driven and byte-exact.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
How to write deterministic, harness-based H3 engine tests using MockHarness — no real sockets, no timers, script-driven and byte-exact.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | Protocol Testing |
| description | How to write deterministic, harness-based H3 engine tests using MockHarness — no real sockets, no timers, script-driven and byte-exact. |
| applies_to | ["claude","codex"] |
| triggers | ["new H3 behavior","new frame type","engine state change","any test addition"] |
Defines how to write deterministic, harness-based tests for H3 engine behavior. No real sockets, no real timers — every byte and every event is scripted.
MockHarness)Location: crates/istok-h3/src/mock/
The harness is script-driven:
MockHarness with scripted incoming stream events.// Minimal test structure
let harness = MockHarness::new(vec![
// scripted inbound events
StreamEvent::Data { stream_id: 0, data: vec![0x00], fin: false },
]);
let writes = harness.run_until_idle();
assert_eq!(writes[0].data, expected_headers_frame);
assert!(!writes[0].fin);
assert_eq!(writes[1].data, expected_data_frame);
assert!(writes[1].fin);
Keep test payloads small and recognizable:
[0x00] (one-byte placeholder, no QPACK encoding yet)[0x01]Avoid random or generated data in unit tests — use fuzz targets for that.
Every codec (varint, frame) needs three test classes:
| Class | What to test |
|---|---|
| Roundtrip | encode(x) → decode(…) == x |
| Malformed rejection | Known-bad byte sequences must return an error, not panic |
| Boundary conditions | Max varint value, empty payload, max frame length |
Fuzz targets live in crates/istok-core/fuzz/fuzz_targets/ and are built with
cargo fuzz (nightly required). Currently covering:
fuzz_varint_decode — varint::decodefuzz_frame_decode — h3_frame::decode_frame_headerTo run locally (+nightly is required — cargo-fuzz uses -Z flags):
cd crates/istok-core
cargo +nightly fuzz run fuzz_varint_decode
cargo +nightly fuzz run fuzz_frame_decode
Runs indefinitely until Ctrl+C. Corpus is saved in fuzz/corpus/ and seeds future runs.
For a time-bounded run (CI-style):
ASAN_OPTIONS="detect_odr_violation=0:quarantine_size_mb=1:malloc_context_size=0" \
cargo +nightly fuzz run fuzz_varint_decode -- -max_total_time=30 -max_len=8 -rss_limit_mb=256
Use max_len=8 for varint (QUIC varint max is 8 bytes) and max_len=16 for frame
decode (type varint + length varint = up to 16 bytes).
Rule: crashes are bugs. The engine must never panic on arbitrary input.
fuzz_targets/<name>.rs file (see existing targets for the one-liner pattern).[[bin]] entry to crates/istok-core/fuzz/Cargo.toml.Cargo.toml must have [workspace] at the top — without it, Cargo
treats the fuzz crate as part of the parent workspace and cargo fuzz fails.
This is already present; do not remove it when editing the file.tokio::time::sleep or tokio::net in unit tests — use the mock harness.fin explicitly.How to scope, implement, and close milestones — vertical slices, DoD checklists, scaffold rules, and sequencing constraints.
Compatibility rules for keeping istok-core and istok-transport free of std — allowed crates, feature gates, and forbidden patterns.
Coding conventions for all Istok crates — error handling, panic-free library code, feature gates, and style rules.