Hardening (non-module framework files):
- Retry-then-continue: bounded per-host retry on transient failures across all 4
mass-scan fan-outs; '10 errors -> abort sweep' softened to warn-and-continue
- Crash fixes: shell completer char-boundary guard; unreachable! -> bail!
- WS oversize-frame desync fixed (was bricking the PQ AEAD ratchet); MCP tenant
job list/kill, out-of-range port, non-string option now correct/errored
- No silent error swallowing: swept framework files, every dropped error now
bound + surfaced (warn for logged-only/data-loss, debug for already-propagated
or aggregated per-host); removed _ => {} and Err(_)/|_| discards
Docs + release: README + docs/ updated for the release; RELEASE_NOTES.txt
section 6d added; new RELEASE_GITHUB.txt (GitHub release body).
Build: 0 errors, 0 warnings, 40/40 targeted tests green.
4.3 KiB
Testing & QA
Guidelines for verifying that new modules and framework changes are correct.
Static Checks
Run before every commit or PR:
# Format code
cargo fmt
# Lint (use where available)
cargo clippy
# Compile check (fast, no linking)
cargo check
A clean cargo check with 0 errors is required. The current codebase (363 modules) compiles with legacy warnings from mid-migration modules — see the Changelog for the running count.
Build Verification
cargo build
Modules self-register via register_native_module! at compile time using
the inventory crate — there is no build.rs codegen (removed in v0.5.6).
All 363 modules are auto-discovered at link time. If a new module fails to
register, ensure pub mod your_module; is present in the sibling mod.rs.
Runtime Smoke Tests
Shell
cargo run
# Inside the shell:
modules # Verify new module appears in list
find <keyword> # Verify keyword search works
u scanners/sample_scanner
set target 127.0.0.1
go # Runs the sample scanner against localhost
CLI
cargo run -- -m scanners/sample_scanner -t 127.0.0.1
cargo run -- --list-modules # Verify your module is listed
API
# Start the server
cargo run -- --api
# Verify server starts (module listing requires PQ WebSocket session)
curl http://localhost:8080/health
Unit Tests
Run all unit tests:
cargo test
Module-level tests can be added inline:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_response() {
let output = parse_response(b"some payload");
assert!(output.is_some());
}
}
For async tests:
#[tokio::test]
async fn test_async_behavior() {
// ...
}
Wordlist Validation
Before adding a module that depends on wordlists:
- Confirm the file exists under
lists/ - Reference the path in docstrings or
lists/readme.md - Validate it is non-empty at runtime and handle the empty case gracefully
Framework Feature Smoke Tests
After modifying framework features, verify these work:
# Shell smoke test
cargo run
# Inside shell:
info exploits/sample_exploit # Should display module metadata
setg port 8080 # Set global option
show options # Should show port=8080
unsetg port # Remove it
creds # Should show empty cred store
hosts # Should show empty host list
workspace # Should show "default" workspace
loot # Should show empty loot
jobs # Should show no jobs
spool /tmp/test.log # Start console logging
spool off # Stop logging
export json /tmp/test.json # Should create JSON file
# API smoke test — verify server starts and health endpoint responds
cargo run -- --api
curl http://localhost:8080/health
# All other endpoints require a PQ WebSocket session — see API-Server.md
Regression Notes
| Area | What to verify |
|---|---|
| New cred module | Correct concurrency model, DNS resolved once (not per attempt) |
| New exploit | Response validated before declaring success, artifacts written to CWD |
| New scanner | Outputs parseable results, status codes filtered correctly |
| Mass-scan module | Scheduler exclusions applied, no per-module EXCLUDED_RANGES, target-specific filenames |
| API change | cargo check clean, endpoint documented in API Server |
| Utils change | All prompt helpers still compile, no dead code warnings |
Module with info() |
info command displays metadata |
| Source port | Connections use tcp_connect_str/udp_bind, not raw socket calls |
| Batch mode | Interactive/REPL modules bail with is_batch_mode() guard |
| Global options change | JSON file updated atomically, cfg_prompt_* respects priority chain |
| Workspace change | JSON saved on modification, workspace switch preserves data |
| Cred store change | JSON persistence works, search returns correct results |
Known Disabled / Stubbed Code
| Module | Status | Reason |
|---|---|---|
scanners/dns_recursion |
✅ Fixed | Rewritten for hickory-client v0.25 (AsyncClient → Client, builder pattern + TokioRuntimeProvider) |