بنقرة واحدة
mutation-testing
Rust mutation testing with cargo-mutants, survived-mutant triage, and test adequacy fixes.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Rust mutation testing with cargo-mutants, survived-mutant triage, and test adequacy fixes.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Use this skill to generate well-branded interfaces and assets for RIPDPI (an Android-native, Compose-first VPN and DPI-bypass app), either for production or throwaway prototypes/mocks/etc. Contains essential design guidelines, colors, type, fonts, brand-ship icons, and an interactive UI kit of every public composable from the live ui/components tree.
Use when managing the Rust workspace, adding/removing crates, editing workspace dependencies, running cargo nextest/audit/deny, configuring Cargo profiles for Android cross-compilation, debugging Cargo.lock churn, migrating crate edition, or wiring Gradle to cargo via the ripdpi.android.rust-native plugin.
Use when modifying the diagnostics scan pipeline, ScanRequest/ScanReport types, ProbeTask families, ripdpi-monitor-engine / ripdpi-diagnostics-* crates, strategy-probe candidates, the diagnostics catalog (packs/profiles), wire-schema contracts between Rust and Kotlin, DIAGNOSTICS_ENGINE_SCHEMA_VERSION, golden contract tests, or adding a new probe type / profile. Triggers on diagnostics scans, strategy probes, automatic audit, dpi-detector profiles, or anything in core/diagnostics or native/rust/crates/ripdpi-monitor-*.
Android-specific Rust build, verification, and packaging — per-target 16 KiB page alignment, size-optimized release profile, ELF symbol allowlist, .so size budgets, NDK 29 specifics. Use when modifying .cargo/config.toml for Android targets, the workspace [profile.release] / [profile.android-jni] block, or when verifying a built .so before release.
Telemetry and observability discipline for the RIPDPI Android Rust stack — control-plane vs data-plane logging, bounded flume event queues, atomic counters, snapshot polling, readiness callbacks, and deterministic JSON contracts. Use when authoring or modifying telemetry emission code, the bounded event ring, the Kotlin-side telemetry consumer, or any per-packet logging.
Custom detekt rules, DI/privacy/suppression guardrails, detekt.yml configuration, and false-positive triage.
| name | mutation-testing |
| description | Rust mutation testing with cargo-mutants, survived-mutant triage, and test adequacy fixes. |
Coverage tells you which lines execute during tests, not whether the tests verify the behavior. A function with 100% coverage can have zero assertions.
Mutation testing injects small semantic changes (mutants) -- flipping operators, replacing return values, deleting calls -- and re-runs the test suite for each. If tests still pass after a mutation, that mutant "survived," meaning tests execute the code but never check its correctness. Surviving mutants point directly at weak assertions, missing edge-case tests, or untested error paths.
All commands assume your working directory is the repository root.
cargo mutants \
--manifest-path native/rust/Cargo.toml \
--test-tool nextest \
--jobs auto \
--output target/mutants-output
Add --in-diff "git diff origin/main...HEAD" to the command above. This only
generates mutants for changed lines, so a focused PR might produce 10-50
mutants instead of thousands.
Add --package ripdpi-desync to target one crate. Combine with --in-diff
for the fastest feedback loop.
| Flag | Purpose |
|---|---|
--list | Dry-run: print mutants without executing tests |
--file <path> | Restrict to a specific source file |
--re <regex> | Only mutants matching a regex on the function name |
--timeout-multiplier <N> | Override the config timeout multiplier |
-j <N> / --jobs <N> | Parallel mutant jobs (default: auto) |
timeout_multiplier = 3.0
minimum_test_timeout = 30
baseline_duration * 3.0 before
being killed. The 3x accounts for build overhead and CI variability.All 23 workspace crates are mutation targets by default. Prefer narrow source-level excludes over disabling entire packages.
To exclude specific functions or modules, add to mutants.toml:
exclude_re = ["Display::fmt", "impl.*Debug"]
Schedule: Weekly on Monday 06:00 UTC (cron: "0 6 * * 1").
Manual dispatch inputs:
packages -- space-separated crate names; empty = all 23 cratesin_diff -- true to only mutate lines changed vs mainKey details:
rust-toolchain.toml)cargo-nextest and cargo-mutants via taiki-e/install-actionubuntu-latest with a 90-minute timeouttarget/mutants-output/ as artifact, retained 14 daysTo trigger manually from the CLI:
gh workflow run mutation-testing.yml \
-f packages="ripdpi-desync ripdpi-packets" \
-f in_diff=true
Results land in target/mutants-output/. Key files:
| File | Content |
|---|---|
caught.txt | Mutants killed by tests (good) |
missed.txt | Mutants that survived (test gaps) |
timeout.txt | Mutants that caused infinite loops / hangs |
unviable.txt | Mutants that failed to compile (not interesting) |
outcomes.json | Machine-readable full results |
missed.txtmutants.toml rather than writing a meaningless test// Weak: survives mutations that change the return value
assert!(compute_ttl(input).is_ok());
// Strong: catches any change to the computed value
assert_eq!(compute_ttl(input), Ok(Duration::from_secs(30)));
Mutants often flip < to <= or +1 to -1. Pin the boundaries:
#[test]
fn fragment_offset_boundary() {
// Exactly at limit -- should succeed
assert!(validate_offset(MAX_OFFSET).is_ok());
// One past limit -- should fail
assert!(validate_offset(MAX_OFFSET + 1).is_err());
}
Error branches often survive because no test triggers them. Write explicit tests for malformed input, invalid state, and rejection paths. Similarly, if a function has side effects (incrementing a counter, sending a metric), assert the effect occurred -- mutations that delete the call survive otherwise.
Suppress these in mutants.toml with exclude_re rather than writing
low-value tests:
tracing::debug! argument changes do not affect correctness.unreachable!() in type-guarded match arms.The script is the single entry point for both CI and local batch runs.
What it does: Locates native/rust/Cargo.toml, reads env vars
(MUTANTS_TEST_TOOL=nextest, MUTANTS_PACKAGES=all,
MUTANTS_JOBS unset = cargo-mutants default parallelism), filters packages via
cargo metadata --locked if a subset is requested, then calls cargo mutants with
assembled args. Extra CLI args (e.g., --in-diff) are passed through.
Local usage:
bash scripts/ci/run-rust-mutants.sh # all crates
MUTANTS_PACKAGES="ripdpi-desync" bash scripts/ci/run-rust-mutants.sh # one crate
bash scripts/ci/run-rust-mutants.sh --in-diff "git diff origin/main...HEAD" # incremental
MUTANTS_JOBS=4 bash scripts/ci/run-rust-mutants.sh # limit parallelism
The script uses run_workspace_mutants and currently targets only the main
workspace. Add another call at the bottom to extend to additional workspaces.