feat: release Dever 0.1.5 with direct workers and long transactions

This commit is contained in:
Codex committed 2026-10-11 11:17:33 +00:00
1 parent 89629c2197
commit a900d7e8db
153 files changed
+3676 -3708

No files matched your search

+34 -36
View File
@@ -9,8 +9,8 @@ use dever_runtime::wire::Encoder;
use serde_json::json;
use sha2::{Digest, Sha256};
#[path = "support/sandbox.rs"]
mod sandbox;
#[path = "support/process_runtime.rs"]
mod process_runtime;
#[path = "support/temp.rs"]
mod temp;
@@ -35,7 +35,6 @@ impl Fixture {
fs::create_dir(directory.path().join("markers")).unwrap();
fs::create_dir(directory.path().join("config")).unwrap();
let settings = json!({"adapter": {PORT: {
"files": {"markers": {"path":"markers", "write":true}},
"command": {"timeout_ms":timeout_ms, "output_limit":output_limit}
}}});
fs::write(
@@ -44,13 +43,13 @@ impl Fixture {
)
.unwrap();
let workspace = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let mut assets = sandbox::assets(&workspace);
assets.push(sandbox::Asset {
let mut assets = process_runtime::assets(&workspace);
assets.push(process_runtime::Asset {
path: "commands/fixture/tool".into(),
bytes: program,
executable: true,
});
assets.push(sandbox::Asset {
assets.push(process_runtime::Asset {
path: "tool.dever-command.json".into(),
bytes: json!({"format":"dever-command-launch-v1", "ecosystem":"command", "entry":"tool",
"executable":"commands/fixture/tool", "arguments":[], "working_directory":"commands/fixture"})
@@ -104,6 +103,12 @@ struct Output {
stderr: Vec<u8>,
}
async fn tree(directory: std::path::PathBuf) -> Result<(), String> {
invoke(&["tree", directory.to_str().unwrap()], None)
.await
.map(|_| ())
}
async fn invoke(args: &[&str], stdin: Option<&[u8]>) -> Result<Output, String> {
let mut writer = Encoder::default();
writer.begin_object()?;
@@ -255,18 +260,12 @@ async fn heartbeat(fixture: &Fixture) -> Result<(), String> {
}
#[test]
fn guard_exec_failure_is_a_fault_not_a_program_exit_code() {
fn invalid_executable_is_rejected_before_a_program_exit_code_exists() {
let fixture = Fixture::with_program(5000, 1024 * 1024, b"not an ELF executable\n".to_vec());
dever_runtime::task::run_entry(async {
fixture.start().await?;
let error = invoke(&[], None)
.await
.err()
.ok_or("exec failure was returned as an exit code")?;
assert!(
error.contains("startup failed") && error.contains("cannot execute"),
"{error}"
);
let error = fixture.start().await.unwrap_err();
assert!(error.contains("invalid executable ELF"), "{error}");
assert!(!fixture.marker("starts").exists());
component::shutdown().await
})
.unwrap();
@@ -294,15 +293,26 @@ async fn assert_reaped(fixture: &Fixture) {
);
}
#[test]
fn successful_root_exit_stops_descendants_holding_output_pipes() {
let fixture = Fixture::new(5000, 1024 * 1024);
dever_runtime::task::run_entry(async {
fixture.start().await?;
let directory = fixture.marker("");
let output = invoke(&["tree-exit", directory.to_str().unwrap()], None).await?;
assert_eq!(output.code, 0);
assert_reaped(&fixture).await;
component::shutdown().await
})
.unwrap();
}
#[test]
fn timeout_reaps_descendants_and_keeps_the_adapter_available() {
let fixture = Fixture::new(800, 1024 * 1024);
dever_runtime::task::run_entry(async {
fixture.start().await?;
let call = dever_runtime::task::run(async {
invoke(&["tree", "/data/markers"], None).await.map(|_| ())
})
.await?;
let call = dever_runtime::task::run(tree(fixture.marker(""))).await?;
heartbeat(&fixture).await?;
let error = dever_runtime::task::wait(call)
.await
@@ -321,10 +331,7 @@ fn cancellation_and_root_close_reap_descendants_without_replay() {
let fixture = Fixture::new(5000, 1024 * 1024);
dever_runtime::task::run_entry(async {
fixture.start().await?;
let call = dever_runtime::task::run(async {
invoke(&["tree", "/data/markers"], None).await.map(|_| ())
})
.await?;
let call = dever_runtime::task::run(tree(fixture.marker(""))).await?;
heartbeat(&fixture).await?;
if root_close {
// Return while the call is active: the invocation closes its
@@ -361,10 +368,7 @@ fn queued_cancellation_does_not_wait_for_an_unrelated_running_command() {
let fixture = Fixture::new(5000, 1024 * 1024);
dever_runtime::task::run_entry(async {
fixture.start().await?;
let active = dever_runtime::task::run(async {
invoke(&["tree", "/data/markers"], None).await.map(|_| ())
})
.await?;
let active = dever_runtime::task::run(tree(fixture.marker(""))).await?;
heartbeat(&fixture).await?;
let (entered, admitted) = tokio::sync::oneshot::channel();
let queued = dever_runtime::task::run(async move {
@@ -395,10 +399,7 @@ fn task_deadline_waits_for_command_process_cleanup() {
let fixture = Fixture::new(5000, 1024 * 1024);
dever_runtime::task::run_entry(async {
fixture.start().await?;
let call = dever_runtime::task::run(async {
invoke(&["tree", "/data/markers"], None).await.map(|_| ())
})
.await?;
let call = dever_runtime::task::run(tree(fixture.marker(""))).await?;
heartbeat(&fixture).await?;
assert_eq!(dever_runtime::task::wait_timeout(call, 10).await?, None);
assert_reaped(&fixture).await;
@@ -412,10 +413,7 @@ fn explicit_shutdown_drains_active_and_queued_commands() {
let fixture = Fixture::new(5000, 1024 * 1024);
dever_runtime::task::run_entry(async {
fixture.start().await?;
let active = dever_runtime::task::run(async {
invoke(&["tree", "/data/markers"], None).await.map(|_| ())
})
.await?;
let active = dever_runtime::task::run(tree(fixture.marker(""))).await?;
heartbeat(&fixture).await?;
let queued =
dever_runtime::task::run(async { invoke(&["echo", "queued"], None).await.map(|_| ()) })