#[cfg(test)] mod regression_tests { use super::*; use serde_json::json; use std::sync::Arc; use parking_lot::RwLock; use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; #[test] fn test_insert_get_flow() { let db = Arc::new(RwLock::new(HashMap::new())); let server = FutriixServer { db: db.clone(), time_series_db: Arc::new(RwLock::new(HashMap::new())), command_queue: Arc::new(SegQueue::new()), transactions: Arc::new(RwLock::new(HashMap::new())), indexes: Arc::new(RwLock::new(HashMap::new())), replication_enabled: false, peer_nodes: Vec::new(), sync_interval: 1000, last_sync_timestamp: Arc::new(RwLock::new(0)), command_history: Arc::new(RwLock::new(Vec::new())), next_tx_id: Arc::new(RwLock::new(1)), }; // Тест базовой вставки и получения let insert_cmd = Command::Insert { key: "test_key".to_string(), value: json!({"field": "value"}), }; let response = server.process_command_internal(insert_cmd); assert!(matches!(response, Response::Success(None))); let get_cmd = Command::Get { key: "test_key".to_string(), version: None, }; let response = server.process_command_internal(get_cmd); assert!(matches!(response, Response::Success(Some(_)))); if let Response::Success(Some(value)) = response { assert_eq!(value, json!({"field": "value"})); } // Тест обновления let update_cmd = Command::Update { key: "test_key".to_string(), value: json!({"field": "new_value"}), }; let response = server.process_command_internal(update_cmd); assert!(matches!(response, Response::Success(None))); // Тест получения конкретной версии let get_cmd = Command::Get { key: "test_key".to_string(), version: Some(0), }; let response = server.process_command_internal(get_cmd); assert!(matches!(response, Response::Success(Some(_)))); if let Response::Success(Some(value)) = response { assert_eq!(value, json!({"field": "value"})); } // Тест удаления let delete_cmd = Command::Delete { key: "test_key".to_string(), }; let response = server.process_command_internal(delete_cmd); assert!(matches!(response, Response::Success(None))); // Проверка что данные действительно удалены let get_cmd = Command::Get { key: "test_key".to_string(), version: None, }; let response = server.process_command_internal(get_cmd); assert!(matches!(response, Response::Error(_))); } #[test] fn test_transaction_flow() { let db = Arc::new(RwLock::new(HashMap::new())); let server = FutriixServer { db: db.clone(), time_series_db: Arc::new(RwLock::new(HashMap::new())), command_queue: Arc::new(SegQueue::new()), transactions: Arc::new(RwLock::new(HashMap::new())), indexes: Arc::new(RwLock::new(HashMap::new())), replication_enabled: false, peer_nodes: Vec::new(), sync_interval: 1000, last_sync_timestamp: Arc::new(RwLock::new(0)), command_history: Arc::new(RwLock::new(Vec::new())), next_tx_id: Arc::new(RwLock::new(1)), }; // Начало транзакции let begin_cmd = Command::BeginTransaction; let response = server.process_command_internal(begin_cmd); let tx_id = if let Response::Success(Some(id)) = response { id.as_u64().unwrap() } else { panic!("Transaction begin failed"); }; // Вставка в транзакции let insert_cmd = Command::Insert { key: "tx_key".to_string(), value: json!({"tx": "data"}), }; let response = server.process_command_internal(insert_cmd); assert!(matches!(response, Response::Success(None))); // Проверка что данные не видны вне транзакции let get_cmd = Command::Get { key: "tx_key".to_string(), version: None, }; let response = server.process_command_internal(get_cmd); assert!(matches!(response, Response::Error(_))); // Коммит транзакции let commit_cmd = Command::CommitTransaction(tx_id); let response = server.process_command_internal(commit_cmd); assert!(matches!(response, Response::Success(None))); // Проверка что данные теперь видны let get_cmd = Command::Get { key: "tx_key".to_string(), version: None, }; let response = server.process_command_internal(get_cmd); assert!(matches!(response, Response::Success(Some(_)))); // Тест отката транзакции let begin_cmd = Command::BeginTransaction; let response = server.process_command_internal(begin_cmd); let tx_id = if let Response::Success(Some(id)) = response { id.as_u64().unwrap() } else { panic!("Transaction begin failed"); }; let insert_cmd = Command::Insert { key: "rollback_key".to_string(), value: json!({"should": "not_exist"}), }; let response = server.process_command_internal(insert_cmd); assert!(matches!(response, Response::Success(None))); let rollback_cmd = Command::RollbackTransaction(tx_id); let response = server.process_command_internal(rollback_cmd); assert!(matches!(response, Response::Success(None))); // Проверка что данные не сохранились let get_cmd = Command::Get { key: "rollback_key".to_string(), version: None, }; let response = server.process_command_internal(get_cmd); assert!(matches!(response, Response::Error(_))); } #[test] fn test_time_series_operations() { let db = Arc::new(RwLock::new(HashMap::new())); let server = FutriixServer { db: db.clone(), time_series_db: Arc::new(RwLock::new(HashMap::new())), command_queue: Arc::new(SegQueue::new()), transactions: Arc::new(RwLock::new(HashMap::new())), indexes: Arc::new(RwLock::new(HashMap::new())), replication_enabled: false, peer_nodes: Vec::new(), sync_interval: 1000, last_sync_timestamp: Arc::new(RwLock::new(0)), command_history: Arc::new(RwLock::new(Vec::new())), next_tx_id: Arc::new(RwLock::new(1)), }; let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_millis(); // Вставка временных рядов let ts_insert = Command::TimeSeriesInsert { key: "ts_data".to_string(), value: json!({"temp": 25}), timestamp: Some(now), }; let response = server.process_command_internal(ts_insert); assert!(matches!(response, Response::Success(None))); // Вставка без явного timestamp let ts_insert = Command::TimeSeriesInsert { key: "ts_data".to_string(), value: json!({"temp": 26}), timestamp: None, }; let response = server.process_command_internal(ts_insert); assert!(matches!(response, Response::Success(None))); // Запрос временных рядов let ts_query = Command::TimeSeriesQuery { key: "ts_data".to_string(), start: now - 1000, end: now + 1000, }; let response = server.process_command_internal(ts_query); assert!(matches!(response, Response::TimeSeriesData(_))); if let Response::TimeSeriesData(data) = response { assert!(data.len() >= 1); assert_eq!(data[0].1, json!({"temp": 25})); } } }