epoll test: further clean up check_epoll_wait
This commit is contained in:
parent
78dfb8a108
commit
465df5656f
@ -24,7 +24,7 @@ fn main() {
|
||||
const EPOLL_IN_OUT_ET: u32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _;
|
||||
|
||||
#[track_caller]
|
||||
fn check_epoll_wait<const N: usize>(epfd: i32, expected_notifications: &[(u32, u64)]) -> bool {
|
||||
fn check_epoll_wait<const N: usize>(epfd: i32, expected_notifications: &[(u32, u64)]) {
|
||||
let epoll_event = libc::epoll_event { events: 0, u64: 0 };
|
||||
let mut array: [libc::epoll_event; N] = [epoll_event; N];
|
||||
let maxsize = N;
|
||||
@ -33,22 +33,18 @@ fn check_epoll_wait<const N: usize>(epfd: i32, expected_notifications: &[(u32, u
|
||||
if res < 0 {
|
||||
panic!("epoll_wait failed: {}", std::io::Error::last_os_error());
|
||||
}
|
||||
assert_eq!(res, expected_notifications.len().try_into().unwrap());
|
||||
assert_eq!(
|
||||
res,
|
||||
expected_notifications.len().try_into().unwrap(),
|
||||
"got wrong number of notifications"
|
||||
);
|
||||
let slice = unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) };
|
||||
let mut return_events = slice.iter();
|
||||
let mut expected_notifications = expected_notifications.iter();
|
||||
while let Some(return_event) = return_events.next() {
|
||||
if let Some(notification) = expected_notifications.next() {
|
||||
let event = return_event.events;
|
||||
let data = return_event.u64;
|
||||
assert_eq!(event, notification.0);
|
||||
assert_eq!(data, notification.1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
for (return_event, expected_event) in slice.iter().zip(expected_notifications.iter()) {
|
||||
let event = return_event.events;
|
||||
let data = return_event.u64;
|
||||
assert_eq!(event, expected_event.0, "got wrong events");
|
||||
assert_eq!(data, expected_event.1, "got wrong data");
|
||||
}
|
||||
// There shouldn't be any more expected.
|
||||
return expected_notifications.next().is_none();
|
||||
}
|
||||
|
||||
fn test_epoll_socketpair() {
|
||||
@ -77,10 +73,10 @@ fn test_epoll_socketpair() {
|
||||
// Check result from epoll_wait.
|
||||
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
||||
let expected_value = u64::try_from(fds[1]).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
|
||||
// Check that this is indeed using "ET" (edge-trigger) semantics: a second epoll should return nothing.
|
||||
assert!(check_epoll_wait::<8>(epfd, &[]));
|
||||
check_epoll_wait::<8>(epfd, &[]);
|
||||
|
||||
// Write some more to fd[0].
|
||||
let data = "abcde".as_bytes().as_ptr();
|
||||
@ -89,7 +85,7 @@ fn test_epoll_socketpair() {
|
||||
|
||||
// This did not change the readiness of fd[1]. And yet, we're seeing the event reported
|
||||
// again by the kernel, so Miri does the same.
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
|
||||
// Close the peer socketpair.
|
||||
let res = unsafe { libc::close(fds[0]) };
|
||||
@ -100,7 +96,7 @@ fn test_epoll_socketpair() {
|
||||
let expected_event =
|
||||
u32::try_from(libc::EPOLLRDHUP | libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP).unwrap();
|
||||
let expected_value = u64::try_from(fds[1]).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
||||
fn test_epoll_ctl_mod() {
|
||||
@ -127,7 +123,7 @@ fn test_epoll_ctl_mod() {
|
||||
// Check result from epoll_wait.
|
||||
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
||||
let expected_value = u64::try_from(fds[1]).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
|
||||
// Test EPOLLRDHUP.
|
||||
let mut ev = libc::epoll_event {
|
||||
@ -145,7 +141,7 @@ fn test_epoll_ctl_mod() {
|
||||
let expected_event =
|
||||
u32::try_from(libc::EPOLLRDHUP | libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP).unwrap();
|
||||
let expected_value = u64::try_from(fds[1]).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
||||
fn test_epoll_ctl_del() {
|
||||
@ -169,7 +165,7 @@ fn test_epoll_ctl_del() {
|
||||
assert_ne!(res, -1);
|
||||
|
||||
// Test EPOLL_CTL_DEL.
|
||||
assert!(check_epoll_wait::<0>(epfd, &[]));
|
||||
check_epoll_wait::<0>(epfd, &[]);
|
||||
}
|
||||
|
||||
// This test is for one fd registered under two different epoll instance.
|
||||
@ -200,8 +196,8 @@ fn test_two_epoll_instance() {
|
||||
// Notification should be received from both instance of epoll.
|
||||
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
||||
let expected_value = u64::try_from(fds[1]).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd1, &[(expected_event, expected_value)]));
|
||||
assert!(check_epoll_wait::<8>(epfd2, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd1, &[(expected_event, expected_value)]);
|
||||
check_epoll_wait::<8>(epfd2, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
||||
// This test is for two same file description registered under the same epoll instance through dup.
|
||||
@ -235,10 +231,10 @@ fn test_two_same_fd_in_same_epoll_instance() {
|
||||
//Two notification should be received.
|
||||
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
||||
let expected_value = 5 as u64;
|
||||
assert!(check_epoll_wait::<8>(
|
||||
check_epoll_wait::<8>(
|
||||
epfd,
|
||||
&[(expected_event, expected_value), (expected_event, expected_value)]
|
||||
));
|
||||
&[(expected_event, expected_value), (expected_event, expected_value)],
|
||||
);
|
||||
}
|
||||
|
||||
fn test_epoll_eventfd() {
|
||||
@ -263,7 +259,7 @@ fn test_epoll_eventfd() {
|
||||
// Check result from epoll_wait.
|
||||
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
||||
let expected_value = u64::try_from(fd).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
||||
fn test_pointer() {
|
||||
@ -313,10 +309,10 @@ fn test_epoll_socketpair_both_sides() {
|
||||
let expected_value0 = fds[0] as u64;
|
||||
let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value1 = fds[1] as u64;
|
||||
assert!(check_epoll_wait::<8>(
|
||||
check_epoll_wait::<8>(
|
||||
epfd,
|
||||
&[(expected_event0, expected_value0), (expected_event1, expected_value1)]
|
||||
));
|
||||
&[(expected_event0, expected_value0), (expected_event1, expected_value1)],
|
||||
);
|
||||
|
||||
// Read from fds[0].
|
||||
let mut buf: [u8; 5] = [0; 5];
|
||||
@ -327,7 +323,7 @@ fn test_epoll_socketpair_both_sides() {
|
||||
// Notification should be provided for fds[1].
|
||||
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value = fds[1] as u64;
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
||||
// When file description is fully closed, epoll_wait should not provide any notification for
|
||||
@ -356,7 +352,7 @@ fn test_closed_fd() {
|
||||
assert_eq!(res, 0);
|
||||
|
||||
// No notification should be provided because the file description is closed.
|
||||
assert!(check_epoll_wait::<8>(epfd, &[]));
|
||||
check_epoll_wait::<8>(epfd, &[]);
|
||||
}
|
||||
|
||||
// When a certain file descriptor registered with epoll is closed, but the underlying file description
|
||||
@ -390,7 +386,7 @@ fn test_not_fully_closed_fd() {
|
||||
// Notification should still be provided because the file description is not closed.
|
||||
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value = fd as u64;
|
||||
assert!(check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)]);
|
||||
|
||||
// Write to the eventfd instance to produce notification.
|
||||
let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes();
|
||||
@ -402,7 +398,7 @@ fn test_not_fully_closed_fd() {
|
||||
assert_eq!(res, 0);
|
||||
|
||||
// No notification should be provided.
|
||||
assert!(check_epoll_wait::<1>(epfd, &[]));
|
||||
check_epoll_wait::<1>(epfd, &[]);
|
||||
}
|
||||
|
||||
// Each time a notification is provided, it should reflect the file description's readiness
|
||||
@ -437,7 +433,7 @@ fn test_event_overwrite() {
|
||||
// Check result from epoll_wait.
|
||||
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value = u64::try_from(fd).unwrap();
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
||||
// An epoll notification will be provided for every succesful read in a socketpair.
|
||||
@ -476,10 +472,10 @@ fn test_socketpair_read() {
|
||||
let expected_value0 = fds[0] as u64;
|
||||
let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value1 = fds[1] as u64;
|
||||
assert!(check_epoll_wait::<8>(
|
||||
check_epoll_wait::<8>(
|
||||
epfd,
|
||||
&[(expected_event0, expected_value0), (expected_event1, expected_value1)]
|
||||
));
|
||||
&[(expected_event0, expected_value0), (expected_event1, expected_value1)],
|
||||
);
|
||||
|
||||
// Read 3 bytes from fds[0].
|
||||
let mut buf: [u8; 3] = [0; 3];
|
||||
@ -491,7 +487,7 @@ fn test_socketpair_read() {
|
||||
// But in real system, no notification will be provided here.
|
||||
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value = fds[1] as u64;
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
|
||||
// Read until the buffer is empty.
|
||||
let mut buf: [u8; 2] = [0; 2];
|
||||
@ -503,5 +499,5 @@ fn test_socketpair_read() {
|
||||
// In real system, notification will be provided too.
|
||||
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
|
||||
let expected_value = fds[1] as u64;
|
||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user