#[cfg(test)] mod smoke_tests { use super::*; use serde_json::json; use tokio::net::TcpStream; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use std::time::Duration; use tokio::time; #[tokio::test] async fn test_server_startup() { // Запуск сервера в фоновом режиме let config: Value = toml::from_str(r#" [server] ip = "127.0.0.1" port = 9090 log_path = "smoke_test.log" [client] ip = "127.0.0.1" port = 9090 [replication] enabled = false peer_nodes = [] sync_interval = 1000 [http_api] enabled = false port = 9091 "#).unwrap(); let server = FutriixServer::new(&config); let addr = "127.0.0.1:9090".to_string(); tokio::spawn(async move { if let Err(e) = server.run(&addr).await { eprintln!("Server error: {}", e); } }); // Даем серверу время на запуск time::sleep(Duration::from_millis(100)).await; // Проверка подключения match TcpStream::connect("127.0.0.1:9090").await { Ok(_) => println!("Server is running"), Err(e) => panic!("Failed to connect to server: {}", e), } } #[tokio::test] async fn test_basic_operations() { let config: Value = toml::from_str(r#" [server] ip = "127.0.0.1" port = 9092 log_path = "smoke_test_ops.log" [client] ip = "127.0.0.1" port = 9092 [replication] enabled = false peer_nodes = [] sync_interval = 1000 [http_api] enabled = false port = 9093 "#).unwrap(); let server = FutriixServer::new(&config); let addr = "127.0.0.1:9092".to_string(); tokio::spawn(async move { if let Err(e) = server.run(&addr).await { eprintln!("Server error: {}", e); } }); // Даем серверу время на запуск time::sleep(Duration::from_millis(100)).await; // Подключаемся к серверу let mut stream = TcpStream::connect("127.0.0.1:9092").await.unwrap(); // Тест вставки let insert_cmd = Command::Insert { key: "smoke_key".to_string(), value: json!({"test": "value"}), }; send_command(&mut stream, &insert_cmd).await.unwrap(); // Тест получения let get_cmd = Command::Get { key: "smoke_key".to_string(), version: None, }; let response = send_command(&mut stream, &get_cmd).await.unwrap(); assert!(matches!(response, Response::Success(Some(_)))); if let Response::Success(Some(value)) = response { assert_eq!(value, json!({"test": "value"})); } // Тест обновления let update_cmd = Command::Update { key: "smoke_key".to_string(), value: json!({"test": "updated"}), }; send_command(&mut stream, &update_cmd).await.unwrap(); // Проверка обновления let get_cmd = Command::Get { key: "smoke_key".to_string(), version: None, }; let response = send_command(&mut stream, &get_cmd).await.unwrap(); assert!(matches!(response, Response::Success(Some(_)))); if let Response::Success(Some(value)) = response { assert_eq!(value, json!({"test": "updated"})); } // Тест удаления let delete_cmd = Command::Delete { key: "smoke_key".to_string(), }; send_command(&mut stream, &delete_cmd).await.unwrap(); // Проверка удаления let get_cmd = Command::Get { key: "smoke_key".to_string(), version: None, }; let response = send_command(&mut stream, &get_cmd).await.unwrap(); assert!(matches!(response, Response::Error(_))); } async fn send_command(stream: &mut TcpStream, cmd: &Command) -> Result> { let cmd_bytes = rmp_serde::to_vec(cmd)?; let len = cmd_bytes.len() as u32; stream.write_all(&len.to_be_bytes()).await?; stream.write_all(&cmd_bytes).await?; let mut len_buf = [0u8; 4]; stream.read_exact(&mut len_buf).await?; let len = u32::from_be_bytes(len_buf) as usize; let mut buf = vec![0u8; len]; stream.read_exact(&mut buf).await?; Ok(rmp_serde::from_slice(&buf)?) } }