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
58 lines
2.1 KiB
Rust
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"
|
|
);
|
|
}
|