#![allow(dead_code)]
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct WatchDogConfig {
pub timeout_ms: u64,
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct WatchDog {
pub config: WatchDogConfig,
last_kick_tick: u64,
current_tick: u64,
kick_count: u64,
}
#[allow(dead_code)]
pub fn default_watch_dog_config() -> WatchDogConfig {
WatchDogConfig { timeout_ms: 5000 }
}
#[allow(dead_code)]
pub fn new_watch_dog(config: WatchDogConfig) -> WatchDog {
WatchDog { config, last_kick_tick: 0, current_tick: 0, kick_count: 0 }
}
#[allow(dead_code)]
pub fn advance_tick(wd: &mut WatchDog, delta_ms: u64) {
wd.current_tick += delta_ms;
}
#[allow(dead_code)]
pub fn kick_watch_dog(wd: &mut WatchDog) {
wd.last_kick_tick = wd.current_tick;
wd.kick_count += 1;
}
#[allow(dead_code)]
pub fn watch_dog_elapsed_ms(wd: &WatchDog) -> u64 {
wd.current_tick.saturating_sub(wd.last_kick_tick)
}
#[allow(dead_code)]
pub fn watch_dog_timeout_ms(wd: &WatchDog) -> u64 {
wd.config.timeout_ms
}
#[allow(dead_code)]
pub fn watch_dog_is_expired(wd: &WatchDog) -> bool {
watch_dog_elapsed_ms(wd) > wd.config.timeout_ms
}
#[allow(dead_code)]
pub fn reset_watch_dog(wd: &mut WatchDog) {
wd.current_tick = 0;
wd.last_kick_tick = 0;
wd.kick_count = 0;
}
#[allow(dead_code)]
pub fn watch_dog_kick_count(wd: &WatchDog) -> u64 {
wd.kick_count
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_watch_dog() {
let wd = new_watch_dog(default_watch_dog_config());
assert_eq!(watch_dog_elapsed_ms(&wd), 0);
assert!(!watch_dog_is_expired(&wd));
}
#[test]
fn test_kick_resets_elapsed() {
let mut wd = new_watch_dog(default_watch_dog_config());
advance_tick(&mut wd, 1000);
kick_watch_dog(&mut wd);
assert_eq!(watch_dog_elapsed_ms(&wd), 0);
}
#[test]
fn test_expiry() {
let mut wd = new_watch_dog(WatchDogConfig { timeout_ms: 100 });
advance_tick(&mut wd, 200);
assert!(watch_dog_is_expired(&wd));
}
#[test]
fn test_not_expired_before_timeout() {
let mut wd = new_watch_dog(WatchDogConfig { timeout_ms: 1000 });
advance_tick(&mut wd, 500);
assert!(!watch_dog_is_expired(&wd));
}
#[test]
fn test_kick_count() {
let mut wd = new_watch_dog(default_watch_dog_config());
kick_watch_dog(&mut wd);
kick_watch_dog(&mut wd);
assert_eq!(watch_dog_kick_count(&wd), 2);
}
#[test]
fn test_reset_watch_dog() {
let mut wd = new_watch_dog(default_watch_dog_config());
advance_tick(&mut wd, 500);
kick_watch_dog(&mut wd);
reset_watch_dog(&mut wd);
assert_eq!(watch_dog_elapsed_ms(&wd), 0);
assert_eq!(watch_dog_kick_count(&wd), 0);
}
#[test]
fn test_timeout_ms() {
let wd = new_watch_dog(WatchDogConfig { timeout_ms: 2000 });
assert_eq!(watch_dog_timeout_ms(&wd), 2000);
}
#[test]
fn test_elapsed_after_advance() {
let mut wd = new_watch_dog(default_watch_dog_config());
advance_tick(&mut wd, 300);
assert_eq!(watch_dog_elapsed_ms(&wd), 300);
}
}