Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,97 @@
|
||||
//! 真子进程覆盖输出上限、后代持有管道和正常/超时两种回收路径。
|
||||
|
||||
use super::Directory;
|
||||
use dever::process::testing::capture;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
fn test_process_timeout_reaps_only_its_owned_group() {
|
||||
let directory = Directory::new();
|
||||
let mut unrelated = std::process::Command::new("/bin/sleep")
|
||||
.arg("30")
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let output = capture(
|
||||
Path::new("/bin/sh"),
|
||||
&[
|
||||
"-c".into(),
|
||||
"/bin/sh -c 'sleep 30 & echo $!; wait' & echo $!; wait".into(),
|
||||
],
|
||||
&directory.0,
|
||||
Duration::from_millis(250),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(output.timed_out);
|
||||
assert_eq!(output.stdout.lines().count(), 2);
|
||||
for descendant in output.stdout.lines() {
|
||||
let descendant: u32 = descendant.parse().unwrap();
|
||||
assert!(!Path::new(&format!("/proc/{descendant}")).exists());
|
||||
}
|
||||
assert!(unrelated.try_wait().unwrap().is_none());
|
||||
unrelated.kill().unwrap();
|
||||
unrelated.wait().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_success_reaps_descendants_before_joining_output_readers() {
|
||||
let directory = Directory::new();
|
||||
let output = capture(
|
||||
Path::new("/bin/sh"),
|
||||
&["-c".into(), "/bin/sh -c 'sleep 30 & echo $! > grandchild; wait' & echo $!; while [ ! -s grandchild ]; do :; done; /bin/cat grandchild".into()],
|
||||
&directory.0,
|
||||
Duration::from_secs(3),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert!(!output.timed_out);
|
||||
assert_eq!(output.stdout.lines().count(), 2);
|
||||
for descendant in output.stdout.lines() {
|
||||
let descendant: u32 = descendant.parse().unwrap();
|
||||
assert!(!Path::new(&format!("/proc/{descendant}")).exists());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_noisy_output_stays_bounded_without_disk_capture() {
|
||||
let directory = Directory::new();
|
||||
let output = capture(
|
||||
Path::new("/bin/sh"),
|
||||
&[
|
||||
"-c".into(),
|
||||
"echo $$; /bin/cat /dev/zero & /bin/cat /dev/zero >&2 & wait".into(),
|
||||
],
|
||||
&directory.0,
|
||||
Duration::from_secs(1),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(output.timed_out);
|
||||
let marker = "\n[output truncated after 1 MiB]\n";
|
||||
for stream in [&output.stdout, &output.stderr] {
|
||||
assert_eq!(stream.len(), 1_048_576 + marker.len());
|
||||
assert!(stream.ends_with(marker));
|
||||
}
|
||||
let descendant: u32 = output.stdout.lines().next().unwrap().parse().unwrap();
|
||||
assert!(!Path::new(&format!("/proc/{descendant}")).exists());
|
||||
assert_eq!(std::fs::read_dir(&directory.0).unwrap().count(), 0);
|
||||
// 启动失败也释放进程监管状态,同一目录可继续执行下一例。
|
||||
assert!(
|
||||
capture(
|
||||
Path::new("/missing-dever-test"),
|
||||
&[],
|
||||
&directory.0,
|
||||
Duration::from_secs(1)
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
let next = capture(
|
||||
Path::new("/bin/true"),
|
||||
&[],
|
||||
&directory.0,
|
||||
Duration::from_secs(1),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(next.status.success());
|
||||
assert!(!next.timed_out);
|
||||
assert!(next.stdout.is_empty() && next.stderr.is_empty());
|
||||
}
|
||||
Reference in new issue
Block a user