#[cfg(feature = "acme")]
mod acme_full_workflow_tests {
use potato::acme::{AcmeOptions, DynamicTlsAcceptor};
use std::fs;
use std::time::Duration;
#[tokio::test]
async fn test_complete_acme_workflow() {
let temp_dir = std::env::temp_dir().join("potato_acme_workflow_test");
std::fs::create_dir_all(&temp_dir).unwrap();
let (cert_pem1, key_pem1) = generate_test_cert("initial.example.com");
let cert_path = temp_dir.join("cert.pem");
let key_path = temp_dir.join("key.pem");
fs::write(&cert_path, &cert_pem1).unwrap();
fs::write(&key_path, &key_pem1).unwrap();
let acceptor = DynamicTlsAcceptor::new(&cert_pem1, &key_pem1).unwrap();
let initial_acceptor = acceptor.get_acceptor().await;
drop(initial_acceptor);
let metadata = fs::metadata(&cert_path).unwrap();
let modified = metadata.modified().unwrap();
let elapsed = modified.elapsed().unwrap();
assert!(elapsed < Duration::from_secs(60 * 24 * 3600));
let (cert_pem2, key_pem2) = generate_test_cert("renewed.example.com");
let reload_result = acceptor.reload(&cert_pem2, &key_pem2).await;
assert!(reload_result.is_ok(), "证书重载应该成功");
let reloaded_acceptor = acceptor.get_acceptor().await;
drop(reloaded_acceptor);
fs::write(&cert_path, &cert_pem2).unwrap();
fs::write(&key_path, &key_pem2).unwrap();
let _ = fs::remove_dir_all(&temp_dir);
println!("✓ Complete ACME workflow test passed");
}
#[test]
fn test_multi_domain_acme_options() {
let opts = AcmeOptions {
domains: vec![
"example.com".to_string(),
"www.example.com".to_string(),
"api.example.com".to_string(),
],
email: "admin@example.com".to_string(),
acme_directory: Some(
"https://acme-staging-v02.api.letsencrypt.org/directory".to_string(),
),
cert_dir: Some("/tmp/multi_domain_certs".to_string()),
};
assert_eq!(opts.domains.len(), 3);
assert!(opts.domains.contains(&"example.com".to_string()));
assert!(opts.domains.contains(&"www.example.com".to_string()));
assert!(opts.domains.contains(&"api.example.com".to_string()));
}
#[tokio::test]
async fn test_certificate_reload_atomicity() {
let (cert_pem1, key_pem1) = generate_test_cert("atomic1.example.com");
let acceptor = DynamicTlsAcceptor::new(&cert_pem1, &key_pem1).unwrap();
let initial_acceptor = acceptor.get_acceptor().await;
drop(initial_acceptor);
for i in 0..5 {
let domain = format!("atomic{}.example.com", i + 2);
let (cert_pem, key_pem) = generate_test_cert(&domain);
let reload_result = acceptor.reload(&cert_pem, &key_pem).await;
assert!(reload_result.is_ok(), "第{}次重载应该成功", i + 1);
let acceptor = acceptor.get_acceptor().await;
drop(acceptor);
}
println!("✓ Certificate reload atomicity test passed");
}
#[test]
fn test_cert_directory_permissions() {
let temp_dir = std::env::temp_dir().join("potato_acme_perms_test");
let _ = fs::remove_dir_all(&temp_dir);
assert!(!temp_dir.exists());
fs::create_dir_all(&temp_dir).unwrap();
assert!(temp_dir.exists());
let cert_path = temp_dir.join("cert.pem");
let (cert_pem, _) = generate_test_cert("perms.example.com");
fs::write(&cert_path, &cert_pem).unwrap();
assert!(cert_path.exists());
let _ = fs::remove_dir_all(&temp_dir);
}
fn generate_test_cert(domain: &str) -> (String, String) {
use rcgen::{CertificateParams, DistinguishedName, KeyPair};
let mut params = CertificateParams::new(vec![domain.to_string()]).unwrap();
params.distinguished_name = DistinguishedName::new();
let key_pair = KeyPair::generate().unwrap();
let cert = params.self_signed(&key_pair).unwrap();
let cert_pem = cert.pem();
let key_pem = key_pair.serialize_pem();
(cert_pem, key_pem)
}
}