#![cfg(test)]
use std::sync::atomic::Ordering;
use std::sync::Arc;
use crate::devices::mmio_bus::MmioDevice;
use crate::devices::serial::{SerialPl011, SerialState};
fn fresh() -> (Arc<SerialState>, SerialPl011) {
let state = Arc::new(SerialState::new());
state.set_heartbeat_detection(true);
let dev = SerialPl011::new(state.clone());
(state, dev)
}
fn drive(dev: &SerialPl011, line: &str) {
for b in line.bytes() {
dev.write(0x000, b as u64, 1);
}
dev.write(0x000, b'\n' as u64, 1);
}
#[test]
fn captures_well_formed_state_gpa_line() {
let (st, dev) = fresh();
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0x83018000");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0x83018000);
}
#[test]
fn captures_with_surrounding_log_noise() {
let (st, dev) = fresh();
drive(
&dev,
"[ 0.123] init-oci: foo bar [SUPERMACHINE-SMPARK] state_gpa=0xdeadbeef extra trailing",
);
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0xdeadbeef);
}
#[test]
fn captures_max_u64_value() {
let (st, dev) = fresh();
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0xffffffffffffffff");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), u64::MAX);
}
#[test]
fn ignores_more_than_16_hex_chars_does_not_overflow() {
let (st, dev) = fresh();
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0x1234567890abcdef0");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0x1234567890abcdef);
}
#[test]
fn stops_at_first_non_hex_byte() {
let (st, dev) = fresh();
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0xabc trailing-junk");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0xabc);
}
#[test]
fn ignores_lines_without_the_prefix() {
let (st, dev) = fresh();
st.smpark_state_gpa.store(0xabcd1234, Ordering::SeqCst);
drive(&dev, "[NOT-SMPARK] state_gpa=0xdead");
drive(&dev, "init-oci: workload-pre-exec");
drive(&dev, "smpark: loaded; n_cpus=4 state_gpa=0xbeef");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0xabcd1234);
}
#[test]
fn case_sensitive_hex_a_through_f_supported() {
let (st, dev) = fresh();
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0xABCDEF");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0xabcdef);
}
#[test]
fn second_announcement_overwrites_first() {
let (st, dev) = fresh();
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0x1000");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0x1000);
drive(&dev, "[SUPERMACHINE-SMPARK] state_gpa=0x2000");
assert_eq!(st.smpark_state_gpa.load(Ordering::SeqCst), 0x2000);
}