use bhttp::Message;
use ohttp_gateway::key_manager::{CipherSuiteConfig, KeyManager, KeyManagerConfig};
use std::io::Cursor;
use std::time::Duration;
use tokio;
#[tokio::test]
async fn test_key_generation() {
let config = KeyManagerConfig::default();
let manager = KeyManager::new(config).await.unwrap();
let stats = manager.get_stats().await;
assert_eq!(stats.total_keys, 1);
assert_eq!(stats.active_keys, 1);
assert!(stats.active_key_id > 0); }
#[tokio::test]
async fn test_key_generation_with_seed() {
let config = KeyManagerConfig::default();
let seed = vec![0u8; 32];
let manager = KeyManager::new_with_seed(config, seed).await.unwrap();
let stats = manager.get_stats().await;
assert_eq!(stats.total_keys, 1);
assert_eq!(stats.active_keys, 1);
}
#[tokio::test]
async fn test_key_generation_with_insufficient_seed() {
let config = KeyManagerConfig::default();
let short_seed = vec![0u8; 16];
let result = KeyManager::new_with_seed(config, short_seed).await;
assert!(result.is_err());
if let Err(e) = result {
assert!(e.to_string().contains("Seed must be at least 32 bytes"));
}
}
#[tokio::test]
async fn test_key_rotation() {
let config = KeyManagerConfig {
rotation_interval: Duration::from_secs(60),
key_retention_period: Duration::from_secs(30),
auto_rotation_enabled: true,
..Default::default()
};
let manager = KeyManager::new(config).await.unwrap();
let initial_stats = manager.get_stats().await;
manager.rotate_keys().await.unwrap();
let new_stats = manager.get_stats().await;
assert_eq!(new_stats.total_keys, 2); assert_ne!(new_stats.active_key_id, initial_stats.active_key_id);
}
#[tokio::test]
async fn test_get_current_server() {
let config = KeyManagerConfig::default();
let manager = KeyManager::new(config).await.unwrap();
let server = manager.get_current_server().await;
assert!(server.is_ok());
}
#[tokio::test]
async fn test_get_server_by_id() {
let config = KeyManagerConfig::default();
let manager = KeyManager::new(config).await.unwrap();
let stats = manager.get_stats().await;
let active_id = stats.active_key_id;
let server = manager.get_server_by_id(active_id).await;
assert!(server.is_some());
let non_existent = manager.get_server_by_id(active_id.wrapping_add(100)).await;
assert!(non_existent.is_none());
}
#[tokio::test]
async fn test_should_rotate() {
let config = KeyManagerConfig {
rotation_interval: Duration::from_millis(100), ..Default::default()
};
let manager = KeyManager::new(config).await.unwrap();
assert!(!manager.should_rotate().await);
tokio::time::sleep(Duration::from_millis(200)).await;
assert!(manager.should_rotate().await);
}
#[tokio::test]
async fn test_get_encoded_config() {
let config = KeyManagerConfig::default();
let manager = KeyManager::new(config).await.unwrap();
let encoded_config = manager.get_encoded_config().await.unwrap();
assert!(!encoded_config.is_empty());
assert!(encoded_config.len() > 2);
let length_prefix = u16::from_be_bytes([encoded_config[0], encoded_config[1]]);
assert_eq!(length_prefix as usize, encoded_config.len() - 2);
assert!(encoded_config.len() < 1000); }
#[tokio::test]
async fn test_multiple_cipher_suites() {
let config = KeyManagerConfig {
cipher_suites: vec![
CipherSuiteConfig {
kem: "X25519_SHA256".to_string(),
kdf: "HKDF_SHA256".to_string(),
aead: "AES_128_GCM".to_string(),
},
CipherSuiteConfig {
kem: "X25519_SHA256".to_string(),
kdf: "HKDF_SHA256".to_string(),
aead: "CHACHA20_POLY1305".to_string(),
},
],
..Default::default()
};
let manager = KeyManager::new(config).await.unwrap();
let stats = manager.get_stats().await;
assert_eq!(stats.total_keys, 1);
}
#[tokio::test]
async fn test_cleanup_expired_keys() {
let config = KeyManagerConfig {
rotation_interval: Duration::from_millis(50),
key_retention_period: Duration::from_millis(100),
auto_rotation_enabled: false, ..Default::default()
};
let manager = KeyManager::new(config).await.unwrap();
manager.rotate_keys().await.unwrap();
let stats_after_rotation = manager.get_stats().await;
assert_eq!(stats_after_rotation.total_keys, 2);
tokio::time::sleep(Duration::from_millis(200)).await;
manager.rotate_keys().await.unwrap();
let final_stats = manager.get_stats().await;
assert!(final_stats.total_keys <= 2);
}
#[tokio::test]
async fn test_bhttp_parsing() {
const REQUEST: &[u8] = &[
2, 3, 71, 69, 84, 5, 104, 116, 116, 112, 115, 9, 108, 111, 99, 97, 108, 104, 111, 115, 116,
4, 47, 103, 101, 116, 10, 117, 115, 101, 114, 45, 97, 103, 101, 110, 116, 21, 79, 72, 84,
84, 80, 45, 84, 101, 115, 116, 45, 67, 108, 105, 101, 110, 116, 47, 49, 46, 48, 6, 97, 99,
99, 101, 112, 116, 16, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 106, 115,
111, 110, 0, 0, 0,
];
let m = Message::read_bhttp(&mut Cursor::new(REQUEST)).unwrap();
assert!(m.header().get(b"accept").is_some());
}