falcot/tests/integration_tests.rs
2025-09-12 00:40:20 +03:00

183 lines
6.4 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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);
}