feat: release Dever 0.1.5 with direct workers and long transactions
This commit is contained in:
1 parent
89629c2197
commit
a900d7e8db
153 files changed
+3676
-3708
No files matched your search
@@ -4,8 +4,8 @@
|
||||
reason = "This test crate uses only the shared static ELF fixture"
|
||||
)]
|
||||
mod native_elf;
|
||||
#[path = "../dever-tests/tests/support/sandbox.rs"]
|
||||
mod sandbox;
|
||||
#[path = "../dever-tests/tests/support/process_runtime.rs"]
|
||||
mod process_runtime;
|
||||
#[path = "../dever-tests/tests/support/temp.rs"]
|
||||
mod temp;
|
||||
#[path = "support/wheel.rs"]
|
||||
@@ -32,6 +32,80 @@ use temp::TemporaryDirectory;
|
||||
#[path = "external_workers/command.rs"]
|
||||
mod command;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[path = "external_workers/ffi.rs"]
|
||||
mod ffi;
|
||||
|
||||
#[test]
|
||||
fn native_ffi_workers_package_the_checked_contract_and_recursive_libraries() {
|
||||
let root = TemporaryDirectory::new();
|
||||
let mut sources = SourceMap::default();
|
||||
sources.add(
|
||||
"media/native/port.dever",
|
||||
"triple(value: Int) (output: Int) fails app.NativeError",
|
||||
);
|
||||
sources.add(
|
||||
"media/native/adapter.dever",
|
||||
"external exec \"bin/worker\" {}",
|
||||
);
|
||||
sources.add(
|
||||
"media/native/app.dever",
|
||||
"type NativeError { error Unavailable }\ntriple(value: Int) (output: Int) { output = port.triple(value) }",
|
||||
);
|
||||
sources.add("media/native/api.dever", "cmd triple = app.triple");
|
||||
let program = dever_core::check(&sources).unwrap_or_else(|errors| panic!("{errors:?}"));
|
||||
let contract = &program.external_worker_contracts()[0];
|
||||
let mut entry = resource(
|
||||
contract.entry.clone(),
|
||||
native_elf::compiler(&["libfixture.so"]),
|
||||
);
|
||||
entry.executable = true;
|
||||
assert!(
|
||||
workers::prepare(root.path(), &program, &[entry.clone()])
|
||||
.unwrap_err()
|
||||
.contains("libfixture.so")
|
||||
);
|
||||
let directory = root
|
||||
.path()
|
||||
.join(&contract.entry)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("lib");
|
||||
fs::create_dir_all(&directory).unwrap();
|
||||
fs::write(
|
||||
directory.join("libfixture.so"),
|
||||
native_elf::library("libfixture.so", &[]),
|
||||
)
|
||||
.unwrap();
|
||||
let mut loader = resource(
|
||||
format!("process-runtime/lib/{}", dever_process::loader_name()),
|
||||
native_elf::static_executable(),
|
||||
);
|
||||
loader.executable = true;
|
||||
let resources = workers::prepare(root.path(), &program, &[entry, loader]).unwrap();
|
||||
let manifest = resources
|
||||
.iter()
|
||||
.find(|file| file.path.ends_with("/contract.json"))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
serde_json::from_slice::<serde_json::Value>(&manifest.bytes).unwrap(),
|
||||
contract.sdk_manifest()
|
||||
);
|
||||
assert!(
|
||||
resources
|
||||
.iter()
|
||||
.any(|file| file.path.ends_with("/lib/libfixture.so") && !file.executable)
|
||||
);
|
||||
let launch = resources
|
||||
.iter()
|
||||
.find(|file| file.path.ends_with(".dever-worker.json"))
|
||||
.unwrap();
|
||||
let launch: serde_json::Value = serde_json::from_slice(&launch.bytes).unwrap();
|
||||
assert_eq!(launch["ecosystem"], "exec");
|
||||
assert!(launch["executable"].as_str().unwrap().ends_with("/worker"));
|
||||
assert_eq!(launch["arguments"], json!([]));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
struct OwnedProcessGroup(std::process::Child);
|
||||
|
||||
@@ -93,13 +167,13 @@ fn resource(path: String, bytes: Vec<u8>) -> EmbeddedResource {
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_sandboxed_worker(
|
||||
fn prepare_managed_worker(
|
||||
root: &Path,
|
||||
program: &dever_core::hir::Program,
|
||||
mut resources: Vec<EmbeddedResource>,
|
||||
) -> Vec<EmbeddedResource> {
|
||||
let workspace = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
|
||||
for asset in sandbox::assets(&workspace) {
|
||||
for asset in process_runtime::assets(&workspace) {
|
||||
let mut file = resource(asset.path, asset.bytes);
|
||||
file.executable = asset.executable;
|
||||
resources.push(file);
|
||||
@@ -108,7 +182,7 @@ fn prepare_sandboxed_worker(
|
||||
generated.extend(
|
||||
resources
|
||||
.into_iter()
|
||||
.filter(|resource| resource.path.starts_with("sandbox/")),
|
||||
.filter(|resource| resource.path.starts_with("process-runtime/")),
|
||||
);
|
||||
generated
|
||||
}
|
||||
@@ -450,7 +524,7 @@ fn cross_target_runtime_rejects_host_binary_even_with_matching_pack_hash() {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
#[ignore = "requires explicit Go runtime pack, official UUID proof/archive and sandbox assets"]
|
||||
#[ignore = "requires explicit Go runtime pack, official UUID proof/archive and process_runtime assets"]
|
||||
fn compiles_go_worker_with_locked_tools_and_runs_without_source_or_go() {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
@@ -521,7 +595,7 @@ func Send(_ context.Context, payload any, _ any) (any, error) {
|
||||
assert_eq!(sha(&bytes), artifact.sha256);
|
||||
resources.push(resource(artifact.path.clone(), bytes));
|
||||
}
|
||||
for asset in sandbox::assets(&workspace) {
|
||||
for asset in process_runtime::assets(&workspace) {
|
||||
let mut file = resource(asset.path, asset.bytes);
|
||||
file.executable = asset.executable;
|
||||
resources.push(file);
|
||||
@@ -567,7 +641,7 @@ func Send(_ context.Context, payload any, _ any) (any, error) {
|
||||
for file in generated.iter().chain(
|
||||
resources
|
||||
.iter()
|
||||
.filter(|file| file.path.starts_with("sandbox/")),
|
||||
.filter(|file| file.path.starts_with("process-runtime/")),
|
||||
) {
|
||||
let path = temp.path().join(&file.path);
|
||||
fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
@@ -577,14 +651,12 @@ func Send(_ context.Context, payload any, _ any) (any, error) {
|
||||
}
|
||||
}
|
||||
fs::remove_dir_all(entry.parent().unwrap()).unwrap();
|
||||
let child = dever_sandbox::Launch {
|
||||
assets: &temp.path().join("sandbox"),
|
||||
let child = dever_process::Launch {
|
||||
assets: &temp.path().join("process-runtime"),
|
||||
worker: &working_directory,
|
||||
executable: &temp.path().join(&binary.path),
|
||||
arguments: &[],
|
||||
working_directory: &working_directory,
|
||||
capabilities: dever_sandbox::Capabilities::default(),
|
||||
grants: &[],
|
||||
}
|
||||
.command()
|
||||
.unwrap()
|
||||
@@ -729,13 +801,13 @@ fn installs_purelib_and_platlib_python_wheels() {
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicit official native-wheel and complete Python runtime fixture at target/python-managed"]
|
||||
fn runs_official_native_python_wheel_in_sandbox() {
|
||||
fn runs_official_native_python_wheel_as_managed_worker() {
|
||||
run_native_python_fixture("python-managed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires explicitly prepared official PEP517 source build at target/source-build"]
|
||||
fn runs_official_python_source_build_in_sandbox() {
|
||||
fn runs_official_python_source_build_as_managed_worker() {
|
||||
run_native_python_fixture("source-build");
|
||||
}
|
||||
|
||||
@@ -820,7 +892,7 @@ fn run_native_python_fixture(fixture: &str) {
|
||||
.collect(),
|
||||
});
|
||||
lock.write_atomic(temp.path()).unwrap();
|
||||
let generated = prepare_sandboxed_worker(temp.path(), &program, resources);
|
||||
let generated = prepare_managed_worker(temp.path(), &program, resources);
|
||||
assert!(
|
||||
generated
|
||||
.iter()
|
||||
@@ -828,14 +900,12 @@ fn run_native_python_fixture(fixture: &str) {
|
||||
&& resource.bytes.starts_with(b"\x7fELF"))
|
||||
);
|
||||
let (deployment, launch) = run_packaged_protocol(&temp, &contract, "pip", &generated);
|
||||
let output = dever_sandbox::Launch {
|
||||
assets: &deployment.join("sandbox"),
|
||||
let output = dever_process::Launch {
|
||||
assets: &deployment.join("process-runtime"),
|
||||
worker: &launch.working_directory,
|
||||
executable: &launch.working_directory.join("runtime/bin/prefix-probe"),
|
||||
arguments: &[],
|
||||
working_directory: &launch.working_directory,
|
||||
capabilities: dever_sandbox::Capabilities::default(),
|
||||
grants: &[],
|
||||
}
|
||||
.command()
|
||||
.unwrap()
|
||||
@@ -877,14 +947,12 @@ fn run_packaged_protocol(
|
||||
ecosystem,
|
||||
)
|
||||
.unwrap();
|
||||
let child = dever_sandbox::Launch {
|
||||
assets: &deployment.join("sandbox"),
|
||||
let child = dever_process::Launch {
|
||||
assets: &deployment.join("process-runtime"),
|
||||
worker: &launch.working_directory,
|
||||
executable: &launch.executable,
|
||||
arguments: &launch.arguments,
|
||||
working_directory: &launch.working_directory,
|
||||
capabilities: dever_sandbox::Capabilities::default(),
|
||||
grants: &[],
|
||||
}
|
||||
.command()
|
||||
.unwrap()
|
||||
@@ -1015,16 +1083,23 @@ fn rejects_python_runtime_without_isolation_flags() {
|
||||
);
|
||||
}
|
||||
|
||||
fn fixture_runtime(name: &str) -> String {
|
||||
let path =
|
||||
std::env::var(name).unwrap_or_else(|_| panic!("set {name} to an absolute runtime path"));
|
||||
assert!(Path::new(&path).is_absolute());
|
||||
path
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicit host Node fixture path"]
|
||||
fn runs_javascript_runner_from_explicit_fixture_runtime_path() {
|
||||
run_fixture_runtime("npm", "/root/.nvm/versions/node/v24.15.0/bin/node");
|
||||
run_fixture_runtime("npm", &fixture_runtime("DEVER_TEST_NODE"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicit host Python fixture path"]
|
||||
fn runs_python_runner_from_explicit_fixture_runtime_path() {
|
||||
run_fixture_runtime("pip", "/usr/bin/python3.12");
|
||||
run_fixture_runtime("pip", &fixture_runtime("DEVER_TEST_PYTHON"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1042,7 +1117,7 @@ fn binds_commonjs_exports_without_a_registration_table() {
|
||||
&temp,
|
||||
&program,
|
||||
&resources,
|
||||
Some("/root/.nvm/versions/node/v24.15.0/bin/node"),
|
||||
Some(&fixture_runtime("DEVER_TEST_NODE")),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1055,7 +1130,7 @@ fn binds_esm_exports_without_a_registration_table() {
|
||||
&temp,
|
||||
&program,
|
||||
&resources,
|
||||
Some("/root/.nvm/versions/node/v24.15.0/bin/node"),
|
||||
Some(&fixture_runtime("DEVER_TEST_NODE")),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1070,7 +1145,12 @@ fn imports_packaged_sdk_before_adapter_modules() {
|
||||
"raise RuntimeError('shadowed SDK')\n",
|
||||
)
|
||||
.unwrap();
|
||||
execute_generated_fixture(&temp, &program, &resources, Some("/usr/bin/python3.12"));
|
||||
execute_generated_fixture(
|
||||
&temp,
|
||||
&program,
|
||||
&resources,
|
||||
Some(&fixture_runtime("DEVER_TEST_PYTHON")),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -1080,18 +1160,31 @@ fn compiled_managed_worker_runs_after_source_and_pack_are_removed() {
|
||||
use std::os::unix::process::CommandExt;
|
||||
|
||||
let temp = TemporaryDirectory::new();
|
||||
let binary = fs::read("/root/.nvm/versions/node/v24.15.0/bin/node").unwrap();
|
||||
let binary = fs::read(&fixture_runtime("DEVER_TEST_NODE")).unwrap();
|
||||
let (program, resources, sources) =
|
||||
fixture_entry_with_sources(temp.path(), "npm", &binary, None, "worker/main.mjs");
|
||||
let source_entry = program.external_worker_contracts()[0].entry.clone();
|
||||
fs::write(
|
||||
temp.path().join(&source_entry),
|
||||
r#"
|
||||
import { execFileSync } from 'node:child_process';
|
||||
export const send = ({ value }) => {
|
||||
const receipt = Number(execFileSync(process.execPath,
|
||||
['-e', 'process.stdout.write(String(Number(process.argv[1]) + 1))', String(value)],
|
||||
{ encoding: 'utf8', timeout: 3000, maxBuffer: 1024 }));
|
||||
return { receipt };
|
||||
};
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
let raw_pack_path = temp.path().join("runtime.pack");
|
||||
fs::write(&raw_pack_path, &resources[0].bytes).unwrap();
|
||||
let raw = resource(resources[0].path.clone(), fs::read(&raw_pack_path).unwrap());
|
||||
let packaged = prepare_sandboxed_worker(temp.path(), &program, vec![raw]);
|
||||
let packaged = prepare_managed_worker(temp.path(), &program, vec![raw]);
|
||||
let native = dever_core::native::compile_project_with_resources(
|
||||
&program,
|
||||
&sources,
|
||||
std::ffi::OsStr::new("/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc"),
|
||||
std::ffi::OsStr::new("rustc"),
|
||||
dever_runtime::config::RuntimeProfile::default(),
|
||||
&packaged,
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user