tests/server_seams.rs: - TlsServerConfig::new per identity variant → rustls_config() + for_tcp_tls (tcp) + for_noq (noq); ALPN + max_early_data_size=u32::MAX asserted per path; Acme-no-feature → AcmeConfig cell tests/client_seams.rs: - TlsClientConfig::new per credentials cell → into_rustls_config + for_noq; enable_early_data=true + single-value ALPN pinned tests/invariant_pins.rs: - nine-scheme exact-list pin (vec equality, order included) - verifier-selection + client-auth presentation matrices via public API (Debug probe for the pub(super) verifier, direct resolver introspection); root-store fallback non-empty tests/acme_lifecycle.rs (#![cfg(feature = acme)]): - spawn-and-return, acme-tls/1 in ALPN, resolver wiring, 0-RTT on the ACME branch; blackhole + staging URLs — zero network I/O Verification: all five feature combos green (default 68+13, noq 72+16, tcp 71+13, acme 68+11, all-features 75+17), clippy -D warnings, fmt --check, doc --no-deps
6.3 KiB
6.3 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| integration-suite | Integration suite — invariant pins + feature-matrix + seam round-trips (tests/) | completed |
|
broad | medium | phase | implementation |
|
Description
The tests/ integration suite per ADR-006: the cross-module surfaces
the in-module seed tests cannot cover. A full-crate crate has no
workspace consumers to lean on, so this suite is the invariant gate
before the alknet rewrite consumes the crate.
The suites
- Server seam round-trips — for each
TlsIdentityvariant (X509 via generated PEM files in a tempdir, RawKey viaEd25519SecretKey::generate, SelfSigned):TlsServerConfig::new→for_noq()(all-features) /for_tcp_tls()/rustls_config()all succeed; the rustls config carries the expected ALPN list andmax_early_data_size. - Client seam round-trips —
TlsClientConfig::newper credentials cell →for_noq()/into_rustls_config();enable_early_datapinned true; ALPN single-value list. - Verifier-selection matrix — the full
local_identity×remote_identityconstruction matrix (the port-client unit assertions promoted to integration level, exercising the public API only). - The nine-scheme exact-list pin — the regression-proof shape (exact vec equality, not membership).
- Root-store fallback —
load_platform_root_cert_store(or the config built from it) yields a non-empty store even when the platform store is empty (webpki-roots merge; assert non-emptiness and count > 0). - ACME lifecycle (
--features acme): construct anAcmeidentity with staging URL + tempdir cache; assert spawn-and-return semantics,acme-tls/1in the ALPN list, and the resolver wiring (no network I/O — do NOT hit Let's Encrypt). - Feature-matrix gate:
default = []compiles + tests pass;--features noq;--features tcp;--features acme;--all-features(the gate is also a CI-verifiable convention, but the suite includes the combination that exercises every feature-gated accessor).
Out of scope (explicitly)
Real handshakes (transport crates' job — the scope boundary), network ACME orders, iroh (no iroh dep exists here), SOCKS5, dispatch.
Work
- Write the
tests/files (one per suite group is fine). - Promote any in-module assertions that exercise cross-module behavior to integration level (keep the in-module ones too).
- Wire the exact-list and
enable_early_datapins.
Verification
- Full suite green across all five feature combos
- The nine-scheme test asserts exact list equality
enable_early_data == trueasserted on a client config- ACME test performs no network I/O (staging URL is constructed, never contacted)
cargo clippy --all-targets -- -D warnings,cargo fmt --check,cargo doc --no-deps(doc comments render)
Acceptance Criteria
- All 7 suites exist and pass
- The suite runs green with a single
cargo test --all-features tests/layout documented in the task Summary
References
- docs/architecture/decisions/006-module-layout-and-tests.md (the test plan)
- docs/architecture/server.md + client.md (the invariants)
- Prior art: the extracted crate's in-module tests
(
crates/alknet-tls/src/*.rs#[cfg(test)]blocks)
Notes
Agent fills this during implementation.
Summary
Agent fills this on completion.
The tests/ layout
| File | Suites covered |
|---|---|
tests/server_seams.rs |
Suites 1 + 7(server half): TlsServerConfig::new per X509 (rcgen PEM pair in tempdir) / RawKey / SelfSigned → rustls_config() + for_tcp_tls() (tcp-gated) + for_noq() (noq-gated); ALPN + max_early_data_size = u32::MAX asserted per path; the Acme-no-feature → TlsError::AcmeConfig cell (cfg(not(feature = "acme"))) |
tests/client_seams.rs |
Suite 2: TlsClientConfig::new per credentials cell (pinned / CA / empty) → into_rustls_config() + for_noq() (noq-gated); enable_early_data == true + single-value ALPN asserted |
tests/invariant_pins.rs |
Suites 3 + 4 + 5: the nine-scheme exact-list pin (exact vec equality, order included); the verifier-selection matrix (Some → FingerprintPinVerifier, None → WebPkiServerVerifier — the fail-closed structure, asserted via the config's derived Debug) + client-auth presentation matrix (RawKey → only_raw_public_keys(), X509 → loaded chain, SelfSigned/None → nothing, Acme → TlsError::AcmeConfig), all through the public API; root-store fallback non-empty |
tests/acme_lifecycle.rs |
Suite 6 (#![cfg(feature = "acme")]): spawn-and-return semantics, acme-tls/1 in the ALPN list, resolver wiring, max_early_data_size on the ACME branch — blackhole directory URL (http://127.0.0.1:9), staging URL constructed (never contacted) |
Suite 7 (the feature-matrix gate) is the verification command block below — every combo is run, not just asserted.
Notes / decisions
rustls::ClientConfig'sverifierandrustls::ServerConfig's verifier arepub(super)at rustls 0.23.44 — the verifier identity is asserted through the derived Debug output (the verifier's type name appears in it); the client-auth resolver IS public (client_auth_cert_resolver), so the presentation matrix asserts it directly (has_certs()/only_raw_public_keys()).alktls::TlsClientConfig.rustls_configispub(crate)— integration level goes throughinto_rustls_config().- The Acme-no-feature test is
cfg(not(feature = "acme"))(it asserts the error only exists when the feature is absent; with the feature the same identity legitimately constructs — that path is covered byacme_lifecycle). - Real handshakes, network ACME, iroh, SOCKS5, dispatch: out of scope per the task (the scope boundary holds).
Verification
- All five feature combos green: default (68 lib + 13 int),
noq(72 + 16),tcp(71 + 13),acme(68 + 11),--all-features(75 + 17). cargo clippy --all-targets --all-features -- -D warnings✓,cargo fmt --check✓,cargo doc --no-deps✓.- The ACME tests perform no network I/O (staging URL constructed, never
contacted; the lifecycle test uses
127.0.0.1:9— a blackhole).