Files
alktls/tests/acme_lifecycle.rs
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

58 lines
2.1 KiB
Rust

//! ACME lifecycle (feature `acme`): construct an `Acme` identity with a
//! staging URL + tempdir cache; assert spawn-and-return semantics,
//! `acme-tls/1` in the ALPN list, and the resolver wiring. No network I/O
//! — the directory URL is constructed, never contacted.
#![cfg(feature = "acme")]
use alktls::{AcmeDirectory, TlsIdentity, TlsServerConfig};
#[tokio::test]
async fn acme_spawns_returns_and_appends_acme_tls_alpn() {
let dir = tempfile::tempdir().expect("tempdir");
let identity = TlsIdentity::Acme {
domains: vec!["localhost".to_string()],
cache_dir: dir.path().join("cache"),
directory: AcmeDirectory::Custom("http://127.0.0.1:9/directory".to_string()),
contact: vec!["mailto:dev@example.com".to_string()],
};
let alpn = vec![b"alk/test".to_vec()];
let config = TlsServerConfig::new(&identity, &alpn)
.await
.expect("ACME config must construct and return immediately (no order awaited)");
let rc = config.rustls_config();
assert_eq!(rc.max_early_data_size, u32::MAX);
assert_eq!(
rc.alpn_protocols,
vec![b"alk/test".to_vec(), b"acme-tls/1".to_vec()],
"the crate appends acme-tls/1 on the ACME path only (alknet ADR-027 §7)"
);
let cert_resolver = &rc.cert_resolver;
let _ = cert_resolver;
assert!(
!format!("{:?}", cert_resolver).is_empty(),
"the ACME resolver is wired as the cert resolver"
);
}
#[tokio::test]
async fn acme_staging_directory_url_is_pinned_in_the_identity() {
let identity = TlsIdentity::Acme {
domains: vec!["example.com".to_string()],
cache_dir: tempfile::tempdir().expect("tempdir").path().join("cache"),
directory: AcmeDirectory::Staging,
contact: vec!["mailto:dev@example.com".to_string()],
};
let alpn = vec![b"alk/test".to_vec()];
let config = TlsServerConfig::new(&identity, &alpn)
.await
.expect("ACME config must construct with the staging directory URL");
assert_eq!(
config.rustls_config().max_early_data_size,
u32::MAX,
"the ACME branch carries the 0-RTT invariant too"
);
}