test(proto): add codec property tests #117

Merged
Lochnair merged 1 commits from test/proto-properties into main 2026-08-19 17:48:25 +00:00
Lochnair commented 2026-08-19 17:45:54 +00:00 (Migrated from github.com)

Summary

  • add proptest-based properties for varint/zigzag codecs;
  • generate valid Params and verify semantic round trips/presence;
  • verify repeated known tags are last-value-wins;
  • verify unknown tags preserve known values.

Properties

  • uvarint_round_trips / signed_varint_round_trips: every u64/i64 round-trips through encode_uvarint/decode_uvarint and encode_varint/decode_varint, with used == encoded.len() and 1 <= encoded.len() <= 10.
  • zigzag_round_trips_from_signed / zigzag_round_trips_from_unsigned: zigzag encode/decode is a bijection across the full i64 and u64 domains.
  • valid_params_round_trip: generated Params (scalar fields over the full i64 domain, constructive enum strategies, Option<ServerFill> bounded to MAX_SERVER_FILL_BYTES) round-trip through encode/decode byte-for-byte semantically.
  • encoded_param_presence_matches_omission_rules: decode_with_presence presence exactly matches Params::encode's omission rule (zero/default scalar and enum values omit their tag; Clock::Unspecified is the one enum whose zero is wire-omission-only; server_fill presence follows Option::is_some, including Some("")).
  • repeated_*_is_last_wins (one per known tag 1-8, plus server_fill tag 9): two explicit values for the same tag decode to the second value, with presence true.
  • unknown_scalar_tag_prefix_does_not_disturb_known_params / ..._suffix_...: an unknown tag (10..=u16::MAX) with an arbitrary u64 value placed before or after a valid encoded Params leaves the decoded value and known-tag presence unchanged.
  • omitted_vs_explicit_zero_presence_for_zero_valid_fields (deterministic table): omitted vs. explicit-zero decode to the same value but different presence for every field where explicit zero is valid; confirms explicit Clock=0 is rejected outright rather than accepted-as-present.

Existing hand-picked deterministic tests and byte vectors in varint.rs/params.rs are unchanged.

Dependency impact

  • proptest is a dev-dependency of irtt-proto only (release 1.11.0, MSRV 1.85, compatible with the workspace's 1.88 MSRV);
  • production dependencies unchanged;
  • root Cargo.lock changed only for the proptest dependency closure (new bit-set/bit-vec/rand versions added alongside existing ones used by other crates, not replacing them);
  • no crate versions changed;
  • fuzz/Cargo.lock and the fuzz workspace are unchanged.

Verification

  • cargo test -p irtt-proto --locked — run twice, stable, all passing (63 unit + 17/14/14 integration tests, including the new properties).
  • cargo fmt --all -- --check — clean.
  • cargo check --workspace --all-targets --all-features --locked — clean.
  • cargo test --workspace --all-targets --all-features --locked — clean.
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings — clean.
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked — clean.
  • cargo check --workspace --all-targets --no-default-features --locked — clean.
  • cargo publish -p irtt-proto --dry-run --locked — packages and verifies cleanly (expected warning that 0.5.0 already exists on crates.io, since this PR intentionally does not bump the version).
  • cd fuzz && cargo +nightly fuzz build — all fuzz targets still build.
  • No property failures were discovered; no production/protocol code was changed.
## Summary - add proptest-based properties for varint/zigzag codecs; - generate valid Params and verify semantic round trips/presence; - verify repeated known tags are last-value-wins; - verify unknown tags preserve known values. ## Properties - `uvarint_round_trips` / `signed_varint_round_trips`: every `u64`/`i64` round-trips through `encode_uvarint`/`decode_uvarint` and `encode_varint`/`decode_varint`, with `used == encoded.len()` and `1 <= encoded.len() <= 10`. - `zigzag_round_trips_from_signed` / `zigzag_round_trips_from_unsigned`: zigzag encode/decode is a bijection across the full `i64` and `u64` domains. - `valid_params_round_trip`: generated `Params` (scalar fields over the full `i64` domain, constructive enum strategies, `Option<ServerFill>` bounded to `MAX_SERVER_FILL_BYTES`) round-trip through `encode`/`decode` byte-for-byte semantically. - `encoded_param_presence_matches_omission_rules`: `decode_with_presence` presence exactly matches `Params::encode`'s omission rule (zero/default scalar and enum values omit their tag; `Clock::Unspecified` is the one enum whose zero is wire-omission-only; `server_fill` presence follows `Option::is_some`, including `Some("")`). - `repeated_*_is_last_wins` (one per known tag 1-8, plus `server_fill` tag 9): two explicit values for the same tag decode to the second value, with presence `true`. - `unknown_scalar_tag_prefix_does_not_disturb_known_params` / `..._suffix_...`: an unknown tag (10..=u16::MAX) with an arbitrary `u64` value placed before or after a valid encoded `Params` leaves the decoded value and known-tag presence unchanged. - `omitted_vs_explicit_zero_presence_for_zero_valid_fields` (deterministic table): omitted vs. explicit-zero decode to the same value but different presence for every field where explicit zero is valid; confirms explicit `Clock=0` is rejected outright rather than accepted-as-present. Existing hand-picked deterministic tests and byte vectors in `varint.rs`/`params.rs` are unchanged. ## Dependency impact - `proptest` is a dev-dependency of `irtt-proto` only (release 1.11.0, MSRV 1.85, compatible with the workspace's 1.88 MSRV); - production dependencies unchanged; - root `Cargo.lock` changed only for the `proptest` dependency closure (new `bit-set`/`bit-vec`/`rand` versions added alongside existing ones used by other crates, not replacing them); - no crate versions changed; - `fuzz/Cargo.lock` and the fuzz workspace are unchanged. ## Verification - `cargo test -p irtt-proto --locked` — run twice, stable, all passing (63 unit + 17/14/14 integration tests, including the new properties). - `cargo fmt --all -- --check` — clean. - `cargo check --workspace --all-targets --all-features --locked` — clean. - `cargo test --workspace --all-targets --all-features --locked` — clean. - `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` — clean. - `RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked` — clean. - `cargo check --workspace --all-targets --no-default-features --locked` — clean. - `cargo publish -p irtt-proto --dry-run --locked` — packages and verifies cleanly (expected warning that 0.5.0 already exists on crates.io, since this PR intentionally does not bump the version). - `cd fuzz && cargo +nightly fuzz build` — all fuzz targets still build. - No property failures were discovered; no production/protocol code was changed.
Sign in to join this conversation.