#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::panic_in_result_fn,
clippy::indexing_slicing
)]
use choreo_daemon::daemon::OpenOptions;
use choreo_daemon::{DaemonState, EmbeddedOptions, ToolPolicy, spawn_embedded};
use choreo_proto::{ClientMessage, DaemonMessage, SessionEvent};
fn open_state(dir: &tempfile::TempDir) -> DaemonState {
DaemonState::open(OpenOptions {
db_path: dir.path().join("state.redb"),
accounts_path: dir.path().join("accounts.toml"),
catalog_paths: choreo_daemon::catalog::CatalogPaths {
bin: dir.path().join("catalog.bin"),
overlay: dir.path().join("models-overlay.toml"),
},
tool_policy: ToolPolicy::Full,
max_turns: 0,
platform_tool_bridge: None,
})
.unwrap()
}
fn create_session(link: &choreo_daemon::EmbeddedLink) -> u64 {
link.client_tx
.send(ClientMessage::CreateSession {
title: Some("embedded test".to_string()),
parent_session_id: None,
working_dir: None,
context_config: None,
account_name: None,
selected_model: None,
reasoning_effort: None,
})
.unwrap();
loop {
match link.daemon_rx.recv().unwrap() {
DaemonMessage::Session {
session_id: Some(sid),
event: SessionEvent::SessionCreated { .. },
} => return sid,
_ => continue,
}
}
}
#[test]
#[ignore]
fn embedded_transport_round_trips_values() {
let dir = tempfile::tempdir().unwrap();
let daemon = spawn_embedded(open_state(&dir), EmbeddedOptions::default()).unwrap();
let link = daemon.connect().unwrap();
let sid = create_session(&link);
assert!(sid > 0);
link.client_tx.send(ClientMessage::ListSessions).unwrap();
let saw_list = loop {
match link.daemon_rx.recv().unwrap() {
DaemonMessage::Sessions { sessions } => break sessions,
_ => continue,
}
};
assert!(
saw_list.iter().any(|s| s.session_id == sid),
"ListSessions must return the session created over this link"
);
link.client_tx
.send(ClientMessage::AttachSession { session_id: sid })
.unwrap();
loop {
match link.daemon_rx.recv().unwrap() {
DaemonMessage::Session {
session_id: Some(id),
event: SessionEvent::SessionAttached,
} => {
assert_eq!(id, sid);
break;
}
_ => continue,
}
}
drop(link);
let link2 = daemon.connect().unwrap();
link2.client_tx.send(ClientMessage::Ping).unwrap();
assert!(matches!(
link2.daemon_rx.recv().unwrap(),
DaemonMessage::Pong
));
daemon.shutdown();
}
#[test]
#[ignore]
fn shutdown_delivers_shutting_down_before_channel_close() {
let dir = tempfile::tempdir().unwrap();
let daemon = spawn_embedded(open_state(&dir), EmbeddedOptions::default()).unwrap();
let link = daemon.connect().unwrap();
link.client_tx.send(ClientMessage::Ping).unwrap();
assert!(matches!(
link.daemon_rx.recv().unwrap(),
DaemonMessage::Pong
));
let drain = std::thread::spawn(move || daemon.shutdown());
assert!(
matches!(link.daemon_rx.recv().unwrap(), DaemonMessage::ShuttingDown),
"ShuttingDown must arrive as a value before the channel closes"
);
assert!(
link.daemon_rx.recv().is_err(),
"after ShuttingDown the channel must be closed"
);
drop(link);
drain.join().unwrap();
}