This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
maestro/crates/maestro-daemon/tests/sidecar.rs
T
Miguel Palhas d006f4a7bd refactor(maestro): drop registry, p2p, and auth from daemon core
Maestro is now single-host: one daemon owns the machine's sessions and
clients talk to it directly. Removes the registry crate, the daemon's
registry client/broker/catalog mirror, JWT attach auth, cookie auth, and
the perimeter (T2) transport config.

The daemon API is now unauthenticated on its bind address, same trust
model as tmux. Session and CreateSessionRequest lose daemon_id;
RegistryEvent becomes CatalogEvent with no daemon variants; attach moves
to WS /api/attach/:id with no token.
2026-08-22 10:00:24 +01:00

111 lines
3.1 KiB
Rust

//! Round-trip and recovery tests for the on-disk sidecar session store.
mod common;
use std::collections::HashMap;
use std::path::PathBuf;
use chrono::{DateTime, Utc};
use maestro_daemon::sidecar::SidecarStore;
use maestro_protocol::{Session, SessionStatus};
use serde_json::Value;
use tempfile::TempDir;
use uuid::Uuid;
fn sample(id: Uuid) -> Session {
Session {
id,
cwd: PathBuf::from("/tmp/work"),
command: "bash".into(),
env: HashMap::from([("FOO".into(), "bar".into())]),
metadata: HashMap::from([("name".into(), Value::String("maestro-impl".into()))]),
status: SessionStatus::Running,
created_at: DateTime::parse_from_rfc3339("2026-05-24T12:00:00Z")
.unwrap()
.with_timezone(&Utc),
foreground: None,
activity: Default::default(),
last_activity_at: chrono::Utc::now(),
current_cwd: Some(PathBuf::from("/tmp/work/crates")),
}
}
#[test]
fn write_then_read_round_trip() {
let dir = TempDir::new().unwrap();
let store = SidecarStore::new(dir.path());
let id = Uuid::new_v4();
let s = sample(id);
store.write(&s).expect("write");
let loaded = store.read(id).expect("read");
assert_eq!(loaded.as_ref(), Some(&s));
let path = store.path_for(id);
assert!(path.exists());
assert!(path.ends_with(format!("{id}.json")));
}
#[test]
fn read_missing_returns_none() {
let dir = TempDir::new().unwrap();
let store = SidecarStore::new(dir.path());
assert!(store.read(Uuid::new_v4()).unwrap().is_none());
}
#[test]
fn delete_removes_file_and_is_idempotent() {
let dir = TempDir::new().unwrap();
let store = SidecarStore::new(dir.path());
let id = Uuid::new_v4();
let s = sample(id);
store.write(&s).unwrap();
assert!(store.path_for(id).exists());
store.delete(id).unwrap();
assert!(!store.path_for(id).exists());
// second delete is a no-op
store.delete(id).unwrap();
}
#[test]
fn load_all_recovers_every_sidecar_and_skips_garbage() {
let dir = TempDir::new().unwrap();
let store = SidecarStore::new(dir.path());
let s1 = sample(Uuid::new_v4());
let s2 = sample(Uuid::new_v4());
store.write(&s1).unwrap();
store.write(&s2).unwrap();
// garbage files in the directory should be ignored
std::fs::write(dir.path().join("not-json.txt"), b"hello").unwrap();
std::fs::write(dir.path().join("broken.json"), b"{not json}").unwrap();
let mut loaded = store.load_all().expect("load_all");
loaded.sort_by_key(|s| s.id);
let mut expected = vec![s1, s2];
expected.sort_by_key(|s| s.id);
assert_eq!(loaded, expected);
}
#[test]
fn load_all_returns_empty_when_directory_missing() {
let dir = TempDir::new().unwrap();
let store = SidecarStore::new(dir.path().join("does-not-exist"));
assert!(store.load_all().unwrap().is_empty());
}
#[test]
fn write_creates_parent_directory() {
let dir = TempDir::new().unwrap();
let nested = dir.path().join("a/b/c");
let store = SidecarStore::new(&nested);
let s = sample(Uuid::new_v4());
store.write(&s).expect("write");
assert!(nested.exists());
assert!(store.path_for(s.id).exists());
}