falcot/tests/integration_tests.rs

183 lines
6.4 KiB
Rust
Raw Permalink Normal View History

2025-09-12 00:40:20 +03:00
// 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);
}