swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/crates/phone-opus/tests
diff options
context:
space:
mode:
Diffstat (limited to 'crates/phone-opus/tests')
-rw-r--r--crates/phone-opus/tests/mcp_hardening.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/crates/phone-opus/tests/mcp_hardening.rs b/crates/phone-opus/tests/mcp_hardening.rs
index 0d53c33..0b32442 100644
--- a/crates/phone-opus/tests/mcp_hardening.rs
+++ b/crates/phone-opus/tests/mcp_hardening.rs
@@ -631,6 +631,7 @@ fn consult_reuses_context_per_cwd_by_default_and_fresh_context_opts_out() -> Tes
let args = must(fs::read_to_string(&args_file), "read fake args file")?;
let lines = args.lines().collect::<Vec<_>>();
assert!(lines.contains(&"-p"));
+ assert!(lines.contains(&"--verbose"));
assert!(lines.contains(&"--output-format"));
assert!(lines.contains(&"stream-json"));
assert!(lines.contains(&"--strict-mcp-config"));
@@ -838,6 +839,56 @@ fn consult_surfaces_downstream_cli_failures() -> TestResult {
}
#[test]
+fn silent_claude_processes_fail_fast_instead_of_wedging() -> TestResult {
+ let root = temp_root("consult_stall")?;
+ let state_home = root.join("state-home");
+ let fake_claude = root.join("claude");
+ let caller_home = root.join("caller-home");
+ must(fs::create_dir_all(&state_home), "create state home")?;
+ must(fs::create_dir_all(&caller_home), "create caller home")?;
+ seed_caller_claude_home(&caller_home)?;
+ write_fake_claude_script(&fake_claude)?;
+
+ let claude_bin = fake_claude.display().to_string();
+ let caller_home_path = caller_home.display().to_string();
+ let env = [
+ ("HOME", caller_home_path.as_str()),
+ ("PHONE_OPUS_CLAUDE_BIN", claude_bin.as_str()),
+ ("PHONE_OPUS_CLAUDE_INITIAL_OUTPUT_TIMEOUT_MS", "100"),
+ ("PHONE_OPUS_TEST_SLEEP_MS", "5000"),
+ ];
+ let mut harness = McpHarness::spawn(&state_home, &env)?;
+ let _ = harness.initialize()?;
+ harness.notify_initialized()?;
+
+ let started = std::time::Instant::now();
+ let consult = harness.call_tool(3, "consult", json!({ "prompt": "hang forever" }))?;
+ let elapsed = started.elapsed();
+
+ assert_tool_error(&consult);
+ assert_eq!(
+ tool_content(&consult)["fault"]["class"].as_str(),
+ Some("downstream")
+ );
+ assert!(
+ tool_content(&consult)["fault"]["detail"]
+ .as_str()
+ .is_some_and(|value| value.contains("produced no stream output within 100 ms"))
+ );
+ assert!(elapsed < std::time::Duration::from_secs(3));
+ assert_eq!(
+ tool_content(&consult)["context"]["consult"]["context_mode"].as_str(),
+ Some("fresh")
+ );
+ assert!(
+ tool_content(&consult)["context"]["consult"]["planned_session_id"]
+ .as_str()
+ .is_some_and(|value| !value.is_empty())
+ );
+ Ok(())
+}
+
+#[test]
fn quota_failures_surface_resume_context_for_same_cwd() -> TestResult {
let root = temp_root("consult_quota_failure")?;
let state_home = root.join("state-home");