liminal-cli 0.3.1

The liminal command: serve the network, maintain its stores, or serve its discovery MCP over stdio
Documentation
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 {
    // A port bound then released: nothing listens on it.
    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(())
    );
    // A remote address is never dialled here; its own connection answers for it.
    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(())
}