#![cfg(feature = "crypto")]
use srt_runtime::km_refresh::{KeyParity, KmRefreshDriver, KmRefreshEvent, KmRefreshThresholds};
const REFRESH_PERIOD: u64 = KmRefreshThresholds::RECOMMENDED.refresh_period; const PRE_ANNOUNCE: u64 = KmRefreshThresholds::RECOMMENDED.pre_announcement_period;
#[test]
fn recommended_thresholds_are_the_spec_values() {
assert_eq!(REFRESH_PERIOD, 1u64 << 25);
assert_eq!(PRE_ANNOUNCE, 4000);
}
#[test]
fn pre_announce_fires_at_refresh_minus_pre_announce_packets() {
let mut driver = KmRefreshDriver::new(KmRefreshThresholds::RECOMMENDED, KeyParity::Even);
assert_eq!(driver.active_parity(), KeyParity::Even);
let short_of_threshold = REFRESH_PERIOD - PRE_ANNOUNCE - 1;
assert_eq!(driver.on_packet_sent(short_of_threshold), Vec::new());
assert_eq!(driver.active_parity(), KeyParity::Even);
let events = driver.on_packet_sent(1);
assert_eq!(
events,
vec![KmRefreshEvent::PreAnnounce {
next_parity: KeyParity::Odd
}]
);
assert_eq!(driver.active_parity(), KeyParity::Even);
assert!(driver.is_key_valid(KeyParity::Even));
assert!(!driver.is_key_valid(KeyParity::Odd));
}
#[test]
fn switchover_fires_at_refresh_period_and_changes_the_active_key() {
let mut driver = KmRefreshDriver::new(KmRefreshThresholds::RECOMMENDED, KeyParity::Even);
let events = driver.on_packet_sent(REFRESH_PERIOD - 1);
assert_eq!(
events,
vec![KmRefreshEvent::PreAnnounce {
next_parity: KeyParity::Odd
}],
"pre-announce must already have fired on the way here"
);
assert_eq!(
driver.active_parity(),
KeyParity::Even,
"not yet switched over"
);
let events = driver.on_packet_sent(1);
assert_eq!(
events,
vec![KmRefreshEvent::Switchover {
new_active: KeyParity::Odd
}]
);
assert_eq!(driver.active_parity(), KeyParity::Odd);
assert!(driver.is_key_valid(KeyParity::Odd), "new key is active");
assert!(
driver.is_key_valid(KeyParity::Even),
"old key must still be valid immediately after switchover"
);
}
#[test]
fn decommission_fires_at_refresh_plus_pre_announce_and_drops_the_old_key() {
let mut driver = KmRefreshDriver::new(KmRefreshThresholds::RECOMMENDED, KeyParity::Even);
let events = driver.on_packet_sent(REFRESH_PERIOD + PRE_ANNOUNCE - 1);
assert!(
events.contains(&KmRefreshEvent::Switchover {
new_active: KeyParity::Odd
}),
"switchover must already have fired: {events:?}"
);
assert!(
driver.is_key_valid(KeyParity::Even),
"old key still valid one packet before decommission"
);
let events = driver.on_packet_sent(1);
assert_eq!(
events,
vec![KmRefreshEvent::Decommission {
retired: KeyParity::Even
}]
);
assert_eq!(driver.active_parity(), KeyParity::Odd);
assert!(
!driver.is_key_valid(KeyParity::Even),
"old key must no longer be valid/held after decommission"
);
assert!(driver.is_key_valid(KeyParity::Odd));
}
#[test]
fn one_call_spanning_the_whole_recommended_window_fires_all_three_events_in_order() {
let mut driver = KmRefreshDriver::new(KmRefreshThresholds::RECOMMENDED, KeyParity::Even);
let events = driver.on_packet_sent(REFRESH_PERIOD + PRE_ANNOUNCE);
assert_eq!(
events,
vec![
KmRefreshEvent::PreAnnounce {
next_parity: KeyParity::Odd
},
KmRefreshEvent::Switchover {
new_active: KeyParity::Odd
},
KmRefreshEvent::Decommission {
retired: KeyParity::Even
},
]
);
assert_eq!(driver.active_parity(), KeyParity::Odd);
assert!(!driver.is_key_valid(KeyParity::Even));
}
#[test]
fn rotation_continues_into_a_second_cycle_with_the_real_thresholds() {
let mut driver = KmRefreshDriver::new(KmRefreshThresholds::RECOMMENDED, KeyParity::Even);
let events = driver.on_packet_sent(REFRESH_PERIOD + PRE_ANNOUNCE);
assert!(events.contains(&KmRefreshEvent::Switchover {
new_active: KeyParity::Odd
}));
assert_eq!(driver.active_parity(), KeyParity::Odd);
let events = driver.on_packet_sent(REFRESH_PERIOD + PRE_ANNOUNCE);
assert_eq!(
events,
vec![
KmRefreshEvent::PreAnnounce {
next_parity: KeyParity::Even
},
KmRefreshEvent::Switchover {
new_active: KeyParity::Even
},
KmRefreshEvent::Decommission {
retired: KeyParity::Odd
},
]
);
assert_eq!(driver.active_parity(), KeyParity::Even);
assert_eq!(driver.total_sent(), 2 * (REFRESH_PERIOD + PRE_ANNOUNCE));
}