use std::time::Instant;
use ableton_link_rs::link::BasicLink;
use tokio::time::{sleep, Duration};
use tracing::info;
fn init_tracing() {
let _ = tracing_subscriber::fmt::try_init();
}
#[tokio::test]
async fn test_peer_timeout_when_disabled() {
init_tracing();
sleep(Duration::from_millis(100)).await;
let mut link1 = BasicLink::new(120.0).await;
let mut link2 = BasicLink::new(120.0).await;
link1.enable().await;
link2.enable().await;
info!("Both Link instances enabled, waiting for peer discovery...");
let mut discovered = false;
for i in 0..100 {
sleep(Duration::from_millis(100)).await;
let peers1 = link1.num_peers();
let peers2 = link2.num_peers();
if i % 10 == 0 {
info!(
"Discovery attempt {}/100: Link1 peers: {}, Link2 peers: {}",
i, peers1, peers2
);
}
if peers1 >= 1 && peers2 >= 1 {
discovered = true;
info!(
"Peer discovery successful at attempt {}: Link1={}, Link2={}",
i, peers1, peers2
);
break;
}
}
assert!(
discovered,
"Peers should discover each other within 10 seconds"
);
info!("Peer discovery successful!");
let disable_time = Instant::now();
link2.disable().await;
info!("Disabled Link2, measuring response time...");
let mut peer_count_updated = false;
let mut response_duration = Duration::from_secs(0);
for i in 0..50 {
sleep(Duration::from_millis(100)).await;
let peers1 = link1.num_peers();
if i % 5 == 0 {
info!(
"Disable detection attempt {}/50: Link1 peers: {}",
i, peers1
);
}
if peers1 == 0 {
response_duration = disable_time.elapsed();
peer_count_updated = true;
info!(
"Peer disable detected at attempt {}, duration: {:?}",
i, response_duration
);
break;
}
}
assert!(
peer_count_updated,
"Link1 should detect Link2 disable within 5 seconds"
);
info!("Peer count updated after {:?}", response_duration);
assert!(
response_duration < Duration::from_millis(3000),
"When Link2 sends bye-bye on disable, Link1 should respond within 3 seconds, but took {:?}",
response_duration
);
info!(
"✅ Peer disable response test passed! Update occurred in {:?}",
response_duration
);
link1.disable().await;
link2.disable().await;
sleep(Duration::from_millis(100)).await;
}
#[tokio::test]
async fn test_peer_rejoin_after_timeout() {
init_tracing();
sleep(Duration::from_millis(200)).await;
let mut link1 = BasicLink::new(120.0).await;
let mut link2 = BasicLink::new(120.0).await;
link1.enable().await;
link2.enable().await;
let mut discovered = false;
for i in 0..100 {
sleep(Duration::from_millis(100)).await;
let peers1 = link1.num_peers();
let peers2 = link2.num_peers();
if i % 10 == 0 {
info!(
"Initial discovery attempt {}/100: Link1 peers: {}, Link2 peers: {}",
i, peers1, peers2
);
}
if peers1 >= 1 && peers2 >= 1 {
discovered = true;
info!("Initial peer discovery successful at attempt {}", i);
break;
}
}
assert!(discovered, "Initial peer discovery failed");
link2.disable().await;
for _ in 0..60 {
sleep(Duration::from_millis(100)).await;
if link1.num_peers() == 0 {
break;
}
}
assert_eq!(link1.num_peers(), 0, "Link1 should detect Link2 timeout");
link2.enable().await;
info!("Re-enabled Link2, waiting for rediscovery...");
let mut rediscovered = false;
for i in 0..100 {
sleep(Duration::from_millis(100)).await;
let peers1 = link1.num_peers();
let peers2 = link2.num_peers();
if i % 10 == 0 {
info!(
"Rediscovery attempt {}/100: Link1 peers: {}, Link2 peers: {}",
i, peers1, peers2
);
}
if peers1 >= 1 && peers2 >= 1 {
rediscovered = true;
info!("Rediscovery successful at attempt {}", i);
break;
}
}
assert!(
rediscovered,
"Peers should rediscover each other after re-enable"
);
info!("✅ Peer rejoin test passed!");
link1.disable().await;
link2.disable().await;
sleep(Duration::from_millis(100)).await;
}