use std::time::SystemTime;
use crate::peer::{
data::{
PINGS_UNTIL_UNREACHABLE,
PINGS_UNTIL_SUSPICIOUS,
REPING_DELAY_MAX
},
link::{
self,
LinkTickResult
},
status
};
use crate::message::PingOrPong;
use super::*;
fn new_link() -> link::Link {
link::Link::new(dummy_address(0))
}
#[test_log::test(test)]
fn remaining() {
assert_eq!(status::remaining(None, Duration::MAX), None);
assert!(
status::remaining(Some(SystemTime::now()), Duration::MAX).unwrap()
<= Duration::MAX
);
let one_s = Duration::from_secs(1);
let three_s = Duration::from_secs(3);
let four_s = Duration::from_secs(4);
let three_s_ago = SystemTime::now() - three_s;
assert_eq!(
status::remaining(Some(three_s_ago), one_s),
None
);
assert!(
status::remaining(Some(three_s_ago), four_s).unwrap()
<= one_s
);
let in_three_s = SystemTime::now() + three_s;
assert_eq!(
status::remaining(Some(in_three_s), one_s),
None
);
}
#[test_log::test(test)]
fn tick() {
let first_tick = new_link().tick();
assert!(matches!(
first_tick,
LinkTickResult::PingDue(_)
));
let mut l = new_link();
l.has_pnged(PingOrPong::Ping);
let just_seen = l.tick();
assert!(matches!(
dbg!(just_seen),
LinkTickResult::Ok(_)
));
let mut l1 = new_link();
l1.has_pnged(PingOrPong::Ping);
let has_just_pinged = l1.tick();
let mut l2 = new_link();
l2.has_pnged(PingOrPong::Pong);
let has_just_ponged = l2.tick();
assert_ne!(
has_just_pinged,
has_just_ponged,
);
let pinged_d = if let LinkTickResult::Ok(t) = has_just_pinged {t} else {
panic!("has_just_pinged not Ok(t)");
};
let ponged_d = if let LinkTickResult::Ok(t) = has_just_ponged {t} else {
panic!("has_just_ponged not Ok(t)");
};
assert!(
pinged_d < ponged_d,
"if peer has just ponged then we sent the last ping, so we will wait a \
little longer to give them a chance to ping first this time.\n\
The peers \"take turns\" pinging to make sure they do not ping at the \
same time."
);
}
#[test_log::test(test)]
fn tick_flaky() {
let mut l3 = new_link();
l3.state = link::LinkState::BeenPinged(PINGS_UNTIL_SUSPICIOUS);
l3.pinged = Some(SystemTime::now() - REPING_DELAY_MAX);
let now_suspicious = l3.tick();
assert!(matches!(
dbg!(now_suspicious),
LinkTickResult::LinkSuspicious(_)
));
let mut l4 = new_link();
l4.state = link::LinkState::Suspicious(PINGS_UNTIL_UNREACHABLE);
l4.pinged = Some(SystemTime::now() - REPING_DELAY_MAX);
let now_unreachable = l4.tick();
assert!(matches!(
dbg!(now_unreachable),
LinkTickResult::LinkUnreachable
));
let mut l5 = new_link();
l5.state = link::LinkState::BeenPinged(0);
l5.pinged = Some(SystemTime::now() - REPING_DELAY_MAX);
let still_ok = l5.tick();
assert!(matches!(
dbg!(still_ok),
LinkTickResult::PingDue(_)
));
let mut l6 = new_link();
l6.state = link::LinkState::Suspicious(PINGS_UNTIL_SUSPICIOUS);
l6.pinged = Some(SystemTime::now() - REPING_DELAY_MAX);
let still_suspicious = l6.tick();
assert!(matches!(
dbg!(still_suspicious),
LinkTickResult::PingDue(_)
));
}