Skip to content

Commit 9c97e9d

Browse files
committed
[nextest-runner] always close stdin before running tests
Some tests might accidentally read from standard input. Always close it.
1 parent a03f23c commit 9c97e9d

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

cargo-nextest/src/tests_integration/fixtures.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub static EXPECTED_LIST: Lazy<Vec<TestInfo>> = Lazy::new(|| {
6161
("test_result_failure", false),
6262
("test_slow_timeout", true),
6363
("test_slow_timeout_2", true),
64+
("test_stdin_closed", false),
6465
("test_subprocess_doesnt_exit", false),
6566
("test_success", false),
6667
("test_success_should_panic", false),
@@ -302,6 +303,7 @@ pub fn check_run_output(stderr: &[u8], relocated: bool) {
302303
(false, "nextest-tests::basic test_result_failure"),
303304
(true, "nextest-tests::basic test_success_should_panic"),
304305
(false, "nextest-tests::basic test_failure_assert"),
306+
(true, "nextest-tests::basic test_stdin_closed"),
305307
(false, "nextest-tests::basic test_flaky_mod_6"),
306308
(cwd_pass, "nextest-tests::basic test_cwd"),
307309
(
@@ -325,10 +327,10 @@ pub fn check_run_output(stderr: &[u8], relocated: bool) {
325327
}
326328

327329
let summary_reg = if relocated {
328-
Regex::new(r"Summary \[.*\] *25 tests run: 17 passed \(1 leaky\), 8 failed, 4 skipped")
330+
Regex::new(r"Summary \[.*\] *26 tests run: 18 passed \(1 leaky\), 8 failed, 4 skipped")
329331
.unwrap()
330332
} else {
331-
Regex::new(r"Summary \[.*\] *25 tests run: 18 passed \(1 leaky\), 7 failed, 4 skipped")
333+
Regex::new(r"Summary \[.*\] *26 tests run: 19 passed \(1 leaky\), 7 failed, 4 skipped")
332334
.unwrap()
333335
};
334336
assert!(

fixtures/nextest-tests/tests/basic.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) The nextest Contributors
2-
use std::{env, path::Path};
2+
use std::{env, io::Read, path::Path};
33

44
#[test]
55
fn test_success() {}
@@ -201,3 +201,15 @@ fn sleep_cmd(secs: usize) -> std::process::Command {
201201
cmd.arg(&format!("{secs}"));
202202
cmd
203203
}
204+
205+
#[test]
206+
fn test_stdin_closed() {
207+
let mut buf = [0u8; 8];
208+
// This should succeed with 0 because it's attached to /dev/null or its Windows equivalent.
209+
assert_eq!(
210+
0,
211+
std::io::stdin()
212+
.read(&mut buf)
213+
.expect("reading from /dev/null succeeded")
214+
);
215+
}

nextest-runner/src/runner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::{
2323
convert::Infallible,
2424
marker::PhantomData,
2525
num::NonZeroUsize,
26+
process::Stdio,
2627
sync::{
2728
atomic::{AtomicBool, Ordering},
2829
Arc,
@@ -413,6 +414,7 @@ impl<'a> TestRunnerInner<'a> {
413414

414415
// Debug environment variable for testing.
415416
cmd.env("__NEXTEST_ATTEMPT", format!("{}", attempt));
417+
cmd.stdin(Stdio::null());
416418

417419
if !self.no_capture {
418420
// Capture stdout and stderr.

nextest-runner/tests/integration/fixtures.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ pub(crate) static EXPECTED_TESTS: Lazy<BTreeMap<&'static str, Vec<TestFixture>>>
116116
TestFixture { name: "test_result_failure", status: FixtureStatus::Fail },
117117
TestFixture { name: "test_slow_timeout", status: FixtureStatus::IgnoredPass },
118118
TestFixture { name: "test_slow_timeout_2", status: FixtureStatus::IgnoredPass },
119+
TestFixture { name: "test_stdin_closed", status: FixtureStatus::Pass },
119120
TestFixture { name: "test_subprocess_doesnt_exit", status: FixtureStatus::Leak },
120121
TestFixture { name: "test_success", status: FixtureStatus::Pass },
121122
TestFixture { name: "test_success_should_panic", status: FixtureStatus::Pass },

0 commit comments

Comments
 (0)