diff --git a/.github/buildomat/jobs/test-full.sh b/.github/buildomat/jobs/test-full.sh new file mode 100644 index 00000000000..e335aeeb528 --- /dev/null +++ b/.github/buildomat/jobs/test-full.sh @@ -0,0 +1,44 @@ +#!/bin/bash +#: +#: name = "illumos-test-full" +#: variety = "basic" +#: target = "omnios-r151038" +#: rust_toolchain = "stable" + +# basic illumos test job with --features full. +# TODO(eliza): consider splitting the "build" and "test" jobs into separate +# buildomat jobs, so that the build and test jobs can fail independently. + +set -o errexit +set -o pipefail +set -o xtrace + + +# These are the same env vars that are set for all GitHub Actions CI jobs. +export RUSTFLAGS="-Dwarnings" +export RUST_BACKTRACE=1 +# We're building once, so there's no need to incur the overhead of an +# incremental build. +export CARGO_INCREMENTAL=0 + +# NOTE: Currently we use the latest cargo-nextest release, since this is what +# the Linux CI jobs do. If we ever start pinning our nextest version, this +# should be changed to match that. +NEXTEST_VERSION='latest' + + +curl -sSfL --retry 10 "https://get.nexte.st/$NEXTEST_VERSION/illumos" | gunzip | tar -xvf - -C ~/.cargo/bin + +# Print the current test execution environment +uname -a +cargo --version +rustc --version + +banner build +ptime -m cargo test --no-run --all --verbose --features full + +banner tests +ptime -m cargo nextest run --features full --no-fail-fast + +banner doctests +ptime -m cargo test --doc --verbose --features full diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index 08d89c49c03..baab6805b6c 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -1160,9 +1160,14 @@ impl LocalState { #[track_caller] fn assert_called_from_owner_thread(&self) { - // FreeBSD has some weirdness around thread-local destruction. + // BSDs and Solarises has some weirdness around thread-local destruction. // TODO: remove this hack when thread id is cleaned up - #[cfg(not(any(target_os = "openbsd", target_os = "freebsd")))] + #[cfg(not(any( + target_os = "openbsd", + target_os = "freebsd", + target_os = "illumos", + target_os = "solaris", + )))] debug_assert!( // if we couldn't get the thread ID because we're dropping the local // data, skip the assertion --- the `Drop` impl is not going to be diff --git a/tokio/tests/io_async_fd.rs b/tokio/tests/io_async_fd.rs index 3ab1cebd884..a9f22a0e3d7 100644 --- a/tokio/tests/io_async_fd.rs +++ b/tokio/tests/io_async_fd.rs @@ -135,15 +135,17 @@ fn socketpair() -> (FileDescriptor, FileDescriptor) { fds } -fn drain(mut fd: &FileDescriptor) { +fn drain(mut fd: &FileDescriptor, mut amt: usize) { let mut buf = [0u8; 512]; - #[allow(clippy::unused_io_amount)] - loop { + while amt > 0 { match fd.read(&mut buf[..]) { - Err(e) if e.kind() == ErrorKind::WouldBlock => break, + Err(e) if e.kind() == ErrorKind::WouldBlock => {} Ok(0) => panic!("unexpected EOF"), Err(e) => panic!("unexpected error: {:?}", e), - Ok(_) => continue, + Ok(x) => { + amt -= x; + continue; + } } } } @@ -219,10 +221,10 @@ async fn reset_writable() { let mut guard = afd_a.writable().await.unwrap(); // Write until we get a WouldBlock. This also clears the ready state. - while guard - .try_io(|_| afd_a.get_ref().write(&[0; 512][..])) - .is_ok() - {} + let mut bytes = 0; + while let Ok(Ok(amt)) = guard.try_io(|_| afd_a.get_ref().write(&[0; 512][..])) { + bytes += amt; + } // Writable state should be cleared now. let writable = afd_a.writable(); @@ -234,7 +236,7 @@ async fn reset_writable() { } // Read from the other side; we should become writable now. - drain(&b); + drain(&b, bytes); let _ = writable.await.unwrap(); } @@ -386,7 +388,10 @@ async fn poll_fns() { let afd_b = Arc::new(AsyncFd::new(b).unwrap()); // Fill up the write side of A - while afd_a.get_ref().write(&[0; 512]).is_ok() {} + let mut bytes = 0; + while let Ok(amt) = afd_a.get_ref().write(&[0; 512]) { + bytes += amt; + } let waker = TestWaker::new(); @@ -446,7 +451,7 @@ async fn poll_fns() { } // Make it writable now - drain(afd_b.get_ref()); + drain(afd_b.get_ref(), bytes); // now we should be writable (ie - the waker for poll_write should still be registered after we wake the read side) let _ = write_fut.await; diff --git a/tokio/tests/net_unix_pipe.rs b/tokio/tests/net_unix_pipe.rs index 37b8b41bd31..a28303e97c3 100644 --- a/tokio/tests/net_unix_pipe.rs +++ b/tokio/tests/net_unix_pipe.rs @@ -457,15 +457,14 @@ async fn anon_pipe_simple_send() -> io::Result<()> { } #[tokio::test] -async fn anon_pipe_spawn_echo() -> std::io::Result<()> { +async fn anon_pipe_spawn_printf() -> std::io::Result<()> { use tokio::process::Command; const DATA: &str = "this is some data to write to the pipe"; let (tx, mut rx) = pipe::pipe()?; - let status = Command::new("echo") - .arg("-n") + let status = Command::new("printf") .arg(DATA) .stdout(tx.into_blocking_fd()?) .status(); diff --git a/tokio/tests/uds_stream.rs b/tokio/tests/uds_stream.rs index b8c4e6a8eed..cb40cbd1832 100644 --- a/tokio/tests/uds_stream.rs +++ b/tokio/tests/uds_stream.rs @@ -406,6 +406,17 @@ async fn epollhup() -> io::Result<()> { drop(listener); let err = connect.await.unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::ConnectionReset); + let errno = err.kind(); + assert!( + // As far as I can tell, whether we see ECONNREFUSED or ECONNRESET here + // seems relatively inconsistent, at least on non-Linux operating + // systems. The difference in meaning between these errnos is not + // particularly well-defined, so let's just accept either. + matches!( + errno, + io::ErrorKind::ConnectionRefused | io::ErrorKind::ConnectionReset + ), + "unexpected error kind: {errno:?} (expected ConnectionRefused or ConnectionReset)" + ); Ok(()) }