use std::net::TcpListener;
use std::os::unix::fs::PermissionsExt;
use std::time::Duration;
use super::{CENTRAL_ISSUER, CENTRAL_SERVER, init, refuse_unanswered_loopback};
type TestResult = Result<(), Box<dyn std::error::Error>>;
const BOUND: Duration = Duration::from_millis(2_000);
#[test]
fn seat_init_writes_the_central_addresses_private_and_never_a_pass() -> TestResult {
let dir = tempfile::tempdir()?;
let out = dir.path().join("seat.toml");
init("agent-7", &dir.path().join("agent.key"), &out)?;
let mode = std::fs::metadata(&out)?.permissions().mode() & 0o777;
assert_eq!(mode, 0o600);
let text = std::fs::read_to_string(&out)?;
assert!(
text.contains(&format!("server = \"{CENTRAL_SERVER}\"")),
"{text}"
);
assert!(
text.contains(&format!("issuer = \"{CENTRAL_ISSUER}\"")),
"{text}"
);
assert!(
!text.contains("127.0.0.1") && !text.contains("token"),
"{text}"
);
let config = crate::Config::load(&out)?;
assert_eq!(config.server, CENTRAL_SERVER);
Ok(())
}
#[test]
fn seat_init_never_replaces_a_seat_file() -> TestResult {
let dir = tempfile::tempdir()?;
let out = dir.path().join("seat.toml");
std::fs::write(&out, "kept")?;
let refused = init("agent-7", &dir.path().join("agent.key"), &out);
assert!(refused.is_err_and(|e| e.to_string().starts_with("liminal_seat_unwritable")));
assert_eq!(std::fs::read_to_string(&out)?, "kept");
Ok(())
}
#[test]
fn an_agent_id_that_would_break_the_file_is_refused() -> TestResult {
let dir = tempfile::tempdir()?;
for agent in ["", "a\"b", "a\nb"] {
assert!(init(agent, &dir.path().join("k"), &dir.path().join("s.toml")).is_err());
}
Ok(())
}
#[test]
fn a_loopback_address_nothing_answers_on_is_refused_by_name() -> TestResult {
let port = TcpListener::bind("127.0.0.1:0")?.local_addr()?.port();
for address in [
format!("127.0.0.1:{port}"),
format!("ws://127.0.0.1:{port}/ws"),
format!("http://localhost:{port}"),
] {
let refused = refuse_unanswered_loopback(&address, BOUND);
assert_eq!(
refused,
Err(format!(
"liminal_mcp_loopback_unanswered: nothing answers at {address}"
))
);
}
Ok(())
}
#[test]
fn a_loopback_address_that_answers_and_any_remote_address_pass() -> TestResult {
let listener = TcpListener::bind("127.0.0.1:0")?;
let port = listener.local_addr()?.port();
assert_eq!(
refuse_unanswered_loopback(&format!("127.0.0.1:{port}"), BOUND),
Ok(())
);
assert_eq!(refuse_unanswered_loopback(CENTRAL_SERVER, BOUND), Ok(()));
assert_eq!(refuse_unanswered_loopback(CENTRAL_ISSUER, BOUND), Ok(()));
Ok(())
}
#[test]
fn a_seat_that_names_no_server_and_no_issuer_reads_as_the_central_services() -> TestResult {
let dir = tempfile::tempdir()?;
let out = dir.path().join("seat.toml");
std::fs::write(
&out,
"channel = \"c\"\n\n[lys]\nagent = \"agent-7\"\nkey_file = \"agent.key\"\n\n\
[limits]\nframe_bytes = 65536\nrecord_bytes = 1048576\nreply_timeout_ms = 10000\n\
flow_steps = 8\nrequest_bytes = 65536\n",
)?;
let config = crate::Config::load(&out)?;
assert_eq!(config.server, CENTRAL_SERVER);
let crate::config::Credential::Lys(lys) = &config.credential else {
return Err("the seat's credential is not Lys".into());
};
assert_eq!(lys.issuer, CENTRAL_ISSUER);
Ok(())
}