101 lines
4.0 KiB
Rust
101 lines
4.0 KiB
Rust
//! World-loaded dream built-ins and messages survive a harness reopen.
|
|
use sausage::{harness::run_module, world::World};
|
|
use std::{path::Path, process::Command};
|
|
const BUNDLE: &str = include_str!("../../js/dream-test-bundle.js");
|
|
fn git(repo: &Path, args: &[&str]) -> anyhow::Result<String> {
|
|
let output = Command::new("git")
|
|
.args(args)
|
|
.current_dir(repo)
|
|
.env("GIT_AUTHOR_NAME", "Test")
|
|
.env("GIT_AUTHOR_EMAIL", "test@example.com")
|
|
.env("GIT_COMMITTER_NAME", "Test")
|
|
.env("GIT_COMMITTER_EMAIL", "test@example.com")
|
|
.output()?;
|
|
anyhow::ensure!(
|
|
output.status.success(),
|
|
"git {args:?}: {}",
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
Ok(String::from_utf8(output.stdout)?.trim().into())
|
|
}
|
|
fn copy_tree(source: &Path, destination: &Path) -> anyhow::Result<()> {
|
|
std::fs::create_dir_all(destination)?;
|
|
for entry in std::fs::read_dir(source)? {
|
|
let entry = entry?;
|
|
let target = destination.join(entry.file_name());
|
|
if entry.file_type()?.is_dir() {
|
|
copy_tree(&entry.path(), &target)?;
|
|
} else {
|
|
std::fs::copy(entry.path(), target)?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
fn prepare(dir: &Path) -> anyhow::Result<()> {
|
|
World::open(dir)?;
|
|
let disk = dir.join("world");
|
|
let repo = disk.join("src/sausage");
|
|
let source = Path::new(env!("CARGO_MANIFEST_DIR")).join("..");
|
|
let target = crate::common::build_git();
|
|
std::fs::create_dir_all(disk.join("bin"))?;
|
|
for binary in ["git", "tar"] {
|
|
std::fs::copy(
|
|
target.join(format!("wasm32-wasip2/release/{binary}.wasm")),
|
|
disk.join(format!("bin/{binary}.wasm")),
|
|
)?;
|
|
}
|
|
copy_tree(&source.join("extensions"), &repo.join("extensions"))?;
|
|
std::fs::create_dir_all(repo.join("extensions/probe"))?;
|
|
std::fs::write(
|
|
repo.join("extensions/probe/server.ts"),
|
|
"export default host => { globalThis.dreamHost=host; globalThis.dreamService=host.need({name:'dream'}); globalThis.dreamSubagents=host.need({name:'subagents'}); globalThis.dreamAutomations=host.need({name:'automations'}); return {name:'probe'}; }",
|
|
)?;
|
|
let mut roster: Vec<serde_json::Value> = ["standing", "coordinator", "worker", "reviewer"].into_iter().map(|role| serde_json::json!({
|
|
"name":role, "description":format!("P3 {role}"), "model":"faux/faux-1",
|
|
"isolate":"none", "resident":role == "standing", "prompt":format!("P3 role:{role}"),
|
|
"denyTools":if role == "worker" || role == "reviewer" {vec!["subagent"]} else {vec![]}
|
|
})).collect();
|
|
let defaults: serde_json::Value =
|
|
serde_yaml_ng::from_str(include_str!("../../../config/config.yaml"))?;
|
|
let mut pass = defaults["roster"]
|
|
.as_array()
|
|
.unwrap()
|
|
.iter()
|
|
.find(|entry| entry["name"] == "dream-pass")
|
|
.unwrap()
|
|
.clone();
|
|
pass["model"] = serde_json::json!("faux/faux-1");
|
|
roster.push(pass);
|
|
crate::common::write_config(dir, "standing", serde_json::json!(roster))?;
|
|
let demo = disk.join("src/demo");
|
|
std::fs::create_dir_all(&demo)?;
|
|
std::fs::write(demo.join("README.md"), "P3 demo\n")?;
|
|
for repo in [&repo, &demo] {
|
|
git(repo, &["init", "-b", "main"])?;
|
|
git(repo, &["add", "."])?;
|
|
git(repo, &["commit", "--no-gpg-sign", "-m", "P3 fixture"])?;
|
|
}
|
|
Ok(())
|
|
}
|
|
async fn run(dir: &Path, mode: &str) -> anyhow::Result<()> {
|
|
let world = World::open(dir)?;
|
|
let exec = sausage::process::exec(World {
|
|
root: world.root.clone(),
|
|
host_dir: world.host_dir.clone(),
|
|
processes: world.processes.clone(),
|
|
})?;
|
|
run_module(
|
|
world,
|
|
exec,
|
|
&format!("globalThis.dreamMode={mode:?};\n{BUNDLE}"),
|
|
)
|
|
.await
|
|
}
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn builtins_fire_and_report_across_reopen() -> anyhow::Result<()> {
|
|
let dir = tempfile::tempdir()?;
|
|
prepare(dir.path())?;
|
|
run(dir.path(), "first").await?;
|
|
run(dir.path(), "reopen").await
|
|
}
|