Init repo
This commit is contained in:
188
tests/integration_tests.rs.bak
Normal file
188
tests/integration_tests.rs.bak
Normal file
@@ -0,0 +1,188 @@
|
||||
// Integration tests for LLM Proxy Gateway
|
||||
|
||||
use llm_proxy::config::Config;
|
||||
use llm_proxy::database::Database;
|
||||
use llm_proxy::state::AppState;
|
||||
use llm_proxy::rate_limiting::RateLimitManager;
|
||||
use tempfile::TempDir;
|
||||
use std::fs;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_config_loading() {
|
||||
// Create a temporary config file
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let config_path = temp_dir.path().join("config.toml");
|
||||
|
||||
let config_content = r#"
|
||||
[server]
|
||||
port = 8080
|
||||
host = "0.0.0.0"
|
||||
|
||||
[database]
|
||||
path = "./data/test.db"
|
||||
max_connections = 5
|
||||
|
||||
[providers.openai]
|
||||
enabled = true
|
||||
base_url = "https://api.openai.com/v1"
|
||||
|
||||
[providers.gemini]
|
||||
enabled = true
|
||||
base_url = "https://generativelanguage.googleapis.com/v1"
|
||||
|
||||
[providers.deepseek]
|
||||
enabled = true
|
||||
base_url = "https://api.deepseek.com"
|
||||
|
||||
[providers.grok]
|
||||
enabled = false
|
||||
base_url = "https://api.x.ai/v1"
|
||||
|
||||
[model_mapping]
|
||||
"gpt-*" = "openai"
|
||||
"gemini-*" = "gemini"
|
||||
"deepseek-*" = "deepseek"
|
||||
"grok-*" = "grok"
|
||||
|
||||
[pricing]
|
||||
openai = { input = 0.01, output = 0.03 }
|
||||
gemini = { input = 0.0005, output = 0.0015 }
|
||||
deepseek = { input = 0.00014, output = 0.00028 }
|
||||
grok = { input = 0.001, output = 0.003 }
|
||||
"#;
|
||||
|
||||
fs::write(&config_path, config_content).unwrap();
|
||||
|
||||
// Test loading config
|
||||
let config = Config::load_from_path(&config_path);
|
||||
assert!(config.is_ok());
|
||||
|
||||
let config = config.unwrap();
|
||||
assert_eq!(config.server.port, 8080);
|
||||
assert!(config.providers.openai.is_some());
|
||||
assert!(config.providers.grok.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_database_initialization() {
|
||||
// Create a temporary database file
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let db_path = temp_dir.path().join("test.db");
|
||||
|
||||
// Test database initialization
|
||||
let database = Database::new(&db_path).await;
|
||||
assert!(database.is_ok());
|
||||
|
||||
let database = database.unwrap();
|
||||
|
||||
// Test connection
|
||||
let test_result = database.test_connection().await;
|
||||
assert!(test_result.is_ok());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_provider_manager() {
|
||||
// Create a provider manager
|
||||
use llm_proxy::providers::{ProviderManager, Provider};
|
||||
use llm_proxy::config::OpenAIConfig;
|
||||
|
||||
let mut manager = ProviderManager::new();
|
||||
assert_eq!(manager.providers.len(), 0);
|
||||
|
||||
// Test adding providers (we can't actually add real providers without API keys)
|
||||
// This test just verifies the manager structure works
|
||||
assert!(manager.get_provider_for_model("gpt-4").is_none());
|
||||
assert!(manager.get_provider("openai").is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_rate_limit_manager() {
|
||||
let manager = RateLimitManager::new(60, 10);
|
||||
|
||||
// Test client rate limiting
|
||||
let allowed = manager.check_request("test-client").await;
|
||||
assert!(allowed); // First request should be allowed
|
||||
|
||||
// Test provider circuit breaker
|
||||
let allowed = manager.check_provider("openai").await;
|
||||
assert!(allowed); // Circuit should be closed initially
|
||||
|
||||
// Record some failures
|
||||
manager.record_provider_failure("openai").await;
|
||||
manager.record_provider_failure("openai").await;
|
||||
manager.record_provider_failure("openai").await;
|
||||
manager.record_provider_failure("openai").await;
|
||||
manager.record_provider_failure("openai").await;
|
||||
|
||||
// After 5 failures, circuit should be open
|
||||
let allowed = manager.check_provider("openai").await;
|
||||
assert!(!allowed); // Circuit should be open
|
||||
|
||||
// Record success to close circuit
|
||||
manager.record_provider_success("openai").await;
|
||||
manager.record_provider_success("openai").await;
|
||||
manager.record_provider_success("openai").await;
|
||||
|
||||
// After 3 successes in half-open state, circuit should be closed
|
||||
let allowed = manager.check_provider("openai").await;
|
||||
assert!(allowed); // Circuit should be closed again
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_app_state_creation() {
|
||||
// Create a temporary database
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let db_path = temp_dir.path().join("test.db");
|
||||
|
||||
let database = Database::new(&db_path).await.unwrap();
|
||||
|
||||
// Test AppState creation using test utilities
|
||||
use llm_proxy::test_utils::create_test_state;
|
||||
let state = create_test_state().await;
|
||||
|
||||
// Verify state components are initialized
|
||||
assert!(state.database.test_connection().await.is_ok());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_multimodal_image_converter() {
|
||||
use llm_proxy::multimodal::{ImageConverter, ImageInput};
|
||||
|
||||
// Test model detection
|
||||
assert!(ImageConverter::model_supports_multimodal("gpt-4-vision-preview"));
|
||||
assert!(ImageConverter::model_supports_multimodal("gemini-pro-vision"));
|
||||
assert!(!ImageConverter::model_supports_multimodal("gpt-3.5-turbo"));
|
||||
assert!(!ImageConverter::model_supports_multimodal("gemini-pro"));
|
||||
|
||||
// Test data URL parsing (utility function)
|
||||
let test_url = "data:image/jpeg;base64,SGVsbG8gV29ybGQ=";
|
||||
let parts: Vec<&str> = test_url[5..].split(";base64,").collect();
|
||||
assert_eq!(parts.len(), 2);
|
||||
assert_eq!(parts[0], "image/jpeg");
|
||||
assert_eq!(parts[1], "SGVsbG8gV29ybGQ=");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_error_conversions() {
|
||||
use llm_proxy::errors::AppError;
|
||||
use anyhow::anyhow;
|
||||
|
||||
// Test anyhow error conversion
|
||||
let anyhow_error = anyhow!("Test error");
|
||||
let app_error: AppError = anyhow_error.into();
|
||||
|
||||
match app_error {
|
||||
AppError::InternalError(msg) => assert_eq!(msg, "Test error"),
|
||||
_ => panic!("Expected InternalError"),
|
||||
}
|
||||
|
||||
// Test sqlx error conversion
|
||||
use sqlx::Error as SqlxError;
|
||||
let sqlx_error = SqlxError::PoolClosed;
|
||||
let app_error: AppError = sqlx_error.into();
|
||||
|
||||
match app_error {
|
||||
AppError::DatabaseError(msg) => assert!(msg.contains("pool closed")),
|
||||
_ => panic!("Expected DatabaseError"),
|
||||
}
|
||||
}
|
||||
0
tests/streaming_test.rs
Normal file
0
tests/streaming_test.rs
Normal file
Reference in New Issue
Block a user