Skip to content

Latest commit

 

History

History
94 lines (68 loc) · 3.47 KB

TESTING.md

File metadata and controls

94 lines (68 loc) · 3.47 KB

Testing guide

The local gate

Run the same checks as CI before opening a pull request:

cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all

Unit and integration tests live next to the code (#[cfg(test)] modules) and in tests/. Decoding changes must include malformed-input tests. The shared fixtures/malformed/ corpus contains small, named samples for truncated XDR, invalid discriminants, empty input, and an overlong length prefix. crates/devkit-xdr/tests/malformed_corpus.rs runs each fixture through its intended decoder and requires a structured DevkitError::Decode; an unexpected successful decode or panic fails the test.

Cross-platform and endianness tests

CI runs the suite on Linux, macOS, and Windows. The following tests pin behavior that otherwise differs between hosts:

  • crates/devkit-xdr/tests/endianness.rs asserts XDR's big-endian wire format with explicit byte sequences (ScVal::U32, ScVal::I32, and ScVal::I64), round-trips them, and checks that base64/JSON output is host-independent.
  • crates/devkit-core/tests/cross_platform.rs asserts that native and forward-slash paths produce the same components, that . components are removed, and that parsers accept CRLF-terminated input.
  • crates/devkit-cli/tests/path_normalization.rs runs inspect-wasm with a native path, a forward-slash path, and a path containing .., and requires byte-identical JSON output.

Use explicit byte arrays rather than values derived from the host when testing encodings, and compare path components rather than rendered separator strings.

Fuzzing

Fuzz targets live in the standalone fuzz/ crate (it is not part of the main workspace). Targets exercise the untrusted-input decoders:

Target Entry point
decode_scval devkit_xdr::inspect_scval_base64
decode_envelope devkit_xdr::inspect_envelope_base64
decode_event devkit_xdr::inspect_event_base64

Fuzzing requires a nightly toolchain and cargo-fuzz:

cargo install cargo-fuzz
cd fuzz
cargo +nightly fuzz run decode_scval -- -max_total_time=60

Targets must not touch the filesystem and must not panic on arbitrary input: every failure should be a structured DevkitError.

Adding a target

  1. Add fuzz/fuzz_targets/<name>.rs using the libfuzzer_sys::fuzz_target! macro.
  2. Register a [[bin]] entry for it in fuzz/Cargo.toml.
  3. The scheduled job discovers targets automatically; no workflow change needed.

Scheduled fuzz smoke job

.github/workflows/fuzz.yml runs weekly (Mondays at 03:00 UTC) and on demand via workflow_dispatch. It:

  1. Discovers every target under fuzz/fuzz_targets/.
  2. Runs each target for a bounded time (60 seconds by default, overridable from the dispatch input).
  3. Fails if any target crashes or leaves a crash artifact in fuzz/artifacts.
  4. Uploads fuzz/artifacts as the fuzz-crashes artifact when a run fails.

Runs are intentionally short so they never slow normal pull-request CI.

Pinning the nightly

The workflow uses dtolnay/rust-toolchain@nightly. To pin a specific nightly, change that reference to a dated toolchain, for example:

- uses: dtolnay/rust-toolchain@master
  with:
    toolchain: nightly-2026-01-01

Reproducing a scheduled failure

Download the fuzz-crashes artifact, then re-run the offending input:

cd fuzz
cargo +nightly fuzz run decode_scval artifacts/decode_scval/<crash-file>