use canlink_hal::{BackendConfig, CanBackend, CanMessage};
use canlink_mock::MockBackend;
#[test]
fn test_hardware_disconnect_detection() {
let mut backend = MockBackend::new();
backend.initialize(&BackendConfig::new("mock")).unwrap();
backend.open_channel(0).unwrap();
let msg = CanMessage::new_standard(0x100, &[1, 2, 3]).unwrap();
assert!(backend.send_message(&msg).is_ok());
backend.simulate_disconnect();
assert!(backend.is_disconnected());
let msg = CanMessage::new_standard(0x200, &[4, 5, 6]).unwrap();
let result = backend.send_message(&msg);
assert!(result.is_err());
let result = backend.receive_message();
assert!(result.is_err());
backend.simulate_reconnect();
assert!(!backend.is_disconnected());
let msg = CanMessage::new_standard(0x300, &[7, 8, 9]).unwrap();
assert!(backend.send_message(&msg).is_ok());
}
#[test]
fn test_disconnect_reconnect_cycle() {
let mut backend = MockBackend::new();
backend.initialize(&BackendConfig::new("mock")).unwrap();
backend.open_channel(0).unwrap();
for i in 0..10 {
let msg = CanMessage::new_standard(0x100 + i, &[i as u8]).unwrap();
assert!(backend.send_message(&msg).is_ok());
backend.simulate_disconnect();
assert!(backend.is_disconnected());
backend.simulate_reconnect();
assert!(!backend.is_disconnected());
}
let recorded = backend.get_recorded_messages();
assert_eq!(recorded.len(), 10);
}
#[test]
fn test_queue_overflow_drop_oldest() {
use canlink_hal::queue::{BoundedQueue, QueueOverflowPolicy};
let mut queue = BoundedQueue::with_policy(5, QueueOverflowPolicy::DropOldest);
for i in 0..10u16 {
let msg = CanMessage::new_standard(0x100 + i, &[i as u8]).unwrap();
queue.push(msg).unwrap();
}
assert_eq!(queue.len(), 5);
let first = queue.pop().unwrap();
assert_eq!(first.id().raw(), 0x105);
let stats = queue.stats();
assert_eq!(stats.dropped, 5);
assert_eq!(stats.overflow_count, 5);
}
#[test]
fn test_queue_overflow_drop_newest() {
use canlink_hal::queue::{BoundedQueue, QueueOverflowPolicy};
let mut queue = BoundedQueue::with_policy(5, QueueOverflowPolicy::DropNewest);
for i in 0..10u16 {
let msg = CanMessage::new_standard(0x100 + i, &[i as u8]).unwrap();
let _ = queue.push(msg); }
assert_eq!(queue.len(), 5);
let first = queue.pop().unwrap();
assert_eq!(first.id().raw(), 0x100);
let stats = queue.stats();
assert_eq!(stats.dropped, 5);
}
#[test]
fn test_repeated_open_close_no_leak() {
for _ in 0..100 {
let mut backend = MockBackend::new();
backend.initialize(&BackendConfig::new("mock")).unwrap();
backend.open_channel(0).unwrap();
for i in 0..10u16 {
let msg = CanMessage::new_standard(i, &[i as u8]).unwrap();
backend.send_message(&msg).unwrap();
}
backend.close_channel(0).unwrap();
backend.close().unwrap();
}
}
#[test]
fn test_filter_with_disconnect() {
let mut backend = MockBackend::new();
backend.initialize(&BackendConfig::new("mock")).unwrap();
backend.open_channel(0).unwrap();
backend.add_id_filter(0x100);
backend.add_id_filter(0x200);
assert_eq!(backend.filter_count(), 2);
backend.simulate_disconnect();
backend.simulate_reconnect();
assert_eq!(backend.filter_count(), 2);
}
#[test]
fn test_backend_state_after_error() {
use canlink_hal::BackendState;
let mut backend = MockBackend::new();
backend.initialize(&BackendConfig::new("mock")).unwrap();
backend.open_channel(0).unwrap();
assert_eq!(backend.get_state(), BackendState::Ready);
backend.simulate_disconnect();
assert_eq!(backend.get_state(), BackendState::Error);
backend.simulate_reconnect();
assert_eq!(backend.get_state(), BackendState::Ready);
}
#[test]
fn test_message_rate_monitor() {
use canlink_hal::MessageRateMonitor;
let mut monitor = MessageRateMonitor::new(100);
for _ in 0..50 {
let exceeded = monitor.record_message();
assert!(!exceeded); }
assert_eq!(monitor.current_count(), 50);
assert_eq!(monitor.threshold(), 100);
}
#[test]
fn test_switch_backend() {
use canlink_hal::switch_backend;
let mut old_backend = MockBackend::new();
old_backend.initialize(&BackendConfig::new("mock")).unwrap();
old_backend.open_channel(0).unwrap();
for i in 0..5u16 {
let msg = CanMessage::new_standard(0x100 + i, &[i as u8]).unwrap();
old_backend.send_message(&msg).unwrap();
}
let mut new_backend = MockBackend::new();
let result = switch_backend(
&mut old_backend,
&mut new_backend,
&BackendConfig::new("mock"),
);
assert!(result.is_ok());
new_backend.open_channel(0).unwrap();
let msg = CanMessage::new_standard(0x200, &[1]).unwrap();
assert!(new_backend.send_message(&msg).is_ok());
}
#[test]
fn test_long_running_simulation() {
let mut backend = MockBackend::new();
backend.initialize(&BackendConfig::new("mock")).unwrap();
backend.open_channel(0).unwrap();
for cycle in 0..1000u32 {
let msg = CanMessage::new_extended(cycle, &[(cycle % 256) as u8]).unwrap();
backend.send_message(&msg).unwrap();
if cycle % 100 == 99 {
backend.simulate_disconnect();
backend.simulate_reconnect();
}
}
let recorded = backend.get_recorded_messages();
assert_eq!(recorded.len(), 1000);
backend.close().unwrap();
}