From b2733e64d900ac237211360848326f3c4caa23f5 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 27 Feb 2022 17:37:03 -0500 Subject: simplify --- tests/basic.rs | 70 +++++-------- tests/behavior.rs | 309 ++++++++++++++++++++++++------------------------------ tests/pipe.rs | 76 ++++++-------- tests/split.rs | 237 ++++++++++++++++++++--------------------- tests/winch.rs | 49 ++++----- 5 files changed, 333 insertions(+), 408 deletions(-) diff --git a/tests/basic.rs b/tests/basic.rs index ed75e60..fd74463 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -22,65 +22,53 @@ fn test_cat_blocking() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_cat_async() { +async fn test_cat_async() { use futures::stream::StreamExt as _; use tokio::io::AsyncWriteExt as _; - let status = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = - pty_process::Command::new("cat").spawn(&pts).unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut child = pty_process::Command::new("cat").spawn(&pts).unwrap(); - let (pty_r, mut pty_w) = pty.split(); + let (pty_r, mut pty_w) = pty.split(); - pty_w.write_all(b"foo\n").await.unwrap(); + pty_w.write_all(b"foo\n").await.unwrap(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); - pty_w.write_all(&[4u8]).await.unwrap(); - child.wait().await.unwrap() - }); + pty_w.write_all(&[4u8]).await.unwrap(); + let status = child.wait().await.unwrap(); assert_eq!(status.code().unwrap(), 0); } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_yes_async() { +async fn test_yes_async() { use tokio::io::AsyncReadExt as _; - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = - pty_process::Command::new("yes").spawn(&pts).unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut child = pty_process::Command::new("yes").spawn(&pts).unwrap(); - let mut buf = [0u8; 3]; + let mut buf = [0u8; 3]; - let bytes = pty.read_buf(&mut &mut buf[..]).await.unwrap(); - assert_eq!(&buf[..bytes], b"y\r\n"); + let bytes = pty.read_buf(&mut &mut buf[..]).await.unwrap(); + assert_eq!(&buf[..bytes], b"y\r\n"); - let (mut pty_r, _pty_w) = pty.split(); - let bytes = pty_r.read_buf(&mut &mut buf[..]).await.unwrap(); - assert_eq!(&buf[..bytes], b"y\r\n"); + let (mut pty_r, _pty_w) = pty.split(); + let bytes = pty_r.read_buf(&mut &mut buf[..]).await.unwrap(); + assert_eq!(&buf[..bytes], b"y\r\n"); - let (mut pty_r, _pty_w) = pty.into_split(); - let bytes = pty_r.read_buf(&mut &mut buf[..]).await.unwrap(); - assert_eq!(&buf[..bytes], b"y\r\n"); + let (mut pty_r, _pty_w) = pty.into_split(); + let bytes = pty_r.read_buf(&mut &mut buf[..]).await.unwrap(); + assert_eq!(&buf[..bytes], b"y\r\n"); - child.kill().await.unwrap() - }); + child.kill().await.unwrap() } diff --git a/tests/behavior.rs b/tests/behavior.rs index 7969f72..bb40e35 100644 --- a/tests/behavior.rs +++ b/tests/behavior.rs @@ -29,41 +29,36 @@ fn test_multiple() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_multiple_async() { +async fn test_multiple_async() { use futures::stream::StreamExt as _; - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = pty_process::Command::new("echo") - .arg("foo") - .spawn(&pts) - .unwrap(); - let (pty_r, _) = pty.split(); + let mut child = pty_process::Command::new("echo") + .arg("foo") + .spawn(&pts) + .unwrap(); + let (pty_r, _) = pty.split(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); - let status = child.wait().await.unwrap(); - assert_eq!(status.code().unwrap(), 0); + let status = child.wait().await.unwrap(); + assert_eq!(status.code().unwrap(), 0); - let mut child = pty_process::Command::new("echo") - .arg("bar") - .spawn(&pts) - .unwrap(); + let mut child = pty_process::Command::new("echo") + .arg("bar") + .spawn(&pts) + .unwrap(); - assert_eq!(output.next().await.unwrap(), "bar\r\n"); + assert_eq!(output.next().await.unwrap(), "bar\r\n"); - let status = child.wait().await.unwrap(); - assert_eq!(status.code().unwrap(), 0); - }); + let status = child.wait().await.unwrap(); + assert_eq!(status.code().unwrap(), 0); } #[test] @@ -138,118 +133,98 @@ fn test_multiple_configured() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_multiple_configured_async() { +async fn test_multiple_configured_async() { use futures::stream::StreamExt as _; use std::os::unix::io::FromRawFd as _; use tokio::io::AsyncBufReadExt as _; - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let (pty_r, _) = pty.split(); - - let (stderr_pipe_r, stderr_pipe_w) = nix::unistd::pipe().unwrap(); - let mut stderr_pipe_r = tokio::io::BufReader::new(unsafe { - tokio::fs::File::from_raw_fd(stderr_pipe_r) - }); - let (pre_exec_pipe_r, pre_exec_pipe_w) = - nix::unistd::pipe().unwrap(); - let mut pre_exec_pipe_r = tokio::io::BufReader::new(unsafe { - tokio::fs::File::from_raw_fd(pre_exec_pipe_r) - }); - let mut cmd = pty_process::Command::new("perl"); - cmd.arg( - "-Esay 'foo'; \ + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let (pty_r, _) = pty.split(); + + let (stderr_pipe_r, stderr_pipe_w) = nix::unistd::pipe().unwrap(); + let mut stderr_pipe_r = tokio::io::BufReader::new(unsafe { + tokio::fs::File::from_raw_fd(stderr_pipe_r) + }); + let (pre_exec_pipe_r, pre_exec_pipe_w) = nix::unistd::pipe().unwrap(); + let mut pre_exec_pipe_r = tokio::io::BufReader::new(unsafe { + tokio::fs::File::from_raw_fd(pre_exec_pipe_r) + }); + let mut cmd = pty_process::Command::new("perl"); + cmd.arg( + "-Esay 'foo'; \ say STDERR 'foo-stderr'; \ open my $fh, '>&=3'; \ say $fh 'foo-3';", - ) - .stderr(unsafe { - std::process::Stdio::from_raw_fd(stderr_pipe_w) - }); - unsafe { - cmd.pre_exec(move || { - nix::unistd::dup2(pre_exec_pipe_w, 3)?; - nix::fcntl::fcntl( - 3, - nix::fcntl::F_SETFD(nix::fcntl::FdFlag::empty()), - )?; - Ok(()) - }); - } - let mut child = cmd.spawn(&pts).unwrap(); - - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - - let mut buf = vec![]; - tokio::time::timeout( - std::time::Duration::from_secs(5), - stderr_pipe_r.read_until(b'\n', &mut buf), - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - std::string::String::from_utf8(buf).unwrap(), - "foo-stderr\n" - ); - - let mut buf = vec![]; - tokio::time::timeout( - std::time::Duration::from_secs(5), - pre_exec_pipe_r.read_until(b'\n', &mut buf), - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - std::string::String::from_utf8(buf).unwrap(), - "foo-3\n" - ); - - let status = child.wait().await.unwrap(); - assert_eq!(status.code().unwrap(), 0); - - let mut child = cmd.spawn(&pts).unwrap(); - - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - - let mut buf = vec![]; - tokio::time::timeout( - std::time::Duration::from_secs(5), - stderr_pipe_r.read_until(b'\n', &mut buf), - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - std::string::String::from_utf8(buf).unwrap(), - "foo-stderr\n" - ); - - let mut buf = vec![]; - tokio::time::timeout( - std::time::Duration::from_secs(5), - pre_exec_pipe_r.read_until(b'\n', &mut buf), - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - std::string::String::from_utf8(buf).unwrap(), - "foo-3\n" - ); - - let status = child.wait().await.unwrap(); - assert_eq!(status.code().unwrap(), 0); + ) + .stderr(unsafe { std::process::Stdio::from_raw_fd(stderr_pipe_w) }); + unsafe { + cmd.pre_exec(move || { + nix::unistd::dup2(pre_exec_pipe_w, 3)?; + nix::fcntl::fcntl( + 3, + nix::fcntl::F_SETFD(nix::fcntl::FdFlag::empty()), + )?; + Ok(()) }); + } + let mut child = cmd.spawn(&pts).unwrap(); + + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + + let mut buf = vec![]; + tokio::time::timeout( + std::time::Duration::from_secs(5), + stderr_pipe_r.read_until(b'\n', &mut buf), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(std::string::String::from_utf8(buf).unwrap(), "foo-stderr\n"); + + let mut buf = vec![]; + tokio::time::timeout( + std::time::Duration::from_secs(5), + pre_exec_pipe_r.read_until(b'\n', &mut buf), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(std::string::String::from_utf8(buf).unwrap(), "foo-3\n"); + + let status = child.wait().await.unwrap(); + assert_eq!(status.code().unwrap(), 0); + + let mut child = cmd.spawn(&pts).unwrap(); + + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + + let mut buf = vec![]; + tokio::time::timeout( + std::time::Duration::from_secs(5), + stderr_pipe_r.read_until(b'\n', &mut buf), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(std::string::String::from_utf8(buf).unwrap(), "foo-stderr\n"); + + let mut buf = vec![]; + tokio::time::timeout( + std::time::Duration::from_secs(5), + pre_exec_pipe_r.read_until(b'\n', &mut buf), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(std::string::String::from_utf8(buf).unwrap(), "foo-3\n"); + + let status = child.wait().await.unwrap(); + assert_eq!(status.code().unwrap(), 0); } #[test] @@ -270,33 +245,28 @@ fn test_controlling_terminal() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_controlling_terminal_async() { +async fn test_controlling_terminal_async() { use futures::stream::StreamExt as _; - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let (pty_r, _) = pty.split(); - let mut child = pty_process::Command::new("perl") - .arg( - "-Eopen my $fh, '<', '/dev/tty' or die; \ + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let (pty_r, _) = pty.split(); + let mut child = pty_process::Command::new("perl") + .arg( + "-Eopen my $fh, '<', '/dev/tty' or die; \ if (-t $fh) { say 'true' } else { say 'false' }", - ) - .spawn(&pts) - .unwrap(); + ) + .spawn(&pts) + .unwrap(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "true\r\n"); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "true\r\n"); - let status = child.wait().await.unwrap(); - assert_eq!(status.code().unwrap(), 0); - }); + let status = child.wait().await.unwrap(); + assert_eq!(status.code().unwrap(), 0); } #[test] @@ -317,29 +287,24 @@ fn test_session_leader() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_session_leader_async() { +async fn test_session_leader_async() { use futures::stream::StreamExt as _; - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = pty_process::Command::new("python") - .arg("-cimport os; print(os.getpid() == os.getsid(0))") - .spawn(&pts) - .unwrap(); - - let (pty_r, _) = pty.split(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "True\r\n"); - - let status = child.wait().await.unwrap(); - eprintln!("{:?}", status); - assert_eq!(status.code().unwrap(), 0); - }); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut child = pty_process::Command::new("python") + .arg("-cimport os; print(os.getpid() == os.getsid(0))") + .spawn(&pts) + .unwrap(); + + let (pty_r, _) = pty.split(); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "True\r\n"); + + let status = child.wait().await.unwrap(); + eprintln!("{:?}", status); + assert_eq!(status.code().unwrap(), 0); } diff --git a/tests/pipe.rs b/tests/pipe.rs index e09334b..cbe42ad 100644 --- a/tests/pipe.rs +++ b/tests/pipe.rs @@ -60,50 +60,42 @@ fn test_pipe_blocking() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_pipe_async() { +async fn test_pipe_async() { use std::os::unix::io::FromRawFd as _; use tokio::io::AsyncReadExt as _; - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let (read_fd, write_fd) = - nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC).unwrap(); - - let pty_from = pty_process::Pty::new().unwrap(); - let pts_from = pty_from.pts().unwrap(); - pty_from.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut cmd_from = pty_process::Command::new("seq"); - cmd_from.args(["1", "10"]); - cmd_from.stdout(unsafe { - std::process::Stdio::from_raw_fd(write_fd) - }); - let mut child_from = cmd_from.spawn(&pts_from).unwrap(); - - let mut pty_to = pty_process::Pty::new().unwrap(); - let pts_to = pty_to.pts().unwrap(); - let mut cmd_to = pty_process::Command::new("tac"); - cmd_to - .stdin(unsafe { std::process::Stdio::from_raw_fd(read_fd) }); - let mut child_to = cmd_to.spawn(&pts_to).unwrap(); - - assert!(child_from.wait().await.unwrap().success()); - drop(cmd_from); - - // wait for the `tac` process to finish generating output (we - // don't really have a good way to detect when that happens) - tokio::time::sleep(std::time::Duration::from_millis(100)).await; - - let mut buf = [0u8; 1024]; - let bytes = pty_to.read(&mut buf).await.unwrap(); - assert_eq!( - &buf[..bytes], - b"10\r\n9\r\n8\r\n7\r\n6\r\n5\r\n4\r\n3\r\n2\r\n1\r\n" - ); - - assert!(child_to.wait().await.unwrap().success()); - }); + let (read_fd, write_fd) = + nix::unistd::pipe2(nix::fcntl::OFlag::O_CLOEXEC).unwrap(); + + let pty_from = pty_process::Pty::new().unwrap(); + let pts_from = pty_from.pts().unwrap(); + pty_from.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut cmd_from = pty_process::Command::new("seq"); + cmd_from.args(["1", "10"]); + cmd_from.stdout(unsafe { std::process::Stdio::from_raw_fd(write_fd) }); + let mut child_from = cmd_from.spawn(&pts_from).unwrap(); + + let mut pty_to = pty_process::Pty::new().unwrap(); + let pts_to = pty_to.pts().unwrap(); + let mut cmd_to = pty_process::Command::new("tac"); + cmd_to.stdin(unsafe { std::process::Stdio::from_raw_fd(read_fd) }); + let mut child_to = cmd_to.spawn(&pts_to).unwrap(); + + assert!(child_from.wait().await.unwrap().success()); + drop(cmd_from); + + // wait for the `tac` process to finish generating output (we + // don't really have a good way to detect when that happens) + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + + let mut buf = [0u8; 1024]; + let bytes = pty_to.read(&mut buf).await.unwrap(); + assert_eq!( + &buf[..bytes], + b"10\r\n9\r\n8\r\n7\r\n6\r\n5\r\n4\r\n3\r\n2\r\n1\r\n" + ); + + assert!(child_to.wait().await.unwrap().success()); } diff --git a/tests/split.rs b/tests/split.rs index f537f17..fc9b9d0 100644 --- a/tests/split.rs +++ b/tests/split.rs @@ -1,108 +1,82 @@ mod helpers; #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_split() { +async fn test_split() { use futures::stream::StreamExt as _; use tokio::io::AsyncWriteExt as _; - let rt = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); - rt.block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut cmd = pty_process::Command::new("perl"); - cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]); - let mut child = cmd.spawn(&pts).unwrap(); - - { - pty.write_all(b"foo\n").await.unwrap(); - let (pty_r, _) = pty.split(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - } - - { - let (pty_r, mut pty_w) = pty.split(); - pty_w.write_all(b"foo\n").await.unwrap(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - assert_eq!(output.next().await.unwrap(), "foo\r\n"); - } - - { - let (pty_r, pty_w) = pty.split(); - pty_w.resize(pty_process::Size::new(25, 80)).unwrap(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "WINCH\r\n"); - } - - pty.write_all(&[4u8]).await.unwrap(); - child.wait().await.unwrap() - }); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut cmd = pty_process::Command::new("perl"); + cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]); + let mut child = cmd.spawn(&pts).unwrap(); + + { + pty.write_all(b"foo\n").await.unwrap(); + let (pty_r, _) = pty.split(); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + } + + { + let (pty_r, mut pty_w) = pty.split(); + pty_w.write_all(b"foo\n").await.unwrap(); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + assert_eq!(output.next().await.unwrap(), "foo\r\n"); + } + + { + let (pty_r, pty_w) = pty.split(); + pty_w.resize(pty_process::Size::new(25, 80)).unwrap(); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "WINCH\r\n"); + } + + pty.write_all(&[4u8]).await.unwrap(); + child.wait().await.unwrap(); } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_into_split() { +async fn test_into_split() { use tokio::io::{AsyncBufReadExt as _, AsyncWriteExt as _}; - let rt = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); - rt.block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut cmd = pty_process::Command::new("perl"); - cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]); - let mut child = cmd.spawn(&pts).unwrap(); - - { - pty.write_all(b"foo\n").await.unwrap(); - let (pty_r, pty_w) = pty.into_split(); - let mut ptybuf = tokio::io::BufReader::new(pty_r); - for _ in 0..2 { - let mut buf = vec![]; - tokio::time::timeout( - std::time::Duration::from_secs(5), - ptybuf.read_until(b'\n', &mut buf), - ) - .await - .unwrap() - .unwrap(); - assert_eq!(&buf[..], b"foo\r\n"); - } - pty = ptybuf.into_inner().unsplit(pty_w).unwrap(); - } - - { - let (pty_r, mut pty_w) = pty.into_split(); - pty_w.write_all(b"foo\n").await.unwrap(); - let mut ptybuf = tokio::io::BufReader::new(pty_r); - for _ in 0..2 { - let mut buf = vec![]; - tokio::time::timeout( - std::time::Duration::from_secs(5), - ptybuf.read_until(b'\n', &mut buf), - ) - .await - .unwrap() - .unwrap(); - assert_eq!(&buf[..], b"foo\r\n"); - } - pty = ptybuf.into_inner().unsplit(pty_w).unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut cmd = pty_process::Command::new("perl"); + cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]); + let mut child = cmd.spawn(&pts).unwrap(); + + { + pty.write_all(b"foo\n").await.unwrap(); + let (pty_r, pty_w) = pty.into_split(); + let mut ptybuf = tokio::io::BufReader::new(pty_r); + for _ in 0..2 { + let mut buf = vec![]; + tokio::time::timeout( + std::time::Duration::from_secs(5), + ptybuf.read_until(b'\n', &mut buf), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(&buf[..], b"foo\r\n"); } - - { - let (pty_r, pty_w) = pty.into_split(); - pty_w.resize(pty_process::Size::new(25, 80)).unwrap(); - let mut ptybuf = tokio::io::BufReader::new(pty_r); + pty = ptybuf.into_inner().unsplit(pty_w).unwrap(); + } + + { + let (pty_r, mut pty_w) = pty.into_split(); + pty_w.write_all(b"foo\n").await.unwrap(); + let mut ptybuf = tokio::io::BufReader::new(pty_r); + for _ in 0..2 { let mut buf = vec![]; tokio::time::timeout( std::time::Duration::from_secs(5), @@ -111,45 +85,56 @@ fn test_into_split() { .await .unwrap() .unwrap(); - assert_eq!(&buf[..], b"WINCH\r\n"); - pty = ptybuf.into_inner().unsplit(pty_w).unwrap(); + assert_eq!(&buf[..], b"foo\r\n"); } + pty = ptybuf.into_inner().unsplit(pty_w).unwrap(); + } + + { + let (pty_r, pty_w) = pty.into_split(); + pty_w.resize(pty_process::Size::new(25, 80)).unwrap(); + let mut ptybuf = tokio::io::BufReader::new(pty_r); + let mut buf = vec![]; + tokio::time::timeout( + std::time::Duration::from_secs(5), + ptybuf.read_until(b'\n', &mut buf), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(&buf[..], b"WINCH\r\n"); + pty = ptybuf.into_inner().unsplit(pty_w).unwrap(); + } - pty.write_all(&[4u8]).await.unwrap(); - child.wait().await.unwrap() - }); + pty.write_all(&[4u8]).await.unwrap(); + child.wait().await.unwrap(); } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_into_split_error() { - let rt = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); - rt.block_on(async { - let pty1 = pty_process::Pty::new().unwrap(); - let pty2 = pty_process::Pty::new().unwrap(); - - let (pty1_r, pty1_w) = pty1.into_split(); - let (pty2_r, pty2_w) = pty2.into_split(); - - let (pty1_r, pty2_w) = if let Err(pty_process::Error::Unsplit(r, w)) = - pty1_r.unsplit(pty2_w) - { - (r, w) - } else { - panic!("fail"); - }; - let (pty2_r, pty1_w) = if let Err(pty_process::Error::Unsplit(r, w)) = - pty2_r.unsplit(pty1_w) - { - (r, w) - } else { - panic!("fail"); - }; - - let _pty1 = pty1_r.unsplit(pty1_w).unwrap(); - let _pty2 = pty2_r.unsplit(pty2_w).unwrap(); - }); +async fn test_into_split_error() { + let pty1 = pty_process::Pty::new().unwrap(); + let pty2 = pty_process::Pty::new().unwrap(); + + let (pty1_r, pty1_w) = pty1.into_split(); + let (pty2_r, pty2_w) = pty2.into_split(); + + let (pty1_r, pty2_w) = if let Err(pty_process::Error::Unsplit(r, w)) = + pty1_r.unsplit(pty2_w) + { + (r, w) + } else { + panic!("fail"); + }; + let (pty2_r, pty1_w) = if let Err(pty_process::Error::Unsplit(r, w)) = + pty2_r.unsplit(pty1_w) + { + (r, w) + } else { + panic!("fail"); + }; + + let _pty1 = pty1_r.unsplit(pty1_w).unwrap(); + let _pty2 = pty2_r.unsplit(pty2_w).unwrap(); } diff --git a/tests/winch.rs b/tests/winch.rs index 6b16ca9..63455e9 100644 --- a/tests/winch.rs +++ b/tests/winch.rs @@ -27,36 +27,31 @@ fn test_winch_std() { } #[cfg(feature = "async")] +#[tokio::main] #[test] -fn test_winch_async() { +async fn test_winch_async() { use futures::stream::StreamExt as _; use tokio::io::AsyncWriteExt as _; - let status = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut pty = pty_process::Pty::new().unwrap(); - let pts = pty.pts().unwrap(); - pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = pty_process::Command::new("perl") - .args(&[ - "-E", - "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>", - ]) - .spawn(&pts) - .unwrap(); - - let (pty_r, mut pty_w) = pty.split(); - let mut output = helpers::output_async(pty_r); - assert_eq!(output.next().await.unwrap(), "started\r\n"); - - pty_w.resize(pty_process::Size::new(25, 80)).unwrap(); - assert_eq!(output.next().await.unwrap(), "WINCH\r\n"); - - pty_w.write_all(b"\n").await.unwrap(); - child.wait().await.unwrap() - }); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut child = pty_process::Command::new("perl") + .args(&[ + "-E", + "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>", + ]) + .spawn(&pts) + .unwrap(); + + let (pty_r, mut pty_w) = pty.split(); + let mut output = helpers::output_async(pty_r); + assert_eq!(output.next().await.unwrap(), "started\r\n"); + + pty_w.resize(pty_process::Size::new(25, 80)).unwrap(); + assert_eq!(output.next().await.unwrap(), "WINCH\r\n"); + + pty_w.write_all(b"\n").await.unwrap(); + let status = child.wait().await.unwrap(); assert_eq!(status.code().unwrap(), 0); } -- cgit v1.2.3