183 lines
6.4 KiB
Rust
183 lines
6.4 KiB
Rust
|
// 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);
|
|||
|
}
|