#[cfg(feature = "vcan_tests")]
use serial_test::serial;
#[cfg(feature = "vcan_tests")]
use socketcan::{
CanAnyFrame, CanFdFrame, EmbeddedFrame, Id, SocketOptions, StandardId, addr::CanAddr,
id::FdFlags, smol::CanFdSocket as AsyncCanFdSocket, smol::CanSocket as AsyncCanSocket,
};
#[cfg(feature = "vcan_tests")]
const VCAN: &str = "vcan0";
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_can_simple() {
smol::block_on(async {
let writer = AsyncCanSocket::open(VCAN).unwrap();
let reader = AsyncCanSocket::open(VCAN).unwrap();
let frame =
socketcan::CanFrame::new(Id::from(StandardId::new(0x14).unwrap()), &[1, 3, 3, 7])
.unwrap();
let (write_result, read_result) =
futures::join!(writer.write_frame(&frame), reader.read_frame());
assert!(write_result.is_ok());
assert_eq!(frame.data(), read_result.unwrap().data());
});
}
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_canfd_simple() {
smol::block_on(async {
let writer = AsyncCanFdSocket::open(VCAN).unwrap();
let reader = AsyncCanFdSocket::open(VCAN).unwrap();
let frame = CanFdFrame::with_flags(
StandardId::new(111).unwrap(),
&[1, 3, 3, 7, 1, 2, 3, 4, 5],
FdFlags::empty(),
)
.unwrap();
let (write_result, read_result) =
futures::join!(writer.write_frame(&frame), reader.read_frame());
assert!(write_result.is_ok());
match read_result.unwrap() {
CanAnyFrame::Fd(read_frame) => assert_eq!(read_frame.data(), frame.data()),
_ => panic!("Did not get FD frame back!"),
}
});
}
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_read_frame_with_timestamp() {
smol::block_on(async {
let writer = AsyncCanSocket::open(VCAN).unwrap();
let reader = AsyncCanSocket::open(VCAN).unwrap();
reader.set_recv_timestamp(true).unwrap();
let frame =
socketcan::CanFrame::new(Id::from(StandardId::new(0x77).unwrap()), &[7, 7, 7]).unwrap();
let sent_at = std::time::SystemTime::now();
let (write_result, read_result) = futures::join!(
writer.write_frame(&frame),
reader.read_frame_with_timestamp(),
);
write_result.unwrap();
let (rx, ts) = read_result.unwrap();
assert_eq!(rx.data(), frame.data());
let delta = ts
.duration_since(sent_at)
.or_else(|e| Ok::<_, std::time::SystemTimeError>(e.duration()))
.unwrap();
assert!(
delta < std::time::Duration::from_secs(2),
"async timestamp out of range: {delta:?}"
);
});
}
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_try_read_and_try_write() {
smol::block_on(async {
let socket1 = AsyncCanSocket::open(VCAN).unwrap();
let socket2 = AsyncCanSocket::open(VCAN).unwrap();
let result = socket2.try_read_frame();
assert!(result.is_err(), "Expected no frames available");
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::WouldBlock);
let frame =
socketcan::CanFrame::new(Id::from(StandardId::new(0x1).unwrap()), &[0]).unwrap();
socket1.try_write_frame(&frame).unwrap();
smol::Timer::after(std::time::Duration::from_millis(100)).await;
socket2.try_read_frame().unwrap();
let result = socket2.try_read_frame();
assert!(result.is_err(), "Expected no frames available");
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::WouldBlock);
});
}
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_try_read_and_try_write_fd() {
smol::block_on(async {
let socket1 = AsyncCanFdSocket::open(VCAN).unwrap();
let socket2 = AsyncCanFdSocket::open(VCAN).unwrap();
let result = socket2.try_read_frame();
assert!(result.is_err(), "Expected no frames available");
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::WouldBlock);
let frame = CanFdFrame::new(StandardId::new(0x1).unwrap(), &[0u8; 8]).unwrap();
socket1.try_write_frame(&frame).unwrap();
smol::Timer::after(std::time::Duration::from_millis(100)).await;
socket2.try_read_frame().unwrap();
let result = socket2.try_read_frame();
assert!(result.is_err(), "Expected no frames available");
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::WouldBlock);
});
}
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_stream_and_sink() {
smol::block_on(async {
use futures::{SinkExt, StreamExt};
let mut sock = AsyncCanSocket::open(VCAN).unwrap();
sock.set_loopback(true).unwrap();
sock.set_recv_own_msgs(true).unwrap();
let f1 =
socketcan::CanFrame::new(Id::from(StandardId::new(0x111).unwrap()), &[1, 2]).unwrap();
let f2 =
socketcan::CanFrame::new(Id::from(StandardId::new(0x222).unwrap()), &[3, 4]).unwrap();
sock.send(f1).await.unwrap();
sock.send(f2).await.unwrap();
let rx1 = sock.next().await.unwrap().unwrap();
let rx2 = sock.next().await.unwrap().unwrap();
assert_eq!(rx1.data(), f1.data());
assert_eq!(rx2.data(), f2.data());
});
}
#[cfg(feature = "vcan_tests")]
#[serial]
#[test]
fn async_open_if_and_open_addr() {
smol::block_on(async {
let addr = CanAddr::from_iface(VCAN).unwrap();
let by_addr = AsyncCanSocket::open_addr(&addr).unwrap();
let ifindex = nix::net::if_::if_nametoindex(VCAN).unwrap();
let by_if = AsyncCanSocket::open_if(ifindex).unwrap();
by_if.set_loopback(true).unwrap();
by_if.set_recv_own_msgs(true).unwrap();
let frame =
socketcan::CanFrame::new(Id::from(StandardId::new(0x55).unwrap()), &[0x5A]).unwrap();
by_if.write_frame(&frame).await.unwrap();
let rx = by_if.read_frame().await.unwrap();
assert_eq!(rx.data(), frame.data());
by_addr.set_loopback(true).unwrap();
by_addr.set_recv_own_msgs(true).unwrap();
by_addr.write_frame(&frame).await.unwrap();
let rx2 = by_addr.read_frame().await.unwrap();
assert_eq!(rx2.data(), frame.data());
});
}