CD/CI git build workflow and unit testing + dependabot intergration for security updates

This commit is contained in:
Chaos Rogers 2025-07-18 12:50:53 +01:00
parent bd2111d77a
commit a6523bf105
6 changed files with 182 additions and 15 deletions

View file

@ -77,6 +77,17 @@ impl LtcState {
match frame.status.as_str() {
"LOCK" => {
self.lock_count += 1;
// Every 5 seconds, recompute whether HH:MM:SS matches local time
let now_secs = Utc::now().timestamp();
if now_secs - self.last_match_check >= 5 {
self.last_match_status = if frame.matches_system_time() {
"IN SYNC".into()
} else {
"OUT OF SYNC".into()
};
self.last_match_check = now_secs;
}
}
"FREE" => {
self.free_count += 1;
@ -86,17 +97,6 @@ impl LtcState {
_ => {}
}
// Every 5 seconds, recompute whether HH:MM:SS matches local time
let now_secs = Utc::now().timestamp();
if now_secs - self.last_match_check >= 5 {
self.last_match_status = if frame.matches_system_time() {
"IN SYNC".into()
} else {
"OUT OF SYNC".into()
};
self.last_match_check = now_secs;
}
self.latest = Some(frame);
}
@ -135,3 +135,72 @@ impl LtcState {
&self.last_match_status
}
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::{Local, Utc};
fn get_test_frame(status: &str, h: u32, m: u32, s: u32) -> LtcFrame {
LtcFrame {
status: status.to_string(),
hours: h,
minutes: m,
seconds: s,
frames: 0,
frame_rate: 25.0,
timestamp: Utc::now(),
}
}
#[test]
fn test_ltc_frame_matches_system_time() {
let now = Local::now();
let frame = get_test_frame("LOCK", now.hour(), now.minute(), now.second());
assert!(frame.matches_system_time());
}
#[test]
fn test_ltc_frame_does_not_match_system_time() {
let now = Local::now();
// Create a time that is one hour ahead, wrapping around 23:00
let different_hour = (now.hour() + 1) % 24;
let frame = get_test_frame("LOCK", different_hour, now.minute(), now.second());
assert!(!frame.matches_system_time());
}
#[test]
fn test_ltc_state_update_lock() {
let mut state = LtcState::new();
let frame = get_test_frame("LOCK", 10, 20, 30);
state.update(frame);
assert_eq!(state.lock_count, 1);
assert_eq!(state.free_count, 0);
assert!(state.latest.is_some());
}
#[test]
fn test_ltc_state_update_free() {
let mut state = LtcState::new();
state.record_offset(100);
assert!(!state.offset_history.is_empty());
let frame = get_test_frame("FREE", 10, 20, 30);
state.update(frame);
assert_eq!(state.lock_count, 0);
assert_eq!(state.free_count, 1);
assert!(state.offset_history.is_empty()); // Offsets should be cleared
assert_eq!(state.last_match_status, "UNKNOWN");
}
#[test]
fn test_offset_history_management() {
let mut state = LtcState::new();
for i in 0..25 {
state.record_offset(i);
}
assert_eq!(state.offset_history.len(), 20);
assert_eq!(*state.offset_history.front().unwrap(), 5); // 0-4 are pushed out
assert_eq!(*state.offset_history.back().unwrap(), 24);
}
}