Skip to content

Commit

Permalink
bzip2.rs: test that triggers isatty
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertdev committed Nov 12, 2024
1 parent a192378 commit a8e1f55
Showing 1 changed file with 160 additions and 0 deletions.
160 changes: 160 additions & 0 deletions tests/quick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,56 @@ macro_rules! expect_success {
};
}

#[cfg(unix)]
unsafe fn custom_tty() -> (
std::sync::MutexGuard<'static, ()>,
std::process::Stdio,
std::process::Stdio,
) {
use std::{os::fd::FromRawFd, sync::Mutex};

// only one thread should be doing this at a time
static X: Mutex<()> = Mutex::new(());

let guard = X.lock().unwrap();

// Open a new PTY master device
let master_fd = libc::posix_openpt(libc::O_RDWR | libc::O_NOCTTY);
if master_fd == -1 {
panic!("{}", std::io::Error::last_os_error());
}

// Grant access to the slave PTY
if unsafe { libc::grantpt(master_fd) } < 0 {
panic!("{}", std::io::Error::last_os_error());
}

// Unlock the slave PTY
if unsafe { libc::unlockpt(master_fd) } < 0 {
panic!("{}", std::io::Error::last_os_error());
}

// Get the path to the slave PTY
let slave_path_ptr = unsafe { libc::ptsname(master_fd) };
if slave_path_ptr.is_null() {
panic!("{}", std::io::Error::last_os_error());
}

// Open the slave PTY
let slave_fd = unsafe { libc::open(slave_path_ptr, libc::O_RDWR) };
if slave_fd < 0 {
panic!("{}", std::io::Error::last_os_error());
}

unsafe {
(
guard,
Stdio::from_raw_fd(master_fd),
Stdio::from_raw_fd(slave_fd),
)
}
}

fn command() -> Command {
match env::var("RUNNER") {
Ok(runner) if !runner.is_empty() => {
Expand Down Expand Up @@ -867,6 +917,21 @@ mod decompress_command {
),),
);
}

#[test]
fn stdin_is_terminal() {
let mut cmd = command();

let (_guard, _master, tty) = unsafe { custom_tty() };

expect_failure!(
cmd.arg("-d").arg("-c").stdin(tty),
concat!(
"bzip2: I won't read compressed data from a terminal.\n",
"bzip2: For help, type: `bzip2 --help'.\n",
),
);
}
}

mod test_command {
Expand Down Expand Up @@ -1041,6 +1106,21 @@ mod test_command {
),
);
}

#[test]
fn stdin_is_terminal() {
let mut cmd = command();

let (_guard, _master, tty) = unsafe { custom_tty() };

expect_failure!(
cmd.arg("-t").stdin(tty),
concat!(
"bzip2: I won't read compressed data from a terminal.\n",
"bzip2: For help, type: `bzip2 --help'.\n",
),
);
}
}

mod compress_command {
Expand Down Expand Up @@ -1481,4 +1561,84 @@ mod compress_command {
),
);
}

#[test]
fn stdout_is_terminal_i2o() {
let mut cmd = command();

let (_guard, _master, tty) = unsafe { custom_tty() };

expect_failure!(
cmd.arg("-z").arg("-c").stdin(Stdio::piped()).stdout(tty),
concat!(
"bzip2: I won't write compressed data to a terminal.\n",
"bzip2: For help, type: `bzip2 --help'.\n",
),
);
}

#[test]
#[cfg(unix)]
fn stdout_is_terminal_f2o() {
let mut cmd = command();

let tmpdir = tempfile::tempdir().unwrap();

let sample1_ref = tmpdir.path().join("sample1.ref");
std::fs::copy("tests/input/quick/sample1.ref", &sample1_ref).unwrap();

let (_guard, _master, tty) = unsafe { custom_tty() };

expect_failure!(
cmd.arg("-z")
.arg("-c")
.arg("-k")
.arg(&sample1_ref)
.stdout(tty),
concat!(
"bzip2: I won't write compressed data to a terminal.\n",
"bzip2: For help, type: `bzip2 --help'.\n",
),
);

// the `-k` flag should keep the input file
assert!(sample1_ref.exists());
}

#[test]
#[cfg(unix)]
fn io_error() {
let mut cmd = command();

let tmpdir = tempfile::tempdir().unwrap();

let sample1_ref = tmpdir.path().join("sample1.ref");
std::fs::copy("tests/input/quick/sample1.ref", &sample1_ref).unwrap();

let (_guard, master, tty) = unsafe { custom_tty() };

// dropping here triggers an IO error down the line
drop(master);

expect_failure!(
cmd.arg("-z")
.arg("-c")
.arg("-k")
.arg(&sample1_ref)
.stdout(tty),
format!(
concat!(
"\n",
"bzip2: I/O or other error, bailing out. Possible reason follows.\n",
"bzip2: Input/output error\n",
"\tInput file = {in_file}, output file = (stdout)\n",
""
),
in_file = sample1_ref.display(),
)
);

// the `-k` flag should keep the input file
assert!(sample1_ref.exists());
}
}

0 comments on commit a8e1f55

Please sign in to comment.