use std::collections::HashMap;
use super::helpers::{minimal_hs, raw_connect, recv_ack, send_hs};
use crate::common::origin::OriginServer;
use nodedb_types::sync::wire::HandshakeMsg;
#[tokio::test]
async fn global_clock_encoding_is_accepted() {
let Some(_server) = OriginServer::try_spawn() else {
eprintln!("SKIP: Origin binary unavailable (set NODEDB_BIN or run via `cargo nextest`)");
return;
};
let mut ws = raw_connect(_server.ws_url).await;
let peer_hex = format!("{:016x}", 0xdeadbeef_u64);
let mut inner = HashMap::new();
inner.insert(peer_hex, 42_u64);
let mut clock = HashMap::new();
clock.insert("_global".to_string(), inner);
let hs = HandshakeMsg {
vector_clock: clock,
..minimal_hs()
};
send_hs(&mut ws, &hs).await;
let ack = recv_ack(&mut ws).await;
assert!(
ack.success,
"Origin must accept the _global clock encoding; error: {:?}",
ack.error
);
assert!(
!ack.session_id.is_empty(),
"session_id must be non-empty on success"
);
}
#[tokio::test]
async fn global_clock_reconnect_resumes_cleanly() {
let Some(_server) = OriginServer::try_spawn() else {
eprintln!("SKIP: Origin binary unavailable (set NODEDB_BIN or run via `cargo nextest`)");
return;
};
let peer_hex = format!("{:016x}", 0xc1_0c_u64);
let base_counter = 100_u64;
{
let mut ws = raw_connect(_server.ws_url).await;
let mut inner = HashMap::new();
inner.insert(peer_hex.clone(), base_counter);
let mut clock = HashMap::new();
clock.insert("_global".to_string(), inner);
let hs = HandshakeMsg {
vector_clock: clock,
..minimal_hs()
};
send_hs(&mut ws, &hs).await;
let ack = recv_ack(&mut ws).await;
assert!(ack.success, "first connect failed: {:?}", ack.error);
}
{
let mut ws = raw_connect(_server.ws_url).await;
let mut inner = HashMap::new();
inner.insert(peer_hex.clone(), base_counter);
let mut clock = HashMap::new();
clock.insert("_global".to_string(), inner);
let hs = HandshakeMsg {
vector_clock: clock,
..minimal_hs()
};
send_hs(&mut ws, &hs).await;
let ack = recv_ack(&mut ws).await;
assert!(
ack.success,
"reconnect with same clock failed: {:?}",
ack.error
);
assert!(!ack.fork_detected, "no fork when lite_id is empty");
}
{
let mut ws = raw_connect(_server.ws_url).await;
let mut inner = HashMap::new();
inner.insert(peer_hex.clone(), base_counter + 10);
let mut clock = HashMap::new();
clock.insert("_global".to_string(), inner);
let hs = HandshakeMsg {
vector_clock: clock,
..minimal_hs()
};
send_hs(&mut ws, &hs).await;
let ack = recv_ack(&mut ws).await;
assert!(
ack.success,
"reconnect with advanced clock failed: {:?}",
ack.error
);
}
}
#[tokio::test]
async fn empty_clock_accepted_for_fresh_device() {
let Some(_server) = OriginServer::try_spawn() else {
eprintln!("SKIP: Origin binary unavailable (set NODEDB_BIN or run via `cargo nextest`)");
return;
};
let mut ws = raw_connect(_server.ws_url).await;
send_hs(&mut ws, &minimal_hs()).await;
let ack = recv_ack(&mut ws).await;
assert!(
ack.success,
"empty clock (fresh device) must be accepted; error: {:?}",
ack.error
);
}