use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::time::Duration;
const BOOT_WAIT: Duration = Duration::from_millis(2000);
fn seed_legacy_palace(registry_root: &Path) -> PathBuf {
let palace_dir = registry_root.join("localLLM");
std::fs::create_dir_all(&palace_dir).expect("create palace dir");
let palace_json = palace_dir.join("palace.json");
let body = serde_json::json!({
"id": "localLLM",
"name": "localLLM",
"description": null,
"created_at": "2025-01-01T00:00:00Z",
"data_dir": palace_dir,
});
let mut f = std::fs::File::create(&palace_json).expect("create palace.json");
f.write_all(serde_json::to_string_pretty(&body).unwrap().as_bytes())
.expect("write palace.json");
palace_json
}
fn read_palace_name(palace_json: &Path) -> String {
let raw = std::fs::read_to_string(palace_json).expect("read palace.json");
let parsed: serde_json::Value = serde_json::from_str(&raw).expect("parse palace.json");
parsed["name"].as_str().expect("name field").to_string()
}
fn locate_binary() -> PathBuf {
PathBuf::from(env!("CARGO_BIN_EXE_trusty-memory"))
}
fn boot_briefly(data_dir: &Path) {
let bin = locate_binary();
let mut child = Command::new(&bin)
.arg("serve")
.arg("--foreground")
.arg("--http")
.arg("127.0.0.1:0")
.env("TRUSTY_DATA_DIR_OVERRIDE", data_dir)
.env("RUST_LOG", "warn")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("spawn trusty-memory binary");
std::thread::sleep(BOOT_WAIT);
let _ = child.kill();
let _ = child.wait();
}
#[test]
fn boot_migrates_default_palace_name_and_is_idempotent() {
let tmp = tempfile::tempdir().expect("tempdir");
let override_base = tmp.path();
let data_dir = override_base.join("trusty-memory");
std::fs::create_dir_all(&data_dir).expect("create data dir");
let palace_json = seed_legacy_palace(&data_dir);
assert_eq!(read_palace_name(&palace_json), "localLLM", "seed legacy");
boot_briefly(override_base);
assert_eq!(
read_palace_name(&palace_json),
"User Memories",
"first boot must migrate the display name"
);
let before = std::fs::read_to_string(&palace_json).expect("read palace.json #2");
boot_briefly(override_base);
let after = std::fs::read_to_string(&palace_json).expect("read palace.json #3");
assert_eq!(read_palace_name(&palace_json), "User Memories");
assert_eq!(
before, after,
"idempotent: re-running boot must not change palace.json"
);
}