first
This commit is contained in:
151
agent/tests/test_file_transfer.rs
Normal file
151
agent/tests/test_file_transfer.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
// Created by: Claude
|
||||
// Date: 2026-01-04
|
||||
// Purpose: Tests unitaires pour le transfert de fichiers
|
||||
// Refs: protocol_events_v_2.md
|
||||
|
||||
use mesh_agent::p2p::protocol::FileMessage;
|
||||
|
||||
#[test]
|
||||
fn test_file_message_meta_serialization() {
|
||||
let meta = FileMessage::Meta {
|
||||
name: "test.txt".to_string(),
|
||||
size: 1024,
|
||||
hash: "abc123".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&meta).unwrap();
|
||||
let deserialized: FileMessage = serde_json::from_str(&json).unwrap();
|
||||
|
||||
match deserialized {
|
||||
FileMessage::Meta { name, size, hash } => {
|
||||
assert_eq!(name, "test.txt");
|
||||
assert_eq!(size, 1024);
|
||||
assert_eq!(hash, "abc123");
|
||||
}
|
||||
_ => panic!("Wrong variant"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_message_chunk_serialization() {
|
||||
let chunk = FileMessage::Chunk {
|
||||
offset: 1024,
|
||||
data: vec![1, 2, 3, 4, 5],
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&chunk).unwrap();
|
||||
let deserialized: FileMessage = serde_json::from_str(&json).unwrap();
|
||||
|
||||
match deserialized {
|
||||
FileMessage::Chunk { offset, data } => {
|
||||
assert_eq!(offset, 1024);
|
||||
assert_eq!(data, vec![1, 2, 3, 4, 5]);
|
||||
}
|
||||
_ => panic!("Wrong variant"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_message_done_serialization() {
|
||||
let done = FileMessage::Done {
|
||||
hash: "final_hash_123".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&done).unwrap();
|
||||
let deserialized: FileMessage = serde_json::from_str(&json).unwrap();
|
||||
|
||||
match deserialized {
|
||||
FileMessage::Done { hash } => {
|
||||
assert_eq!(hash, "final_hash_123");
|
||||
}
|
||||
_ => panic!("Wrong variant"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_blake3_hash() {
|
||||
use blake3::Hasher;
|
||||
|
||||
let data = b"Hello, Mesh!";
|
||||
let hash = Hasher::new().update(data).finalize().to_hex().to_string();
|
||||
|
||||
// Blake3 hash is 32 bytes = 64 hex chars
|
||||
assert_eq!(hash.len(), 64);
|
||||
|
||||
// Verify hash is deterministic
|
||||
let hash2 = Hasher::new().update(data).finalize().to_hex().to_string();
|
||||
assert_eq!(hash, hash2);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_blake3_chunked_hash() {
|
||||
use blake3::Hasher;
|
||||
|
||||
let data = b"Hello, Mesh! This is a longer message to test chunked hashing.";
|
||||
|
||||
// Hash all at once
|
||||
let hash_full = Hasher::new().update(data).finalize().to_hex().to_string();
|
||||
|
||||
// Hash in chunks
|
||||
let mut hasher = Hasher::new();
|
||||
hasher.update(&data[0..20]);
|
||||
hasher.update(&data[20..40]);
|
||||
hasher.update(&data[40..]);
|
||||
let hash_chunked = hasher.finalize().to_hex().to_string();
|
||||
|
||||
// Should be identical
|
||||
assert_eq!(hash_full, hash_chunked);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_message_tag_format() {
|
||||
let meta = FileMessage::Meta {
|
||||
name: "test.txt".to_string(),
|
||||
size: 100,
|
||||
hash: "hash".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&meta).unwrap();
|
||||
|
||||
// Verify it has the "t" field for type tag
|
||||
assert!(json.contains(r#""t":"FILE_META""#));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_length_prefixed_encoding() {
|
||||
use tokio::io::{AsyncWriteExt, AsyncReadExt};
|
||||
|
||||
let msg = FileMessage::Meta {
|
||||
name: "test.txt".to_string(),
|
||||
size: 1024,
|
||||
hash: "abc123".to_string(),
|
||||
};
|
||||
|
||||
// Encode
|
||||
let json = serde_json::to_vec(&msg).unwrap();
|
||||
let len = (json.len() as u32).to_be_bytes();
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
buffer.write_all(&len).await.unwrap();
|
||||
buffer.write_all(&json).await.unwrap();
|
||||
|
||||
// Decode
|
||||
let mut cursor = std::io::Cursor::new(buffer);
|
||||
let mut len_buf = [0u8; 4];
|
||||
cursor.read_exact(&mut len_buf).await.unwrap();
|
||||
let msg_len = u32::from_be_bytes(len_buf) as usize;
|
||||
|
||||
let mut msg_buf = vec![0u8; msg_len];
|
||||
cursor.read_exact(&mut msg_buf).await.unwrap();
|
||||
|
||||
let decoded: FileMessage = serde_json::from_slice(&msg_buf).unwrap();
|
||||
|
||||
match decoded {
|
||||
FileMessage::Meta { name, size, hash } => {
|
||||
assert_eq!(name, "test.txt");
|
||||
assert_eq!(size, 1024);
|
||||
assert_eq!(hash, "abc123");
|
||||
}
|
||||
_ => panic!("Wrong variant"),
|
||||
}
|
||||
}
|
||||
142
agent/tests/test_protocol.rs
Normal file
142
agent/tests/test_protocol.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
// Created by: Claude
|
||||
// Date: 2026-01-04
|
||||
// Purpose: Tests pour les protocoles P2P et terminal
|
||||
// Refs: protocol_events_v_2.md, signaling_v_2.md
|
||||
|
||||
use mesh_agent::p2p::protocol::*;
|
||||
|
||||
#[test]
|
||||
fn test_p2p_hello_serialization() {
|
||||
let hello = P2PHello {
|
||||
t: "P2P_HELLO".to_string(),
|
||||
session_id: "session_123".to_string(),
|
||||
session_token: "token_abc".to_string(),
|
||||
from_device_id: "device_456".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&hello).unwrap();
|
||||
let deserialized: P2PHello = serde_json::from_str(&json).unwrap();
|
||||
|
||||
assert_eq!(deserialized.t, "P2P_HELLO");
|
||||
assert_eq!(deserialized.session_id, "session_123");
|
||||
assert_eq!(deserialized.session_token, "token_abc");
|
||||
assert_eq!(deserialized.from_device_id, "device_456");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_p2p_response_ok() {
|
||||
let response = P2PResponse::Ok;
|
||||
|
||||
let json = serde_json::to_string(&response).unwrap();
|
||||
assert!(json.contains(r#""t":"P2P_OK""#));
|
||||
|
||||
let deserialized: P2PResponse = serde_json::from_str(&json).unwrap();
|
||||
match deserialized {
|
||||
P2PResponse::Ok => {}
|
||||
_ => panic!("Expected P2P_OK"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_p2p_response_deny() {
|
||||
let response = P2PResponse::Deny {
|
||||
reason: "Invalid token".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&response).unwrap();
|
||||
assert!(json.contains(r#""t":"P2P_DENY""#));
|
||||
assert!(json.contains("Invalid token"));
|
||||
|
||||
let deserialized: P2PResponse = serde_json::from_str(&json).unwrap();
|
||||
match deserialized {
|
||||
P2PResponse::Deny { reason } => {
|
||||
assert_eq!(reason, "Invalid token");
|
||||
}
|
||||
_ => panic!("Expected P2P_DENY"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_terminal_message_output() {
|
||||
let msg = TerminalMessage::Output {
|
||||
data: "$ ls -la\n".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&msg).unwrap();
|
||||
assert!(json.contains(r#""t":"TERM_OUT""#));
|
||||
|
||||
let deserialized: TerminalMessage = serde_json::from_str(&json).unwrap();
|
||||
match deserialized {
|
||||
TerminalMessage::Output { data } => {
|
||||
assert_eq!(data, "$ ls -la\n");
|
||||
}
|
||||
_ => panic!("Expected TERM_OUT"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_terminal_message_input() {
|
||||
let msg = TerminalMessage::Input {
|
||||
data: "echo hello\n".to_string(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&msg).unwrap();
|
||||
assert!(json.contains(r#""t":"TERM_IN""#));
|
||||
|
||||
let deserialized: TerminalMessage = serde_json::from_str(&json).unwrap();
|
||||
match deserialized {
|
||||
TerminalMessage::Input { data } => {
|
||||
assert_eq!(data, "echo hello\n");
|
||||
}
|
||||
_ => panic!("Expected TERM_IN"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_terminal_message_resize() {
|
||||
let msg = TerminalMessage::Resize {
|
||||
cols: 120,
|
||||
rows: 30,
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&msg).unwrap();
|
||||
assert!(json.contains(r#""t":"TERM_RESIZE""#));
|
||||
|
||||
let deserialized: TerminalMessage = serde_json::from_str(&json).unwrap();
|
||||
match deserialized {
|
||||
TerminalMessage::Resize { cols, rows } => {
|
||||
assert_eq!(cols, 120);
|
||||
assert_eq!(rows, 30);
|
||||
}
|
||||
_ => panic!("Expected TERM_RESIZE"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_message_types_have_type_field() {
|
||||
// FileMessage
|
||||
let file_meta = FileMessage::Meta {
|
||||
name: "test.txt".to_string(),
|
||||
size: 100,
|
||||
hash: "hash".to_string(),
|
||||
};
|
||||
let json = serde_json::to_string(&file_meta).unwrap();
|
||||
assert!(json.contains(r#""t":"FILE_META""#));
|
||||
|
||||
// P2P
|
||||
let hello = P2PHello {
|
||||
t: "P2P_HELLO".to_string(),
|
||||
session_id: "s1".to_string(),
|
||||
session_token: "t1".to_string(),
|
||||
from_device_id: "d1".to_string(),
|
||||
};
|
||||
let json = serde_json::to_string(&hello).unwrap();
|
||||
assert!(json.contains(r#""t":"P2P_HELLO""#));
|
||||
|
||||
// Terminal
|
||||
let term_out = TerminalMessage::Output {
|
||||
data: "output".to_string(),
|
||||
};
|
||||
let json = serde_json::to_string(&term_out).unwrap();
|
||||
assert!(json.contains(r#""t":"TERM_OUT""#));
|
||||
}
|
||||
Reference in New Issue
Block a user