-
Notifications
You must be signed in to change notification settings - Fork 689
Enable most AIO tests on musl targets and clean them up #929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
cb96bab
test_aio: use assert_eq and avoid using #[allow]
jonas-schievink 5431536
enable most aio tests on musl
jonas-schievink 0afffff
Use sequentially consistent atomic ordering
jonas-schievink fb7dd44
enable aio signal tests where possible
jonas-schievink b2e950a
disable `test_liocb_listio_read_immutable` due to failures on Travis
jonas-schievink File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ use nix::sys::aio::*; | |
use nix::sys::signal::{SaFlags, SigAction, sigaction, SigevNotify, SigHandler, Signal, SigSet}; | ||
use nix::sys::time::{TimeSpec, TimeValLike}; | ||
use std::io::{Write, Read, Seek, SeekFrom}; | ||
use std::ops::Deref; | ||
use std::os::unix::io::AsRawFd; | ||
use std::sync::atomic::{AtomicBool, Ordering}; | ||
use std::{thread, time}; | ||
|
@@ -47,7 +46,6 @@ fn test_accessors() { | |
// our bindings. So it's sufficient to check that AioCb.cancel returned any | ||
// AioCancelStat value. | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_cancel() { | ||
let wbuf: &[u8] = b"CDEF"; | ||
|
||
|
@@ -72,7 +70,6 @@ fn test_cancel() { | |
|
||
// Tests using aio_cancel_all for all outstanding IOs. | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_aio_cancel_all() { | ||
let wbuf: &[u8] = b"CDEF"; | ||
|
||
|
@@ -96,7 +93,6 @@ fn test_aio_cancel_all() { | |
} | ||
|
||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_fsync() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let mut f = tempfile().unwrap(); | ||
|
@@ -132,7 +128,6 @@ fn test_fsync_error() { | |
} | ||
|
||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_aio_suspend() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
const WBUF: &[u8] = b"CDEFG"; | ||
|
@@ -168,14 +163,13 @@ fn test_aio_suspend() { | |
} | ||
} | ||
|
||
assert!(wcb.aio_return().unwrap() as usize == WBUF.len()); | ||
assert!(rcb.aio_return().unwrap() as usize == rlen); | ||
assert_eq!(wcb.aio_return().unwrap() as usize, WBUF.len()); | ||
assert_eq!(rcb.aio_return().unwrap() as usize, rlen); | ||
} | ||
|
||
// Test a simple aio operation with no completion notification. We must poll | ||
// for completion | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_read() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let mut rbuf = vec![0; 4]; | ||
|
@@ -192,11 +186,11 @@ fn test_read() { | |
aiocb.read().unwrap(); | ||
|
||
let err = poll_aio(&mut aiocb); | ||
assert!(err == Ok(())); | ||
assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len()); | ||
assert_eq!(err, Ok(())); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); | ||
} | ||
|
||
assert!(EXPECT == rbuf.deref().deref()); | ||
assert_eq!(EXPECT, &*rbuf); | ||
} | ||
|
||
/// `AioCb::read` should not modify the `AioCb` object if `libc::aio_read` | ||
|
@@ -221,7 +215,6 @@ fn test_read_error() { | |
|
||
// Tests from_mut_slice | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_read_into_mut_slice() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let mut rbuf = vec![0; 4]; | ||
|
@@ -238,16 +231,15 @@ fn test_read_into_mut_slice() { | |
aiocb.read().unwrap(); | ||
|
||
let err = poll_aio(&mut aiocb); | ||
assert!(err == Ok(())); | ||
assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len()); | ||
assert_eq!(err, Ok(())); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); | ||
} | ||
|
||
assert!(rbuf == EXPECT); | ||
assert_eq!(rbuf, EXPECT); | ||
} | ||
|
||
// Tests from_ptr | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_read_into_pointer() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let mut rbuf = vec![0; 4]; | ||
|
@@ -268,18 +260,16 @@ fn test_read_into_pointer() { | |
aiocb.read().unwrap(); | ||
|
||
let err = poll_aio(&mut aiocb); | ||
assert!(err == Ok(())); | ||
assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len()); | ||
assert_eq!(err, Ok(())); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); | ||
} | ||
|
||
assert!(rbuf == EXPECT); | ||
assert_eq!(rbuf, EXPECT); | ||
} | ||
|
||
// Test reading into an immutable buffer. It should fail | ||
// FIXME: This test fails to panic on Linux/musl | ||
// Test reading into an immutable buffer. It should fail with a panic. | ||
#[test] | ||
#[should_panic(expected = "Can't read into an immutable buffer")] | ||
#[cfg_attr(target_env = "musl", ignore)] | ||
fn test_read_immutable_buffer() { | ||
let rbuf: &[u8] = b"CDEF"; | ||
let f = tempfile().unwrap(); | ||
|
@@ -292,11 +282,9 @@ fn test_read_immutable_buffer() { | |
aiocb.read().unwrap(); | ||
} | ||
|
||
|
||
// Test a simple aio operation with no completion notification. We must poll | ||
// for completion. Unlike test_aio_read, this test uses AioCb::from_slice | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_write() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let wbuf = "CDEF".to_string().into_bytes(); | ||
|
@@ -314,18 +302,17 @@ fn test_write() { | |
aiocb.write().unwrap(); | ||
|
||
let err = poll_aio(&mut aiocb); | ||
assert!(err == Ok(())); | ||
assert!(aiocb.aio_return().unwrap() as usize == wbuf.len()); | ||
assert_eq!(err, Ok(())); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, wbuf.len()); | ||
|
||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf, EXPECT); | ||
} | ||
|
||
// Tests `AioCb::from_boxed_slice` with `Bytes` | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_write_bytes() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let wbuf = Box::new(Bytes::from(&b"CDEF"[..])); | ||
|
@@ -344,18 +331,17 @@ fn test_write_bytes() { | |
aiocb.write().unwrap(); | ||
|
||
let err = poll_aio(&mut aiocb); | ||
assert!(err == Ok(())); | ||
assert!(aiocb.aio_return().unwrap() as usize == expected_len); | ||
assert_eq!(err, Ok(())); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, expected_len); | ||
|
||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf, EXPECT); | ||
} | ||
|
||
// Tests `AioCb::from_boxed_mut_slice` with `BytesMut` | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_read_bytes_mut_small() { | ||
const INITIAL: &[u8] = b"abcdef"; | ||
let rbuf = Box::new(BytesMut::from(vec![0; 4])); | ||
|
@@ -380,7 +366,6 @@ fn test_read_bytes_mut_small() { | |
|
||
// Tests `AioCb::from_ptr` | ||
#[test] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_write_from_pointer() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
let wbuf = "CDEF".to_string().into_bytes(); | ||
|
@@ -402,13 +387,13 @@ fn test_write_from_pointer() { | |
aiocb.write().unwrap(); | ||
|
||
let err = poll_aio(&mut aiocb); | ||
assert!(err == Ok(())); | ||
assert!(aiocb.aio_return().unwrap() as usize == wbuf.len()); | ||
assert_eq!(err, Ok(())); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, wbuf.len()); | ||
|
||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf, EXPECT); | ||
} | ||
|
||
/// `AioCb::write` should not modify the `AioCb` object if `libc::aio_write` | ||
|
@@ -433,20 +418,19 @@ lazy_static! { | |
} | ||
|
||
extern fn sigfunc(_: c_int) { | ||
SIGNALED.store(true, Ordering::Relaxed); | ||
SIGNALED.store(true, Ordering::SeqCst); | ||
} | ||
|
||
// Test an aio operation with completion delivered by a signal | ||
// FIXME: This test is ignored on mips because of failures in qemu in CI | ||
#[test] | ||
#[cfg_attr(any(all(target_env = "musl", target_arch = "x86_64"), target_arch = "mips", target_arch = "mips64"), ignore)] | ||
#[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)] | ||
fn test_write_sigev_signal() { | ||
#[allow(unused_variables)] | ||
let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); | ||
let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); | ||
let sa = SigAction::new(SigHandler::Handler(sigfunc), | ||
SaFlags::SA_RESETHAND, | ||
SigSet::empty()); | ||
SIGNALED.store(false, Ordering::Relaxed); | ||
SIGNALED.store(false, Ordering::SeqCst); | ||
unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); | ||
|
||
const INITIAL: &[u8] = b"abcdef123456"; | ||
|
@@ -466,22 +450,21 @@ fn test_write_sigev_signal() { | |
}, | ||
LioOpcode::LIO_NOP); | ||
aiocb.write().unwrap(); | ||
while !SIGNALED.load(Ordering::Relaxed) { | ||
while !SIGNALED.load(Ordering::SeqCst) { | ||
thread::sleep(time::Duration::from_millis(10)); | ||
} | ||
|
||
assert!(aiocb.aio_return().unwrap() as usize == WBUF.len()); | ||
assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len()); | ||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf, EXPECT); | ||
} | ||
|
||
// Test LioCb::listio with LIO_WAIT, so all AIO ops should be complete by the | ||
// time listio returns. | ||
#[test] | ||
#[cfg(not(any(target_os = "ios", target_os = "macos")))] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_liocb_listio_wait() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
const WBUF: &[u8] = b"CDEF"; | ||
|
@@ -513,22 +496,21 @@ fn test_liocb_listio_wait() { | |
let err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone); | ||
err.expect("lio_listio"); | ||
|
||
assert!(liocb.aio_return(0).unwrap() as usize == WBUF.len()); | ||
assert!(liocb.aio_return(1).unwrap() as usize == rlen); | ||
assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len()); | ||
assert_eq!(liocb.aio_return(1).unwrap() as usize, rlen); | ||
} | ||
assert!(rbuf.deref().deref() == b"3456"); | ||
assert_eq!(rbuf, b"3456"); | ||
|
||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf2).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf2 == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf2, EXPECT); | ||
} | ||
|
||
// Test LioCb::listio with LIO_NOWAIT and no SigEvent, so we must use some other | ||
// mechanism to check for the individual AioCb's completion. | ||
#[test] | ||
#[cfg(not(any(target_os = "ios", target_os = "macos")))] | ||
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] | ||
fn test_liocb_listio_nowait() { | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
const WBUF: &[u8] = b"CDEF"; | ||
|
@@ -562,26 +544,25 @@ fn test_liocb_listio_nowait() { | |
|
||
poll_aio(&mut liocb.aiocbs[0]).unwrap(); | ||
poll_aio(&mut liocb.aiocbs[1]).unwrap(); | ||
assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len()); | ||
assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen); | ||
assert_eq!(liocb.aiocbs[0].aio_return().unwrap() as usize, WBUF.len()); | ||
assert_eq!(liocb.aiocbs[1].aio_return().unwrap() as usize, rlen); | ||
} | ||
assert!(rbuf.deref().deref() == b"3456"); | ||
assert_eq!(rbuf, b"3456"); | ||
|
||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf2).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf2 == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf2, EXPECT); | ||
} | ||
|
||
// Test LioCb::listio with LIO_NOWAIT and a SigEvent to indicate when all | ||
// AioCb's are complete. | ||
// FIXME: This test is ignored on mips/mips64 because of failures in qemu in CI. | ||
#[test] | ||
#[cfg(not(any(target_os = "ios", target_os = "macos")))] | ||
#[cfg_attr(any(target_arch = "mips", target_arch = "mips64", target_env = "musl"), ignore)] | ||
#[cfg_attr(any(all(target_arch = "x86", target_env = "musl"), target_arch = "mips", target_arch = "mips64"), ignore)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this test fails on x86 with musl, why do you think it will work better on other architectures with musl? |
||
fn test_liocb_listio_signal() { | ||
#[allow(unused_variables)] | ||
let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); | ||
let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); | ||
const INITIAL: &[u8] = b"abcdef123456"; | ||
const WBUF: &[u8] = b"CDEF"; | ||
let mut rbuf = vec![0; 4]; | ||
|
@@ -614,30 +595,30 @@ fn test_liocb_listio_signal() { | |
let mut liocb = LioCb::with_capacity(2); | ||
liocb.aiocbs.push(wcb); | ||
liocb.aiocbs.push(rcb); | ||
SIGNALED.store(false, Ordering::Relaxed); | ||
SIGNALED.store(false, Ordering::SeqCst); | ||
unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); | ||
let err = liocb.listio(LioMode::LIO_NOWAIT, sigev_notify); | ||
err.expect("lio_listio"); | ||
while !SIGNALED.load(Ordering::Relaxed) { | ||
while !SIGNALED.load(Ordering::SeqCst) { | ||
thread::sleep(time::Duration::from_millis(10)); | ||
} | ||
|
||
assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len()); | ||
assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen); | ||
assert_eq!(liocb.aiocbs[0].aio_return().unwrap() as usize, WBUF.len()); | ||
assert_eq!(liocb.aiocbs[1].aio_return().unwrap() as usize, rlen); | ||
} | ||
assert!(rbuf.deref().deref() == b"3456"); | ||
assert_eq!(rbuf, b"3456"); | ||
|
||
f.seek(SeekFrom::Start(0)).unwrap(); | ||
let len = f.read_to_end(&mut rbuf2).unwrap(); | ||
assert!(len == EXPECT.len()); | ||
assert!(rbuf2 == EXPECT); | ||
assert_eq!(len, EXPECT.len()); | ||
assert_eq!(rbuf2, EXPECT); | ||
} | ||
|
||
// Try to use LioCb::listio to read into an immutable buffer. It should fail | ||
// FIXME: This test fails to panic on Linux/musl | ||
#[test] | ||
#[cfg(not(any(target_os = "ios", target_os = "macos")))] | ||
#[should_panic(expected = "Can't read into an immutable buffer")] | ||
// FIXME: This test fails on Travis with "failed to initiate panic, error 5" | ||
#[cfg_attr(target_env = "musl", ignore)] | ||
fn test_liocb_listio_read_immutable() { | ||
let rbuf: &[u8] = b"abcd"; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relaxed
is fine here, becauseSIGNALED
isn't being used to control access to any other variables. It's only being accessed by itself, so stricter atomic instructions aren't needed. This is the kind of application that, in C, wouldn't even use special instructions, just asigatomic_t
variable.