#![cfg(feature = "async")]
use canlink_hal::{BackendConfig, CanBackend, CanBackendAsync, CanMessage};
use canlink_mock::{MockBackend, MockConfig};
use std::time::Duration;
fn create_initialized_backend() -> MockBackend {
let mut backend = MockBackend::new();
let config = BackendConfig::new("mock");
backend.initialize(&config).unwrap();
backend.open_channel(0).unwrap();
backend
}
fn create_backend_with_messages(messages: Vec<CanMessage>) -> MockBackend {
let config = MockConfig::with_preset_messages(messages);
let mut backend = MockBackend::with_config(config);
let backend_config = BackendConfig::new("mock");
backend.initialize(&backend_config).unwrap();
backend.open_channel(0).unwrap();
backend
}
#[tokio::test]
async fn test_send_message_async() {
let mut backend = create_initialized_backend();
let msg = CanMessage::new_standard(0x123, &[0x01, 0x02, 0x03, 0x04]).unwrap();
let result = backend.send_message_async(&msg).await;
assert!(result.is_ok());
assert!(backend.verify_message_sent(canlink_hal::CanId::Standard(0x123)));
}
#[tokio::test]
async fn test_send_multiple_messages_async() {
let mut backend = create_initialized_backend();
for i in 0..10u16 {
let msg = CanMessage::new_standard(0x100 + i, &[i as u8]).unwrap();
backend.send_message_async(&msg).await.unwrap();
}
assert!(backend.verify_message_count(10));
}
#[tokio::test]
async fn test_receive_message_async_no_timeout() {
let preset = vec![
CanMessage::new_standard(0x111, &[0x11]).unwrap(),
CanMessage::new_standard(0x222, &[0x22]).unwrap(),
];
let mut backend = create_backend_with_messages(preset);
let msg1 = backend.receive_message_async(None).await.unwrap();
assert!(msg1.is_some());
assert_eq!(msg1.unwrap().id(), canlink_hal::CanId::Standard(0x111));
let msg2 = backend.receive_message_async(None).await.unwrap();
assert!(msg2.is_some());
assert_eq!(msg2.unwrap().id(), canlink_hal::CanId::Standard(0x222));
let msg3 = backend.receive_message_async(None).await.unwrap();
assert!(msg3.is_none());
}
#[tokio::test]
async fn test_receive_message_async_with_timeout_success() {
let preset = vec![CanMessage::new_standard(0x333, &[0x33]).unwrap()];
let mut backend = create_backend_with_messages(preset);
let result = backend
.receive_message_async(Some(Duration::from_millis(100)))
.await
.unwrap();
assert!(result.is_some());
assert_eq!(result.unwrap().id(), canlink_hal::CanId::Standard(0x333));
}
#[tokio::test]
async fn test_receive_message_async_with_timeout_expires() {
let mut backend = create_initialized_backend();
let start = std::time::Instant::now();
let result = backend
.receive_message_async(Some(Duration::from_millis(50)))
.await
.unwrap();
let elapsed = start.elapsed();
assert!(result.is_none());
assert!(elapsed >= Duration::from_millis(45)); assert!(elapsed < Duration::from_millis(200)); }
#[tokio::test]
async fn test_async_send_receive_roundtrip() {
let mut backend = create_initialized_backend();
let sent_msg = CanMessage::new_standard(0x456, &[0x44, 0x55, 0x66]).unwrap();
backend.send_message_async(&sent_msg).await.unwrap();
let recorded = backend.get_recorded_messages();
assert_eq!(recorded.len(), 1);
assert_eq!(recorded[0].id(), canlink_hal::CanId::Standard(0x456));
assert_eq!(recorded[0].data(), &[0x44, 0x55, 0x66]);
}
#[tokio::test]
async fn test_async_canfd_message() {
let mut backend = create_initialized_backend();
let fd_data: Vec<u8> = (0..64).collect();
let fd_msg = CanMessage::new_fd(canlink_hal::CanId::Standard(0x789), &fd_data).unwrap();
let result = backend.send_message_async(&fd_msg).await;
assert!(result.is_ok());
let recorded = backend.get_recorded_messages();
assert_eq!(recorded.len(), 1);
assert_eq!(recorded[0].data().len(), 64);
}
#[tokio::test]
async fn test_async_extended_id() {
let mut backend = create_initialized_backend();
let msg = CanMessage::new_extended(0x1234_5678, &[0xAA, 0xBB]).unwrap();
backend.send_message_async(&msg).await.unwrap();
assert!(backend.verify_message_sent(canlink_hal::CanId::Extended(0x1234_5678)));
}
#[tokio::test]
async fn test_async_concurrent_operations() {
use std::sync::Arc;
use tokio::sync::Mutex;
let backend = Arc::new(Mutex::new(create_initialized_backend()));
let mut handles = vec![];
for i in 0..5u16 {
let backend_clone = Arc::clone(&backend);
let handle = tokio::spawn(async move {
let msg = CanMessage::new_standard(0x100 + i, &[i as u8]).unwrap();
let mut backend = backend_clone.lock().await;
backend.send_message_async(&msg).await
});
handles.push(handle);
}
for handle in handles {
handle.await.unwrap().unwrap();
}
let backend = backend.lock().await;
assert!(backend.verify_message_count(5));
}