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(())
}