// tests/integration_tests.rs #![allow(dead_code)] #![allow(unused_imports)] use falcot::server::database::{Database, Index, IndexType}; use falcot::common::protocol::Command; use serde_json::json; use std::sync::Arc; use tokio::time::{sleep, Duration}; /// Регрессионный тест - проверяем, что основные функции работают после изменений #[tokio::test] async fn regression_test() { let db = Arc::new(Database::new()); // Тестируем базовые CRUD операции let collection = db.get_collection("test"); // Create let doc_data = r#"{"name": "test", "value": 42}"#.as_bytes().to_vec(); let id = collection.create_document(doc_data.clone()).unwrap(); assert!(!id.is_empty()); // Read let document = collection.read_document(&id).unwrap().unwrap(); assert_eq!(document, doc_data); // Update let updated_data = r#"{"name": "test", "value": 43}"#.as_bytes().to_vec(); collection.update_document(&id, updated_data.clone()).unwrap(); // Delete collection.delete_document(&id).unwrap(); assert!(collection.read_document(&id).unwrap().is_none()); println!("Regression test passed"); } /// Unit-тест - тестируем конкретный модуль (индексы) #[tokio::test] async fn unit_test_indexes() { let db = Arc::new(Database::new()); let collection = db.get_collection("index_test"); // Создаем индекс let index = Index { name: "name_index".to_string(), index_type: IndexType::Secondary, field: "name".to_string(), unique: false, }; collection.create_index(index).unwrap(); // Добавляем документы let doc1 = json!({"name": "Alice", "age": 30}).to_string().into_bytes(); let doc2 = json!({"name": "Bob", "age": 25}).to_string().into_bytes(); let id1 = collection.create_document(doc1).unwrap(); let id2 = collection.create_document(doc2).unwrap(); // Ищем по индексу let alice_ids = collection.query_by_index("name_index", &json!("Alice")).unwrap(); assert_eq!(alice_ids, vec![id1]); let bob_ids = collection.query_by_index("name_index", &json!("Bob")).unwrap(); assert_eq!(bob_ids, vec![id2]); println!("Unit test for indexes passed"); } /// Smoke-тест - проверяем, что система запускается и базовые функции работают #[tokio::test] async fn smoke_test() { let db = Arc::new(Database::new()); // Проверяем, что можем создать коллекцию let collection = db.get_collection("smoke_test"); assert_eq!(collection.get_name(), "smoke_test"); // Проверяем, что можем выполнить команду let command = Command::Create { collection: "smoke_test".to_string(), document: r#"{"test": "data"}"#.as_bytes().to_vec(), }; let response = db.execute_command(command).unwrap(); assert!(matches!(response, falcot::common::protocol::Response::Success(_))); println!("Smoke test passed"); } /// Нагрузочный тест - проверяем производительность под нагрузкой #[tokio::test] async fn load_test() { let db = Arc::new(Database::new()); let collection = db.get_collection("load_test"); let start_time = std::time::Instant::now(); let mut tasks = Vec::new(); // Создаем 1000 документов параллельно for i in 0..1000 { let db_clone = db.clone(); tasks.push(tokio::spawn(async move { let command = Command::Create { collection: "load_test".to_string(), document: format!(r#"{{"id": {}, "data": "test_{}"}}"#, i, i).into_bytes(), }; db_clone.execute_command(command).unwrap(); })); } // Ждем завершения всех задач for task in tasks { task.await.unwrap(); } let duration = start_time.elapsed(); println!("Load test completed in {:?}", duration); // Проверяем, что все документы созданы let count = collection.count_documents().unwrap(); assert_eq!(count, 1000); assert!(duration.as_secs() < 5, "Load test took too long: {:?}", duration); } /// Стресс-тест - проверяем устойчивость системы при экстремальных условиях #[tokio::test] async fn stress_test() { let db = Arc::new(Database::new()); let collection = db.get_collection("stress_test"); let mut tasks = Vec::new(); // Создаем конкурирующие операции чтения/записи for i in 0..500 { let db_clone = db.clone(); // Задачи записи if i % 2 == 0 { tasks.push(tokio::spawn(async move { for j in 0..10 { let command = Command::Create { collection: "stress_test".to_string(), document: format!(r#"{{"thread": {}, "iteration": {}}}"#, i, j).into_bytes(), }; let _ = db_clone.execute_command(command); sleep(Duration::from_millis(10)).await; } })); } // Задачи чтения else { tasks.push(tokio::spawn(async move { for _ in 0..10 { let command = Command::Query { collection: "stress_test".to_string(), filter: vec![], }; let _ = db_clone.execute_command(command); sleep(Duration::from_millis(15)).await; } })); } } // Ждем завершения с таймаутом let result = tokio::time::timeout(Duration::from_secs(30), async { for task in tasks { task.await.unwrap(); } }).await; assert!(result.is_ok(), "Stress test timed out"); // Проверяем, что система не упала и данные сохранены let count = collection.count_documents().unwrap(); assert!(count > 0, "No documents were created during stress test"); println!("Stress test passed with {} documents", count); }