Files
alktls/tasks/integration-suite.md
T
glm-5.3-flash 87b69e19e6 generation 4: integration suite — seam round-trips + invariant pins
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
2026-09-10 15:00:06 +00:00

6.3 KiB
Raw Blame History

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
port-server
port-client
broad medium phase implementation
tests
integration
invariants
phase-gate

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

  1. Server seam round-trips — for each TlsIdentity variant (X509 via generated PEM files in a tempdir, RawKey via Ed25519SecretKey::generate, SelfSigned): TlsServerConfig::newfor_noq() (all-features) / for_tcp_tls() / rustls_config() all succeed; the rustls config carries the expected ALPN list and max_early_data_size.
  2. Client seam round-tripsTlsClientConfig::new per credentials cell → for_noq() / into_rustls_config(); enable_early_data pinned true; ALPN single-value list.
  3. Verifier-selection matrix — the full local_identity × remote_identity construction matrix (the port-client unit assertions promoted to integration level, exercising the public API only).
  4. The nine-scheme exact-list pin — the regression-proof shape (exact vec equality, not membership).
  5. Root-store fallbackload_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).
  6. ACME lifecycle (--features acme): construct an Acme identity with staging URL + tempdir cache; assert spawn-and-return semantics, acme-tls/1 in the ALPN list, and the resolver wiring (no network I/O — do NOT hit Let's Encrypt).
  7. 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

  1. Write the tests/ files (one per suite group is fine).
  2. Promote any in-module assertions that exercise cross-module behavior to integration level (keep the in-module ones too).
  3. Wire the exact-list and enable_early_data pins.

Verification

  • Full suite green across all five feature combos
  • The nine-scheme test asserts exact list equality
  • enable_early_data == true asserted 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's verifier and rustls::ServerConfig's verifier are pub(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_config is pub(crate) — integration level goes through into_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 by acme_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).