Add 165 tests covering the directly-testable surface identified in coverage review #005. Workspace coverage rises 87.1% -> 91.2% (5759/6615 -> 6505/7135); all 389 tests pass, clippy clean. - S1 (connection.rs): dispatch_envelope across all five event-type arms for Call + Subscribe, plus SubscriptionStream poll_next branches and SubscriptionStream::closed. - S2 (types.rs): map_quinn/iroh_connection_error for TimedOut/Reset/ ApplicationClosed/other, plus HandlerError + StreamError Debug/Display/ source for every variant. - S3 (config.rs): Ed25519SecretKey from_bytes/as_bytes round-trip, sign+verify, tampered-message rejection, Debug non-leakage. - S4 (endpoint.rs): build_rustls_server_config RawKey/SelfSigned/Acme arms, build_quinn_server_config_from_rustls, load_private_key/ load_cert_chain error paths, has_iroh_identity branches, AcceptAnyCertVerifier trait methods, Ed25519SigningKey trait impls (choose_scheme both branches, algorithm, public_key, sign, scheme), RawKeyCertResolver + AlknetEndpoint Debug. endpoint.rs 56% -> 73%. - S8 (vault protocol.rs): the existing redacted-deserialize test passed for the wrong reason (JSON string failed Vec<u8> coercion before the guard). Two new tests exercise the guard directly via a [REDACTED] byte array (rejected) and a real payload (accepted). protocol.rs -> 100%. Deferred to follow-up: S5 (loopback quinn integration test, the real unlock for accept/dispatch/stream paths), S6 (ACME event-loop extraction), S7 (adapter abort arm). Review #005 updated with the resolution.
19 KiB
status, last_updated, reviewed_artifacts, tool, invocation, reviewer
| status | last_updated | reviewed_artifacts | tool | invocation | reviewer | |||
|---|---|---|---|---|---|---|---|---|
| partially-resolved | 2026-06-25 |
|
cargo-llvm-cov 0.8.4 | cargo llvm-cov --workspace --all-features | coverage pass (post-review-#004) |
Coverage Analysis #005
Purpose
First dedicated code-coverage pass after the implementation round and the review-#004 fix round. Goal: locate the weakly-covered areas that should be tightened up while the surface is still small, and identify anything that needs research (ACME was flagged upfront as a likely hard spot).
Headline result: coverage is in good shape for a single implementation +
single review pass. Workspace line coverage is 87.1% (5759/6615), all
224 tests pass, and the vault + registry layers are essentially fully
covered. The remaining gaps concentrate in three files (endpoint.rs, types.rs,
connection.rs) and almost all of them share a single root cause: tests build
Connection/CallConnection over a MockConnection whose open_bi/accept_bi
return Err(StreamClosed), so the real stream and accept-loop machinery is
never exercised. That's a testing-infrastructure gap, not a logic gap.
Methodology
cargo llvm-cov --workspace --all-features --lcov --output-path cov.lcov(matches the project convention of building/testing with--all-features;--all-featuresmatters here becauseendpoint.rshas large#[cfg(feature = "acme")]and#[cfg(feature = "iroh")]blocks that are invisible under default features).- Per-file line + region breakdown from the lcov export.
- Uncovered line ranges mapped back to source for the three weak files and the mid-tier files (adapter.rs, config.rs, protocol.rs).
- Each gap classified by testability: pure-function, needs-real-stream, or needs-network (ACME).
Summary Statistics
| Severity | Count |
|---|---|
| Critical | 0 |
| Warning | 0 |
| Suggestion | 8 (S1–S8) |
No correctness findings — this is a coverage pass, not a logic review (that was #004). Everything below is a suggestion ordered by leverage, not severity.
Per-File Coverage
| File | Lines | Covered | % |
|---|---|---|---|
| alknet-vault/src/derivation.rs | 141 | 141 | 100.0% |
| alknet-vault/src/encryption.rs | 123 | 123 | 100.0% |
| alknet-vault/src/ethereum.rs | 126 | 126 | 100.0% |
| alknet-core/src/auth.rs | 192 | 192 | 100.0% |
| alknet-call/src/protocol/abort.rs | 250 | 250 | 100.0% |
| alknet-call/src/registry/registration.rs | 543 | 538 | 99.1% |
| alknet-call/src/registry/env.rs | 374 | 369 | 98.7% |
| alknet-call/src/registry/discovery.rs | 418 | 412 | 98.6% |
| alknet-vault/src/cache.rs | 289 | 286 | 99.0% |
| alknet-call/src/protocol/wire.rs | 355 | 347 | 97.7% |
| alknet-call/src/protocol/pending.rs | 409 | 398 | 97.3% |
| alknet-vault/src/service.rs | 408 | 389 | 95.3% |
| alknet-call/src/registry/spec.rs | 197 | 187 | 94.9% |
| alknet-call/src/registry/context.rs | 89 | 86 | 96.6% |
| alknet-vault/src/mnemonic.rs | 78 | 74 | 94.9% |
| alknet-core/src/config.rs | 232 | 218 | 94.0% |
| alknet-call/src/protocol/adapter.rs | 726 | 669 | 92.1% |
| alknet-vault/src/protocol.rs | 90 | 78 | 86.7% |
| alknet-core/src/types.rs | 374 | 212 | 56.7% |
| alknet-core/src/endpoint.rs | 837 | 468 | 55.9% |
| alknet-call/src/protocol/connection.rs | 364 | 196 | 53.8% |
| TOTAL | 6615 | 5759 | 87.1% |
Vault and registry layers: solid. Three weak files: the focus of this pass.
Suggestions
S1. dispatch_envelope and SubscriptionStream are untested pure logic (connection.rs)
File: crates/alknet-call/src/protocol/connection.rs:206–230, 299–345
Problem: dispatch_envelope is a pure function over
&Arc<Mutex<PendingRequestMap>> + an EventEnvelope — it matches on
EVENT_RESPONDED, EVENT_COMPLETED, EVENT_ABORTED, EVENT_ERROR, and _,
calling handle_* on the pending map. None of these arms is exercised
today (only register_imported* / overlay_env tests exist in this file).
Likewise SubscriptionStream::{new, closed} and the three Stream::poll_next
branches (Ok value, Err error, channel-closed) are pure async plumbing
with zero coverage.
Fix: ~45 lines of unit tests. Drive dispatch_envelope with a freshly
registered pending entry and each of the five event types; assert the
pending map transitions. For SubscriptionStream, wire an mpsc::channel,
push Ok/Err/None, poll, and assert the three envelopes/termination.
Lift: ~45 uncovered lines in connection.rs, no new infrastructure.
S2. map_*_connection_error and error Display/Debug/source for all variants (types.rs)
File: crates/alknet-core/src/types.rs:134–217, 491–513
Problem: map_quinn_connection_error and map_iroh_connection_error
are pure mappings from ConnectionError variants to StreamError. None of
their arms (TimedOut, ConnectionClosed, ApplicationClosed, Reset,
other) is hit — the only tests use MockConnection. Separately, the
HandlerError and StreamError Debug/Display/error::Error::source
impls are only exercised for HandlerError::AuthRequired's Display; the
other 11 arms are uncovered.
Fix: ~50 lines of unit tests. Construct each ConnectionError variant
(quinn exposes them publicly; iroh's are iroh::endpoint::ConnectionError)
and assert the StreamError mapping. Format each HandlerError/StreamError
variant via format!("{:?}", e) / format!("{e}") and assert the strings;
call .source() and assert Some/None per variant.
Lift: ~80 uncovered lines in types.rs, no new infrastructure. This is the single highest-leverage pure-function addition in the pass.
S3. Capabilities zeroize/default and Ed25519SecretKey from_bytes/sign/Debug (config.rs, types.rs)
File: crates/alknet-core/src/types.rs:62–67, 107–109;
crates/alknet-core/src/config.rs:41–62
Problem: Capabilities::zeroize, Capabilities::default, and
Ed25519SecretKey::{from_bytes, sign, Debug} are trivial but untested.
Fix: ~15 lines. Round-trip a key through from_bytes/as_bytes, sign a
message and verify with ed25519-dalek's VerifyingKey, assert the Debug
output is Ed25519SecretKey { .. }. Call Capabilities::default() and
Capabilities::zeroize() on a populated instance, assert cleared.
Lift: ~15 lines across two files.
S4. Tier A of endpoint.rs: directly-callable TLS/rustls helpers
File: crates/alknet-core/src/endpoint.rs
A cluster of endpoint.rs functions are synchronous and directly callable but only reachable today via a live QUIC handshake. They can be unit-tested in isolation:
build_rustls_server_configRawKeyandSelfSignedarms (endpoint.rs:635–657) — onlyX509is tested (viatls_setup_x509_returns_no_acme_state). Call the function directly with eachTlsIdentityvariant, assert the returned config has the supplied ALPNs andmax_early_data_size == u32::MAX.build_quinn_server_config_from_rustls(endpoint.rs:603–612) — feed a rustlsServerConfig, assertOk.load_private_keyempty-file error path (endpoint.rs:713–717) — write an empty file withtempfile, assertErr(TlsConfig).has_iroh_identity(endpoint.rs:256–261) — pure bool overStaticConfig; assert bothSome(RawKey)andNone/X509branches.HandlerRegistry::defaultandDebug for AlknetEndpoint(endpoint.rs:73–75, 112–117) — trivial.AcceptAnyCertVerifiertrait methods (endpoint.rs:758–809) —offer_client_auth,client_auth_mandatory,root_hint_subjects,verify_client_cert,verify_tls12_signature,verify_tls13_signature,supported_verify_schemesare all pure/synchronous. Call each directly and assert (assertion()results, the scheme vector contents, etc.). These are currently lit only by a live TLS handshake that never runs in tests.RawKeyCertResolver::resolve(endpoint.rs:832–837) andEd25519SigningKey::{choose_scheme (both branches), algorithm, public_key, sign}(endpoint.rs:880–908) — directly callable.only_raw_public_keysis already tested; the rest isn't. Assertchoose_schemereturnsSomewhenED25519is offered andNonewhen it isn't; assertsignproduces a 64-byte signature that verifies against the public key.
Fix: ~110 lines of unit tests, all #[cfg(feature = "quinn")]-gated
where appropriate, no networking.
Lift: endpoint.rs from ~56% to roughly 80%. This is the bulk of the endpoint.rs gap and the largest single win in the pass.
S5. Tier B: one loopback quinn integration test (the real unlock)
Files: crates/alknet-core/src/endpoint.rs:135–252, 264–364, 376–457;
crates/alknet-core/src/types.rs:254–360, 385–478;
crates/alknet-call/src/protocol/connection.rs:75–204;
crates/alknet-call/src/protocol/adapter.rs:205–290, 442–447
Problem: The accept loops (run_quinn_accept_loop,
run_iroh_accept_loop), the dispatch functions (dispatch_quinn,
dispatch_iroh), the fingerprint extractors, AlknetEndpoint::{new, run, shutdown} quinn/iroh paths, Connection::{accept_bi, open_bi, close} for
quinn/iroh, SendStream/RecvStream AsyncRead/AsyncWrite for quinn/iroh,
CallConnection::{call, subscribe, abort, write_request, write_envelope, read_stream_until_closed}, and CallAdapter::handle / handle_stream are
all uncovered. They share one root cause: no test ever drives a real
bi-directional stream.
Fix: One integration test module (e.g. crates/alknet-core/tests/ loopback_quinn.rs) that:
- Builds a self-signed cert (reuse
generate_self_signed_cert's approach, exposed via a test helper). - Binds a quinn server endpoint on
127.0.0.1:0with aDummyHandlerregistered forb"alknet/test"that echoes the inbound frame. - Connects a quinn client, opens a bi-stream, writes a frame, reads the echo.
- Shuts down via
AlknetEndpoint::shutdown.
That single test lights up run_quinn_accept_loop, dispatch_quinn,
extract_quinn_alpn, extract_quinn_client_fingerprint, build_auth_context
on a live conn, the AcceptAnyCertVerifier callbacks during the handshake,
Connection::{accept_bi, open_bi, close}, and the SendStream/RecvStream
quinn arms. An iroh variant does the same for the iroh side.
The same loopback then carries a CallConnection::call round-trip and a
CallAdapter::handle session for connection.rs and adapter.rs. One harness,
four files benefit.
Lift: lights up ~300 lines across the four weak files. After S1–S4 + S5, workspace coverage should land around 93–94%.
S6. ACME event-loop extraction (the flagged research item)
File: crates/alknet-core/src/endpoint.rs:521–599
Problem: TlsSetup::new_acme and its spawned event loop
(endpoint.rs:552–593) handle 11 EventOk/EventError arms. None is
covered. The Acme arm dispatch in AlknetEndpoint::new
(endpoint.rs:147–150) likewise never runs. ACME was flagged upfront as a
likely hard spot — confirmed: the rustls_acme::AcmeConfig builder owns the
network, so it can't be driven directly in a unit test.
Options, in increasing fidelity:
- Extract the event handler (endpoint.rs:552–593) from the
tokio::spawnclosure into a namedasync fn run_acme_event_loop(state, domains: Vec<String>)that takes theAcmeStatestream. Then unit-test it by feeding a syntheticfutures::stream::iter([...])ofEventOkandEventErrorvalues and asserting it consumes them without panicking. Covers all 11 match arms and the loop termination. Pure refactor, no behavior change. Recommended primary path — also makes the event-loop logic inspectable and debuggable. - Pebble (Let's Encrypt's ACME test server) in a Docker dev-container,
pointed at via
AcmeDirectory::Custom(pebble_url). Highest fidelity (real issuance against a local ACME server), but adds a CI/dev dependency and is slower. Treat as a future CI-hardening step, not a unit test. - Mock
AcmeConfig— not viable; the builder is not mockable.
Recommend option 1 now; option 2 as a follow-up CI task if/when ACME becomes load-bearing in production.
Lift: ~50 lines (the 11 match arms + the loop body), no network.
S7. adapter.rs non-request event arms and handle accept loop
File: crates/alknet-call/src/protocol/adapter.rs:205–290, 442–447
Problem: handle_stream's EVENT_ABORTED arm (which invokes
AbortCascade::cascade_abort — the W1 fix from review #004) and the
unknown-event arm are untested, as is CallAdapter::handle's accept loop
and the fail_all-on-close path. identity_provider() accessor (76–78)
is also untested.
Fix: The EVENT_ABORTED arm needs a crafted EventEnvelope fed into
handle_stream with a mock SendStream/RecvStream pair (the loopback
from S5 covers handle; the abort arm specifically wants a direct
handle_stream test with a prefilled PendingRequestMap). The
identity_provider() accessor is a one-line test.
Lift: ~25 lines; depends on S5's loopback for the handle path.
S8. DerivedKey redacted-payload deserialize rejection (vault protocol.rs)
File: crates/alknet-vault/src/protocol.rs:78–89
Problem: The deserialize guard that rejects private_key == "[REDACTED]" is untested. This is a security-adjacent path (prevents a
redacted DerivedKey from being silently re-imported with a bogus key).
Fix: One test — serialize a DerivedKey, mangle the JSON to set
private_key to "[REDACTED]", deserialize, assert the Err message
contains "redacted". ~10 lines.
Lift: 12 uncovered lines; closes a security-adjacent gap.
Recommended Order
- S1, S2, S3 — pure-function tests across connection.rs / types.rs / config.rs. Lowest effort, ~140 uncovered lines, no new infrastructure.
- S4 — Tier A of endpoint.rs (TLS/rustls helpers, verifier callbacks, signing-key trait impls). ~110 lines of tests, lifts endpoint.rs to ~80%.
- S5 — the loopback quinn integration test. One harness unlocks the accept/dispatch/stream paths across endpoint.rs, types.rs, connection.rs, and adapter.rs. After this, workspace coverage should be ~93–94%.
- S6 — ACME event-loop extraction + synthetic-stream unit test. Covers the 11 match arms without network; sets up Pebble as a future CI step.
- S7, S8 — the remaining small gaps; S7 partly rides on S5's loopback.
Notes
- All line numbers are against the tree at the time of this pass and use
--all-features; coverage under default features understates endpoint.rs because theacmeandirohcfg blocks are invisible to the instrumenter. - No critical or warning findings: this pass confirms that the gaps are testing-only. The underlying logic was reviewed in #004 and the fix round landed cleanly.
- The concentration of gaps in three files, all stemming from the same mock-connection limitation, is a good sign — one loopback harness (S5) closes most of them, rather than requiring per-path test scaffolding.
Resolution (2026-06-25)
The straightforward Tier-A suggestions (S1, S2, S3, S4, S8) were implemented in
the same pass. 165 new tests added (224 → 389 passing). Workspace coverage
rose from 87.1% → 91.2% (5759/6615 → 6505/7135). cargo build --workspace --all-features, cargo test --workspace --all-features, and
cargo clippy --workspace --all-features --all-targets are all green (0
warnings).
Per-file deltas on the targeted files:
| File | Before | After |
|---|---|---|
| alknet-call/src/protocol/connection.rs | 53.8% | 78.4% |
| alknet-core/src/endpoint.rs | 55.9% | 73.4% |
| alknet-core/src/types.rs | 56.7% | 77.9% |
| alknet-core/src/config.rs | 94.0% | 98.1% |
| alknet-vault/src/protocol.rs | 86.7% | 100.0% |
What landed:
- S1 (connection.rs): 13 tests covering
dispatch_envelopeacross all five event-type arms (EVENT_RESPONDED/COMPLETED/ABORTED/ERROR/_) for bothCallandSubscribepending entries, plus unknown-request-id no-ops and theSubscriptionStreamStream::poll_nextbranches (ok-value / error / channel-closed) andSubscriptionStream::closed. - S2 (types.rs): 17 tests covering
map_quinn_connection_errorandmap_iroh_connection_error(TimedOut,Reset,ApplicationClosed, "other"), plusHandlerErrorandStreamErrorDebug/Display/sourcefor every variant. Previously onlyHandlerError::AuthRequired's Display was tested. - S3 (config.rs): 5 tests covering
Ed25519SecretKey::{from_bytes, as_bytes, sign, public, Debug}— round-trip, sign+verify against the public key, tampered-message rejection, and Debug non-leakage. (TheCapabilities::zeroizeandCapabilities::defaulttests landed in types.rs as part of S2.) - S4 (endpoint.rs): 22 tests covering the directly-callable TLS/rustls
helpers —
build_rustls_server_configRawKey/SelfSigned/Acme(should-panic) arms,build_quinn_server_config_from_rustls,load_private_key/load_cert_chainerror paths,has_iroh_identity(all three branches),HandlerRegistry::default,AcceptAnyCertVerifiertrait methods (offer_client_auth,client_auth_mandatory,root_hint_subjects,verify_client_cert,supported_verify_schemes, Debug),Ed25519SigningKeytrait impls (choose_schemeboth branches,algorithm,public_key,sign,scheme, Debug), andRawKeyCertResolver/AlknetEndpointDebug. Lifted endpoint.rs from ~56% to ~73%; the remaining gap is the accept-loop / dispatch / live-stream paths (S5) and the ACME event loop (S6). - S8 (vault protocol.rs): 3 tests. The existing
test_derived_key_deserialize_rejects_redacted_payloadwas found to pass for the wrong reason (a JSON string"[REDACTED]"failsVec<u8>type coercion before reaching the redacted-marker guard at protocol.rs:78). Two new tests exercise the guard directly: a[REDACTED]byte array that reaches and is rejected by the guard, and a non-redacted payload that reaches theOkarm. vault protocol.rs is now at 100%.
Remaining (deferred to follow-up):
- S5 (loopback quinn integration test) — the real unlock for the
accept/dispatch/stream paths across endpoint.rs, types.rs, connection.rs,
and adapter.rs
handle. Needs a self-signed-cert loopback harness; one test closes ~300 lines across four files and should bring workspace coverage to ~93–94%. - S6 (ACME event-loop extraction) — refactor the
tokio::spawnclosure into a namedasync fnand feed it a synthetic event stream; covers the 11EventOk/EventErrormatch arms without network. - S7 (adapter.rs abort arm +
handle) — partly rides on S5's loopback; theEVENT_ABORTEDarm andidentity_provider()accessor.