mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-07 00:00:08 +02:00
fs: skip some io_uring tests on Kernels that don't support it (#8134)
This commit is contained in:
@@ -40,6 +40,8 @@ jobs:
|
|||||||
make defconfig
|
make defconfig
|
||||||
make -j$(nproc)
|
make -j$(nproc)
|
||||||
|
|
||||||
|
# We are running tests also on a Kernel version that does not support io_uring
|
||||||
|
# to check if the fallback mechanism works
|
||||||
- name: Generate test binaries with io_uring enabled
|
- name: Generate test binaries with io_uring enabled
|
||||||
run: |
|
run: |
|
||||||
# Build both integration (tokio/tests/) and unit (e.g., tokio/src/fs/file/tests.rs) tests with io_uring enabled
|
# Build both integration (tokio/tests/) and unit (e.g., tokio/src/fs/file/tests.rs) tests with io_uring enabled
|
||||||
|
|||||||
@@ -13,10 +13,21 @@ use std::fs;
|
|||||||
use std::future::poll_fn;
|
use std::future::poll_fn;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
use tokio_test::assert_pending;
|
||||||
|
|
||||||
|
use crate::support::io_uring::io_uring_supported;
|
||||||
|
|
||||||
|
mod support {
|
||||||
|
pub(crate) mod io_uring;
|
||||||
|
}
|
||||||
|
|
||||||
// see: https://github.com/tokio-rs/tokio/issues/7979
|
// see: https://github.com/tokio-rs/tokio/issues/7979
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn file_descriptors_are_closed_when_cancelling_open_op() {
|
async fn file_descriptors_are_closed_when_cancelling_open_op() {
|
||||||
|
if !io_uring_supported() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let tmp = NamedTempFile::new().unwrap();
|
let tmp = NamedTempFile::new().unwrap();
|
||||||
let path = tmp.path().to_path_buf();
|
let path = tmp.path().to_path_buf();
|
||||||
|
|
||||||
@@ -37,10 +48,8 @@ async fn file_descriptors_are_closed_when_cancelling_open_op() {
|
|||||||
let fut = opt.open(&path);
|
let fut = opt.open(&path);
|
||||||
|
|
||||||
// If io_uring is enabled (and not falling back to the thread pool),
|
// If io_uring is enabled (and not falling back to the thread pool),
|
||||||
// the first poll should return Pending. We don't check if the result
|
// the first poll should return Pending.
|
||||||
// is actually pending because we run some checks on old kernel that
|
assert_pending!(Box::pin(fut).poll_unpin(cx));
|
||||||
// do not support uring.
|
|
||||||
let _pending = Box::pin(fut).poll_unpin(cx);
|
|
||||||
|
|
||||||
tx.send(()).unwrap();
|
tx.send(()).unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
target_os = "linux"
|
target_os = "linux"
|
||||||
))]
|
))]
|
||||||
|
|
||||||
|
mod support {
|
||||||
|
pub(crate) mod io_uring;
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -16,6 +21,9 @@ use std::time::Duration;
|
|||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
||||||
use tokio::time::timeout;
|
use tokio::time::timeout;
|
||||||
|
use tokio_test::assert_pending;
|
||||||
|
|
||||||
|
use crate::support::io_uring::io_uring_supported;
|
||||||
|
|
||||||
/// Count currently-open fds in this process.
|
/// Count currently-open fds in this process.
|
||||||
fn fd_count() -> usize {
|
fn fd_count() -> usize {
|
||||||
@@ -42,14 +50,17 @@ struct PollOpenOnceThenNeverRepoll<F> {
|
|||||||
polled_once: bool,
|
polled_once: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Future> Future for PollOpenOnceThenNeverRepoll<F> {
|
impl<F: Future> Future for PollOpenOnceThenNeverRepoll<F>
|
||||||
type Output = ();
|
where
|
||||||
|
F::Output: Debug,
|
||||||
|
{
|
||||||
|
type Output = F::Output;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
if !self.polled_once {
|
if !self.polled_once {
|
||||||
// We don't check if the result is actually pending because
|
// If io_uring is enabled (and not falling back to the thread pool),
|
||||||
// we run some checks on old kernel that do not support uring.
|
// the first poll should return Pending.
|
||||||
let _pending = self.inner.as_mut().poll(cx);
|
assert_pending!(self.inner.as_mut().poll(cx));
|
||||||
|
|
||||||
self.polled_once = true;
|
self.polled_once = true;
|
||||||
self.first_poll_tx.take().unwrap().send(()).unwrap();
|
self.first_poll_tx.take().unwrap().send(()).unwrap();
|
||||||
@@ -80,7 +91,7 @@ async fn completed_then_dropped_before_repoll(path: PathBuf) {
|
|||||||
second_poll_tx: Some(second_tx),
|
second_poll_tx: Some(second_tx),
|
||||||
polled_once: false,
|
polled_once: false,
|
||||||
}
|
}
|
||||||
.await;
|
.await
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait until the inner open has been polled once and registered with io_uring.
|
// Wait until the inner open has been polled once and registered with io_uring.
|
||||||
@@ -98,6 +109,10 @@ async fn completed_then_dropped_before_repoll(path: PathBuf) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn uring_completed_then_dropped() {
|
fn uring_completed_then_dropped() {
|
||||||
|
if !io_uring_supported() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||||
.worker_threads(1)
|
.worker_threads(1)
|
||||||
.enable_all()
|
.enable_all()
|
||||||
|
|||||||
@@ -14,10 +14,21 @@ use std::future::poll_fn;
|
|||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
use tokio::runtime::Builder;
|
use tokio::runtime::Builder;
|
||||||
|
use tokio_test::assert_pending;
|
||||||
|
|
||||||
|
use crate::support::io_uring::io_uring_supported;
|
||||||
|
|
||||||
|
mod support {
|
||||||
|
pub(crate) mod io_uring;
|
||||||
|
}
|
||||||
|
|
||||||
// see: https://github.com/tokio-rs/tokio/issues/7979
|
// see: https://github.com/tokio-rs/tokio/issues/7979
|
||||||
#[test]
|
#[test]
|
||||||
fn shutdown_runtime_while_performing_io_uring_ops() {
|
fn shutdown_runtime_while_performing_io_uring_ops() {
|
||||||
|
if !io_uring_supported() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let tmp = NamedTempFile::new().unwrap();
|
let tmp = NamedTempFile::new().unwrap();
|
||||||
let path = tmp.path().to_path_buf();
|
let path = tmp.path().to_path_buf();
|
||||||
|
|
||||||
@@ -41,10 +52,8 @@ fn shutdown_runtime_while_performing_io_uring_ops() {
|
|||||||
let fut = opt.open(&path);
|
let fut = opt.open(&path);
|
||||||
|
|
||||||
// If io_uring is enabled (and not falling back to the thread pool),
|
// If io_uring is enabled (and not falling back to the thread pool),
|
||||||
// the first poll should return Pending. We don't check if the result
|
// the first poll should return Pending.
|
||||||
// is actually a pending because we run some CI checks based on old
|
assert_pending!(Box::pin(fut).poll_unpin(cx));
|
||||||
// kernels that don't support uring.
|
|
||||||
let _pending = Box::pin(fut).poll_unpin(cx);
|
|
||||||
|
|
||||||
tx.send(()).unwrap();
|
tx.send(()).unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#![cfg(all(
|
||||||
|
tokio_unstable,
|
||||||
|
feature = "io-uring",
|
||||||
|
feature = "rt",
|
||||||
|
feature = "fs",
|
||||||
|
target_os = "linux"
|
||||||
|
))]
|
||||||
|
|
||||||
|
use io_uring::IoUring;
|
||||||
|
|
||||||
|
// Currently, we are running some of the tests on Kernels where io_uring is not supported
|
||||||
|
// to check if the fallback mechanism works, this comes with the limitation that we are not
|
||||||
|
// able to run some checks (e.g., asserting a poll returns pending). This utiliy function
|
||||||
|
// is useful when we want to run a test only in Linux targets where io_uring is supported.
|
||||||
|
pub fn io_uring_supported() -> bool {
|
||||||
|
match IoUring::new(256) {
|
||||||
|
Ok(_) => true,
|
||||||
|
// The Kernel does not support io-uring
|
||||||
|
Err(e) if e.raw_os_error() == Some(libc::ENOSYS) => false,
|
||||||
|
Err(_) => unreachable!(
|
||||||
|
"The target should either support io_uring or return ENOSYS if not supported"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user