use std::str::FromStr; use vault_service::{ service::KmsService, types::{EncryptionContext, KeySpec, KmsBackendConfig}, }; /// Test encryption context #[tokio::test] async fn test_encryption_context() { let mut ctx = EncryptionContext::new(); ctx.add("environment", "test"); ctx.add("service", "integration-test"); assert_eq!(ctx.context.len(), 2); assert_eq!(ctx.context.get("environment").unwrap(), "test"); let ctx_str = ctx.to_string(); assert!(ctx_str.contains("environment=test")); assert!(ctx_str.contains("service=integration-test")); let parsed = EncryptionContext::from_str(&ctx_str).unwrap(); assert_eq!(parsed.context.len(), 2); } /// Test key spec sizes #[test] fn test_key_spec_sizes() { assert_eq!(KeySpec::Aes128.key_size(), 16); assert_eq!(KeySpec::Aes256.key_size(), 32); assert_eq!(KeySpec::Rsa2048.key_size(), 256); assert_eq!(KeySpec::Rsa4096.key_size(), 512); } // /// Test Vault backend initialization (requires Vault running) // #[tokio::test] // #[ignore] // Ignore by default, run with --ignored flag when Vault is // available async fn test_vault_backend_init() { // let config = KmsBackendConfig::Vault { // address: "http://localhost:8200".to_string(), // token: std::env::var("VAULT_TOKEN").expect("VAULT_TOKEN not set"), // mount_point: "transit".to_string(), // namespace: None, // auto_renew_token: false, // }; // // let service = KmsService::new(config).await; // assert!(service.is_ok(), "Failed to initialize Vault backend"); // // let service = service.unwrap(); // assert_eq!(service.get_backend_name(), "vault"); // } // AWS KMS backend not yet implemented // Test AWS KMS backend initialization (requires AWS credentials) // #[tokio::test] // #[ignore] // Ignore by default, run with --ignored flag when AWS is // configured async fn test_aws_kms_backend_init() { // let key_id = std::env::var("AWS_KMS_KEY_ID").expect("AWS_KMS_KEY_ID not // set"); // // let config = KmsBackendConfig::AwsKms { // region: "us-east-1".to_string(), // key_id, // assume_role: None, // }; // // let service = KmsService::new(config).await; // assert!(service.is_ok(), "Failed to initialize AWS KMS backend"); // // let service = service.unwrap(); // assert_eq!(service.get_backend_name(), "aws-kms"); // } // /// Test encryption and decryption round-trip with Vault // #[tokio::test] // #[ignore] // Requires Vault // async fn test_vault_encrypt_decrypt_roundtrip() { // let config = KmsBackendConfig::Vault { // address: "http://localhost:8200".to_string(), // token: std::env::var("VAULT_TOKEN").expect("VAULT_TOKEN not set"), // mount_point: "transit".to_string(), // namespace: None, // auto_renew_token: false, // }; // // let service = KmsService::new(config).await.unwrap(); // // let plaintext = b"Hello, Vault KMS!"; // let mut context = EncryptionContext::new(); // context.add("test", "integration"); // // // Encrypt // let ciphertext = service.encrypt(plaintext, &context).await.unwrap(); // assert!(!ciphertext.is_empty()); // assert_ne!(ciphertext, plaintext); // // // Decrypt // let decrypted = service.decrypt(&ciphertext, &context).await.unwrap(); // assert_eq!(decrypted, plaintext); // } // // /// Test encryption and decryption round-trip with AWS KMS // #[tokio::test] // #[ignore] // Requires AWS KMS // async fn test_aws_kms_encrypt_decrypt_roundtrip() { // let key_id = std::env::var("AWS_KMS_KEY_ID").expect("AWS_KMS_KEY_ID not // set"); // // let config = KmsBackendConfig::AwsKms { // region: "us-east-1".to_string(), // key_id, // assume_role: None, // }; // // let service = KmsService::new(config).await.unwrap(); // // let plaintext = b"Hello, AWS KMS!"; // let mut context = EncryptionContext::new(); // context.add("test", "integration"); // // // Encrypt // let ciphertext = service.encrypt(plaintext, &context).await.unwrap(); // assert!(!ciphertext.is_empty()); // assert_ne!(ciphertext, plaintext); // // // Decrypt // let decrypted = service.decrypt(&ciphertext, &context).await.unwrap(); // assert_eq!(decrypted, plaintext); // } // // /// Test data key generation with AWS KMS // #[tokio::test] // #[ignore] // Requires AWS KMS // async fn test_aws_kms_generate_data_key() { // let key_id = std::env::var("AWS_KMS_KEY_ID").expect("AWS_KMS_KEY_ID not // set"); // // let config = KmsBackendConfig::AwsKms { // region: "us-east-1".to_string(), // key_id, // assume_role: None, // }; // // let service = KmsService::new(config).await.unwrap(); // // // Generate AES-256 data key // let data_key = // service.generate_data_key(&KeySpec::Aes256).await.unwrap(); // // assert_eq!(data_key.plaintext.len(), 32); // 256 bits = 32 bytes // assert!(!data_key.ciphertext.is_empty()); // assert!(!data_key.key_id.is_empty()); // } // // /// Test envelope encryption with AWS KMS // #[tokio::test] // #[ignore] // Requires AWS KMS // async fn test_aws_kms_envelope_encryption() { // let key_id = std::env::var("AWS_KMS_KEY_ID").expect("AWS_KMS_KEY_ID not // set"); // // let config = KmsBackendConfig::AwsKms { // region: "us-east-1".to_string(), // key_id, // assume_role: None, // }; // // let service = KmsService::new(config).await.unwrap(); // // let plaintext = b"Hello, envelope encryption!"; // // // Envelope encrypt // let envelope_ciphertext = // service.envelope_encrypt(plaintext).await.unwrap(); assert!(! // envelope_ciphertext.is_empty()); // // // Envelope decrypt // let decrypted = // service.envelope_decrypt(&envelope_ciphertext).await.unwrap(); assert_eq! // (decrypted, plaintext); } /// Test health check #[tokio::test] #[ignore] // Requires backend async fn test_health_check() { let config = KmsBackendConfig::Rustyvault { server_url: "http://localhost:8200".to_string(), token: std::env::var("RUSTYVAULT_TOKEN").ok(), mount_point: "transit".to_string(), key_name: "test-key".to_string(), tls_verify: false, }; let service = KmsService::new(config).await.unwrap(); let healthy = service.health_check().await.unwrap(); assert!(healthy); } /// Test operations counter #[tokio::test] async fn test_operations_counter() { // Use a mock or test config let config = KmsBackendConfig::Rustyvault { server_url: "http://localhost:8200".to_string(), token: Some("test-token".to_string()), mount_point: "transit".to_string(), key_name: "test-key".to_string(), tls_verify: false, }; if let Ok(service) = KmsService::new(config).await { let initial_count = service.get_operations_count().await; assert_eq!(initial_count, 0); // get_uptime() returns u64, always >= 0 by type let _uptime = service.get_uptime(); } } /// Test context-based encryption (ensures context is enforced) #[tokio::test] #[ignore] // Requires backend async fn test_context_enforcement() { let config = KmsBackendConfig::Rustyvault { server_url: "http://localhost:8200".to_string(), token: std::env::var("RUSTYVAULT_TOKEN").ok(), mount_point: "transit".to_string(), key_name: "test-key".to_string(), tls_verify: false, }; let service = KmsService::new(config).await.unwrap(); let plaintext = b"Context-sensitive data"; let mut encrypt_context = EncryptionContext::new(); encrypt_context.add("purpose", "testing"); encrypt_context.add("level", "critical"); // Encrypt with context let ciphertext = service.encrypt(plaintext, &encrypt_context).await.unwrap(); // Try to decrypt with wrong context (should fail) let mut wrong_context = EncryptionContext::new(); wrong_context.add("purpose", "wrong"); let _result = service.decrypt(&ciphertext, &wrong_context).await; // Note: Vault enforces context, so this should fail // AWS KMS also enforces context when AAD is used } /// Performance test: measure encryption throughput #[tokio::test] #[ignore] // Performance test, run manually async fn test_encryption_performance() { let config = KmsBackendConfig::Rustyvault { server_url: "http://localhost:8200".to_string(), token: std::env::var("RUSTYVAULT_TOKEN").ok(), mount_point: "transit".to_string(), key_name: "test-key".to_string(), tls_verify: false, }; let service = KmsService::new(config).await.unwrap(); let plaintext = b"Performance test data"; let context = EncryptionContext::new(); let iterations = 100; let start = std::time::Instant::now(); for _ in 0..iterations { let _ = service.encrypt(plaintext, &context).await.unwrap(); } let elapsed = start.elapsed(); let ops_per_sec = iterations as f64 / elapsed.as_secs_f64(); println!( "Encryption throughput: {:.2} ops/sec ({} iterations in {:.2}s)", ops_per_sec, iterations, elapsed.as_secs_f64() ); }