Files
codex/codex-rs/cli/tests/app_server.rs
2026-06-23 20:06:19 -07:00

131 lines
3.6 KiB
Rust

use std::path::Path;
use anyhow::Result;
use predicates::str::contains;
use tempfile::TempDir;
fn codex_command(codex_home: &Path) -> Result<assert_cmd::Command> {
let mut cmd = assert_cmd::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?);
cmd.env("CODEX_HOME", codex_home);
Ok(cmd)
}
#[test]
fn strict_config_rejects_unknown_config_fields_for_app_server() -> Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
r#"
foo = "bar"
"#,
)?;
let mut cmd = codex_command(codex_home.path())?;
cmd.args(["app-server", "--strict-config", "--listen", "off"])
.assert()
.failure()
.stderr(contains("unknown configuration field"));
Ok(())
}
#[cfg(unix)]
#[test]
fn proxy_ensure_listener_recovers_a_stale_socket_and_reuses_the_listener() -> Result<()> {
use std::os::unix::net::UnixListener;
let codex_home = TempDir::new()?;
let socket_dir = codex_home.path().join("app-server-control");
let socket_path = socket_dir.join("app-server-control.sock");
std::fs::create_dir_all(&socket_dir)?;
let stale_listener = UnixListener::bind(&socket_path)?;
drop(stale_listener);
let mut first_proxy = codex_command(codex_home.path())?;
first_proxy
.args(["app-server", "proxy", "--ensure-listener"])
.assert()
.success();
let pid_file = codex_home.path().join("app-server-daemon/app-server.pid");
let first_pid_record = std::fs::read_to_string(&pid_file)?;
let mut second_proxy = codex_command(codex_home.path())?;
second_proxy
.args(["app-server", "proxy", "--ensure-listener"])
.assert()
.success();
let second_pid_record = std::fs::read_to_string(pid_file)?;
let mut stop = codex_command(codex_home.path())?;
stop.args(["app-server", "daemon", "stop"])
.assert()
.success();
assert_eq!(first_pid_record, second_pid_record);
Ok(())
}
#[cfg(unix)]
#[test]
fn proxy_ensure_listener_rejects_a_non_default_socket() -> Result<()> {
let codex_home = TempDir::new()?;
let other_socket = codex_home.path().join("other.sock");
let mut proxy = codex_command(codex_home.path())?;
let output = proxy
.args([
"app-server",
"proxy",
"--ensure-listener",
"--sock",
other_socket.to_str().expect("temp path should be UTF-8"),
])
.output()?;
let mut stop = codex_command(codex_home.path())?;
stop.args(["app-server", "daemon", "stop"])
.assert()
.success();
assert!(!output.status.success());
assert!(
String::from_utf8_lossy(&output.stderr)
.contains("--ensure-listener only supports the CODEX_HOME socket")
);
Ok(())
}
#[cfg(unix)]
#[test]
fn proxy_ensure_listener_accepts_default_socket_through_symlinked_codex_home() -> Result<()> {
use std::os::unix::fs::symlink;
let real_home = TempDir::new()?;
let link_parent = TempDir::new()?;
let linked_home = link_parent.path().join("linked-codex-home");
symlink(real_home.path(), &linked_home)?;
let socket_path = linked_home.join("app-server-control/app-server-control.sock");
let mut proxy = codex_command(&linked_home)?;
proxy
.args([
"app-server",
"proxy",
"--ensure-listener",
"--sock",
socket_path.to_str().expect("temp path should be UTF-8"),
])
.assert()
.success();
let mut stop = codex_command(&linked_home)?;
stop.args(["app-server", "daemon", "stop"])
.assert()
.success();
Ok(())
}