mod common;
use common::orcs_cmd;
use predicates::str::contains;
#[test]
fn command_mode_empty_args_enters_interactive() {
let (mut cmd, _guard) = orcs_cmd();
cmd.write_stdin("").assert().success();
}
#[test]
fn command_mode_at_unknown_component_fails() {
let (mut cmd, _guard) = orcs_cmd();
cmd.args(["@nonexistent", "test"])
.assert()
.stderr(contains("Unknown component: @nonexistent"));
}
#[test]
fn command_mode_at_shell_routes_but_needs_approval() {
let (mut cmd, _guard) = orcs_cmd();
cmd.arg("-d")
.args(["@shell", "echo", "hello_cmd_mode"])
.assert()
.failure()
.stdout(contains("Routed @shell to channel"))
.stderr(contains("interactive approval"));
}
#[test]
fn command_mode_llm_pipeline() {
use std::io::{Read, Write};
use std::net::TcpListener;
use std::process::{Command, Stdio};
use std::thread;
let tmp = tempfile::tempdir().expect("create temp dir");
let bin = assert_cmd::cargo::cargo_bin!("orcs");
let listener = TcpListener::bind("127.0.0.1:0").expect("bind mock HTTP server");
let mock_port = listener.local_addr().expect("get mock port").port();
let mock_base_url = format!("http://127.0.0.1:{}", mock_port);
let server_thread = thread::spawn(move || {
for stream in listener.incoming() {
let mut stream = match stream {
Ok(s) => s,
Err(_) => break,
};
let mut request = Vec::new();
let mut buf = [0u8; 4096];
while let Ok(n) = stream.read(&mut buf) {
if n == 0 {
break;
}
request.extend_from_slice(&buf[..n]);
let req_str = String::from_utf8_lossy(&request);
if let Some(header_end) = req_str.find("\r\n\r\n") {
let headers = &req_str[..header_end];
let content_length: usize = headers
.lines()
.find(|l| l.to_lowercase().starts_with("content-length:"))
.and_then(|l| l.split(':').nth(1))
.and_then(|v| v.trim().parse().ok())
.unwrap_or(0);
let body_start = header_end + 4;
if request.len() >= body_start + content_length {
break;
}
}
}
let ollama_response = r#"{"model":"mock-model","choices":[{"index":0,"message":{"role":"assistant","content":"CMD_MODE_RESPONSE_99"},"finish_reason":"stop"}]}"#;
let http_response = format!(
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
ollama_response.len(),
ollama_response
);
let _ = stream.write_all(http_response.as_bytes());
let _ = stream.flush();
}
});
let child = Command::new(bin)
.arg("-d")
.arg("--sandbox")
.arg(tmp.path())
.arg("test_cmd_mode_msg")
.env("ORCS_LLM_BASE_URL", &mock_base_url)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("spawn orcs process");
let output = child.wait_with_output().expect("wait for orcs to complete");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
drop(server_thread);
let _dump = common::dump_test_output("cmd_mode", &stdout, &stderr);
eprintln!("=== CMD_MODE DEBUG ===");
eprintln!("exit_status={:?}", output.status);
eprintln!("stdout_len={} stderr_len={}", stdout.len(), stderr.len());
eprintln!("=== END DEBUG ===");
assert!(
stdout.contains("AgentMgr received: test_cmd_mode_msg"),
"agent_mgr should log receipt of command.\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
let has_mock_response = stdout.contains("CMD_MODE_RESPONSE_99");
eprintln!("has_mock_response={has_mock_response}");
assert!(
has_mock_response,
"Expected mock LLM response 'CMD_MODE_RESPONSE_99' in stdout.\n\
This verifies the full command-mode pipeline.\n\
stdout:\n{stdout}\nstderr:\n{stderr}"
);
}