Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,98 @@
|
||||
//! 共享执行器回归使用 Pod 内的真实子进程,不依赖线上服务。
|
||||
|
||||
use super::super::super::Directory;
|
||||
use dever::compiler::project::dependency::library::build::process;
|
||||
use std::{fs, path::Path, process::Command};
|
||||
|
||||
fn child_gone(path: &Path) {
|
||||
let pid = fs::read_to_string(path).unwrap();
|
||||
assert!(
|
||||
!Path::new("/proc").join(pid.trim()).exists(),
|
||||
"child {pid} was not reaped"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lib_build_output_overflow_drains_pipes_and_reaps_its_group() {
|
||||
let directory = Directory::new();
|
||||
let mut command = Command::new("/bin/sh");
|
||||
command.current_dir(&directory.0).args(["-c", "echo $$ > parent; /bin/sleep 300 & echo $! > child; /usr/bin/head -c 33554432 /dev/zero; wait"]);
|
||||
let error = process::run(command, &directory.0).unwrap_err();
|
||||
assert!(error.contains("16 MiB"), "{error}");
|
||||
child_gone(&directory.0.join("parent"));
|
||||
child_gone(&directory.0.join("child"));
|
||||
assert!(
|
||||
fs::read_dir(&directory.0)
|
||||
.unwrap()
|
||||
.all(|entry| entry.unwrap().metadata().unwrap().len() < 32)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lib_build_success_reaps_descendants_holding_output_open() {
|
||||
let directory = Directory::new();
|
||||
let mut command = Command::new("/bin/sh");
|
||||
command
|
||||
.current_dir(&directory.0)
|
||||
.args(["-c", "/bin/sleep 300 & echo $! > child; exit 0"]);
|
||||
assert!(process::run(command, &directory.0).unwrap().success());
|
||||
child_gone(&directory.0.join("child"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lib_build_scratch_budget_kills_and_reaps_before_returning() {
|
||||
let directory = Directory::new();
|
||||
let mut command = Command::new("/bin/sh");
|
||||
command.current_dir(&directory.0).args(["-c", "echo $$ > parent; /bin/sleep 300 & echo $! > child; /usr/bin/truncate -s 536870913 excess; wait"]);
|
||||
let error = process::run(command, &directory.0).unwrap_err();
|
||||
assert!(error.contains("512 MiB"), "{error}");
|
||||
child_gone(&directory.0.join("parent"));
|
||||
child_gone(&directory.0.join("child"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lib_build_probe_distinguishes_unloadable_exit_and_signal_from_budget_errors() {
|
||||
let directory = Directory::new();
|
||||
for script in ["exit 10", "ulimit -c 0; kill -SEGV $$"] {
|
||||
let mut command = Command::new("/bin/sh");
|
||||
command.args(["-c", script]);
|
||||
let status = process::status(command, &directory.0).unwrap();
|
||||
assert!(!status.success());
|
||||
}
|
||||
let mut command = Command::new("/bin/sh");
|
||||
command.args(["-c", "exit 10"]);
|
||||
assert!(
|
||||
process::run(command, &directory.0)
|
||||
.unwrap_err()
|
||||
.contains("Lib build failed")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lib_build_script_header_cannot_select_host_tools_or_inject_arguments() {
|
||||
let fixture = super::Fixture::new();
|
||||
for header in [
|
||||
"#!/bin/bash",
|
||||
"#!/usr/bin/env node --eval unsafe",
|
||||
"#!/tmp/untrusted",
|
||||
] {
|
||||
let mut stage = dever::compiler::project::dependency::library::build::stage::Stage::new(
|
||||
&fixture.signed,
|
||||
)
|
||||
.unwrap();
|
||||
stage
|
||||
.write(
|
||||
"input/rootfs/usr/bin/script",
|
||||
format!("{header}\nexit 0\n").into_bytes(),
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
let tools = ["rootfs/usr/bin/script".to_owned()].into_iter().collect();
|
||||
assert!(
|
||||
stage
|
||||
.prepare_tools(&tools)
|
||||
.unwrap_err()
|
||||
.contains("signed interpreter")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user