liminal-cli 0.3.1

The liminal command: serve the network, maintain its stores, or serve its discovery MCP over stdio
Documentation
//! ACCESS-010 R4: `liminal check` reads a seat file too, names its kind and
//! its credential by kind only, and refuses a file that is neither.

use std::error::Error;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

type TestResult = Result<(), Box<dyn Error>>;

const LIMITS: &str = "[limits]\nframe_bytes = 65536\nrecord_bytes = 1048576\nreply_timeout_ms = 10000\n\
flow_steps = 8\nrequest_bytes = 65536\n";

fn check(path: &Path) -> Result<Output, std::io::Error> {
    let mut command = Command::new(env!("CARGO_BIN_EXE_liminal"));
    for (name, _) in std::env::vars_os() {
        let name_text = name.to_string_lossy();
        if name_text.starts_with("LIMINAL_") || name_text.starts_with("LYS_") {
            command.env_remove(name);
        }
    }
    command.arg("check").arg("--config").arg(path).output()
}

fn seat(dir: &Path, credential: &str) -> Result<PathBuf, Box<dyn Error>> {
    let path = dir.join("seat.toml");
    std::fs::write(
        &path,
        format!(
            "server = \"127.0.0.1:7900\"\nchannel = \"console.topology\"\n{credential}\n{LIMITS}"
        ),
    )?;
    Ok(path)
}

fn ok_line(output: &Output, path: &Path, credential: &str) {
    let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
    assert_eq!(output.status.code(), Some(0), "{stderr}");
    assert_eq!(
        String::from_utf8_lossy(&output.stdout),
        format!("{}: seat configuration ok: {credential}\n", path.display())
    );
    assert!(stderr.is_empty(), "{stderr}");
}

#[test]
fn an_open_seat_checks_ok_by_kind() -> TestResult {
    let dir = tempfile::tempdir()?;
    let path = seat(dir.path(), "")?;
    ok_line(&check(&path)?, &path, "open");
    Ok(())
}

#[test]
fn a_token_seat_checks_ok_and_prints_no_token_byte() -> TestResult {
    let dir = tempfile::tempdir()?;
    std::fs::write(dir.path().join("token"), "distinct-token-7f3a\n")?;
    let path = seat(dir.path(), "token_file = \"token\"")?;
    let output = check(&path)?;
    ok_line(&output, &path, "token file");
    let printed = format!(
        "{}{}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
    assert!(!printed.contains("distinct-token-7f3a"), "{printed}");
    Ok(())
}

#[test]
fn a_lys_seat_names_its_issuer_only() -> TestResult {
    let dir = tempfile::tempdir()?;
    let path = seat(
        dir.path(),
        "[lys]\nissuer = \"http://127.0.0.1:8490\"\nagent = \"agent-under-test\"",
    )?;
    ok_line(&check(&path)?, &path, "lys issuer http://127.0.0.1:8490");
    Ok(())
}

#[test]
fn a_seat_with_a_zero_limit_is_refused_naming_it() -> TestResult {
    let dir = tempfile::tempdir()?;
    let path = seat(dir.path(), "")?;
    let text = std::fs::read_to_string(&path)?.replace("flow_steps = 8", "flow_steps = 0");
    std::fs::write(&path, text)?;
    let output = check(&path)?;
    assert_eq!(output.status.code(), Some(2));
    assert!(output.stdout.is_empty());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("flow_steps"), "{stderr}");
    Ok(())
}

#[test]
fn a_file_that_is_neither_is_refused_naming_both_fields() -> TestResult {
    let dir = tempfile::tempdir()?;
    let path = dir.path().join("neither.toml");
    std::fs::write(&path, "name = 1\n")?;
    let output = check(&path)?;
    assert_eq!(output.status.code(), Some(2));
    assert!(output.stdout.is_empty());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert_eq!(
        stderr,
        format!(
            "{}: neither a server configuration (no listen_address) nor a seat (no channel)\n",
            path.display()
        )
    );
    Ok(())
}