Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+228
View File
@@ -0,0 +1,228 @@
//! 真实命令的字节管道、非零退出、超时和输出预算;所有写入都在当前测试目录。
use super::{Asset, Bundle, Directory, Limits, Runtime};
use dever_runtime::worker::command::{self, Limits as CommandLimits};
use sha2::{Digest, Sha256};
use std::{fs, path::PathBuf, process::Command, time::Duration};
#[test]
fn command_runs_owned_native_fixture_without_shell_and_drains_on_failure() {
let _execution = super::EXECUTOR.lock().unwrap();
let directory = Directory::new();
let fixture = directory.0.join("fixture");
let source = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../../test/rust/runtime/worker/fixture.rs");
let result = Command::new("rustup")
.args(["run", "1.95.0", "rustc", "--edition=2024", "-O"])
.arg(source)
.arg("-o")
.arg(&fixture)
.output()
.unwrap();
assert!(
result.status.success(),
"{}",
String::from_utf8_lossy(&result.stderr)
);
let runner = directory.0.join("runner");
fs::copy(std::env::current_exe().unwrap(), &runner).unwrap();
let result = Command::new(runner)
.args(["--exact", "command::owned_command_case", "--nocapture"])
.env_clear()
.env("DEVER_COMMAND_FIXTURE", fixture)
.output()
.unwrap();
assert!(
result.status.success(),
"{}\n{}",
String::from_utf8_lossy(&result.stdout),
String::from_utf8_lossy(&result.stderr)
);
}
#[test]
fn owned_command_case() {
let Some(fixture) = std::env::var_os("DEVER_COMMAND_FIXTURE") else {
return;
};
let bytes = fs::read(&fixture).unwrap();
fs::remove_file(fixture).unwrap();
let entry = "module/demo/tool/command";
let launch = serde_json::to_vec(&serde_json::json!({"format":"dever-command-launch-v1","ecosystem":"command","entry":entry,"executable":entry,"arguments":[],"working_directory":"module/demo/tool"})).unwrap();
let files = [
(entry, bytes, true),
("module/demo/tool/command.dever-command.json", launch, false),
]
.map(|(path, bytes, executable)| Asset {
path,
sha256: Box::leak(format!("{:x}", Sha256::digest(&bytes)).into_boxed_str()),
bytes: Box::leak(bytes.into_boxed_slice()),
executable,
});
let bundle: &'static Bundle = Box::leak(Box::new(Bundle {
files: Box::leak(Box::new(files)),
}));
let root = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.to_owned();
let runtime = Runtime::new(Limits {
threads: 2,
workers: 1,
tasks: 32,
})
.unwrap();
runtime
.run(async |scope| {
let arguments = ["--echo", "a b", "$(touch never)", "\"quoted\""].map(str::to_owned);
let output = command::run(
scope,
bundle,
entry,
&arguments,
Some(&[0, 255, 1]),
CommandLimits::default(),
)
.await
.unwrap();
assert_eq!(output.code, 7);
assert_eq!(output.stdout, [0, 255, 1]);
assert_eq!(output.stderr, b"a b\n$(touch never)\n\"quoted\"");
let empty = command::run(
scope,
bundle,
entry,
&["--echo".into()],
None,
CommandLimits::default(),
)
.await
.unwrap();
assert!(empty.stdout.is_empty());
let error = command::run(
scope,
bundle,
entry,
&["--flood".into()],
None,
CommandLimits {
timeout_ms: 1000,
output_limit: 100,
},
)
.await
.err()
.unwrap();
assert!(error.contains("limit"));
let marker = root.join("timed-pid");
let error = command::run(
scope,
bundle,
entry,
&["--hang".into(), marker.to_str().unwrap().into()],
None,
CommandLimits {
timeout_ms: 100,
output_limit: 100,
},
)
.await
.err()
.unwrap();
assert!(error.contains("timed out"));
let pid = fs::read_to_string(marker).unwrap();
assert!(!PathBuf::from(format!("/proc/{pid}")).exists());
let marker = root.join("cancelled-pid");
let arguments = ["--hang".into(), marker.to_str().unwrap().into()];
let running = command::run(
scope,
bundle,
entry,
&arguments,
None,
CommandLimits::default(),
);
tokio::pin!(running);
tokio::select! {
_ = &mut running => panic!("hanging command completed before cancellation"),
ready = tokio::time::timeout(Duration::from_secs(3), async {
while !marker.is_file() { tokio::time::sleep(Duration::from_millis(5)).await; }
}) => ready.unwrap(),
}
})
.unwrap();
let pid = fs::read_to_string(root.join("cancelled-pid")).unwrap();
assert!(!PathBuf::from(format!("/proc/{pid}")).exists());
runtime
.run(async |scope| {
let (started, ready) = tokio::sync::oneshot::channel();
let (release, receive) = std::sync::mpsc::channel();
let blocker = scope
.spawn_sync(move || {
started.send(()).unwrap();
receive.recv().unwrap();
})
.unwrap();
ready.await.unwrap();
let queued = scope
.spawn(move |child| async move {
command::run(
&child,
bundle,
entry,
&["--echo".into()],
None,
CommandLimits::default(),
)
.await
})
.unwrap();
let stopped =
tokio::time::timeout(Duration::from_millis(300), queued.timeout(30)).await;
release.send(()).unwrap();
blocker.wait().await.unwrap();
assert!(matches!(
stopped,
Ok(Ok(dever_runtime::task::Timed::Expired(None)))
));
worker_finish(scope).await;
})
.unwrap();
runtime
.run(async |scope| {
let marker = root.join("child-cancelled-pid");
let arguments = vec!["--hang".into(), marker.to_str().unwrap().into()];
let child = scope
.spawn(move |child| async move {
command::run(
&child,
bundle,
entry,
&arguments,
None,
CommandLimits::default(),
)
.await
})
.unwrap();
tokio::time::timeout(Duration::from_secs(3), async {
while !marker.is_file() {
tokio::time::sleep(Duration::from_millis(5)).await;
}
})
.await
.unwrap();
child.stop().await.unwrap();
let pid = fs::read_to_string(marker).unwrap();
assert!(!PathBuf::from(format!("/proc/{pid}")).exists());
worker_finish(scope).await;
})
.unwrap();
}
async fn worker_finish(scope: &dever_runtime::task::Scope<'_>) {
dever_runtime::worker::finish(scope, Ok(())).await.unwrap();
}