swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/crates/phone-opus/tests/mcp_hardening.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/phone-opus/tests/mcp_hardening.rs')
-rw-r--r--crates/phone-opus/tests/mcp_hardening.rs55
1 files changed, 52 insertions, 3 deletions
diff --git a/crates/phone-opus/tests/mcp_hardening.rs b/crates/phone-opus/tests/mcp_hardening.rs
index b47b365..bc338ca 100644
--- a/crates/phone-opus/tests/mcp_hardening.rs
+++ b/crates/phone-opus/tests/mcp_hardening.rs
@@ -11,6 +11,7 @@ use libmcp_testkit::read_json_lines;
use serde as _;
use serde_json::{Value, json};
use thiserror as _;
+use uuid as _;
type TestResult<T = ()> = Result<T, Box<dyn std::error::Error>>;
@@ -223,7 +224,8 @@ fn cold_start_exposes_consult_and_ops_tools() -> TestResult {
}
#[test]
-fn consult_uses_read_only_toolset_and_requested_working_directory() -> TestResult {
+fn consult_can_resume_a_prior_session_with_read_only_toolset_and_requested_working_directory()
+-> TestResult {
let root = temp_root("consult_success")?;
let state_home = root.join("state-home");
let sandbox = root.join("sandbox");
@@ -234,6 +236,7 @@ fn consult_uses_read_only_toolset_and_requested_working_directory() -> TestResul
let stdout_file = root.join("stdout.json");
let args_file = root.join("args.txt");
let pwd_file = root.join("pwd.txt");
+ let resumed_session = "81f218eb-568b-409b-871b-f6e86d8f666f";
write_fake_claude_script(&fake_claude)?;
must(
fs::write(
@@ -247,7 +250,7 @@ fn consult_uses_read_only_toolset_and_requested_working_directory() -> TestResul
"num_turns": 2,
"result": "oracle",
"stop_reason": "end_turn",
- "session_id": "session-123",
+ "session_id": resumed_session,
"total_cost_usd": 0.125,
"usage": {
"input_tokens": 10,
@@ -287,16 +290,29 @@ fn consult_uses_read_only_toolset_and_requested_working_directory() -> TestResul
json!({
"prompt": "say oracle",
"cwd": sandbox.display().to_string(),
- "max_turns": 7
+ "max_turns": 7,
+ "session_id": resumed_session
}),
)?;
assert_tool_ok(&consult);
assert_eq!(tool_content(&consult)["response"].as_str(), Some("oracle"));
assert_eq!(
+ tool_content(&consult)["session_mode"].as_str(),
+ Some("resumed")
+ );
+ assert_eq!(
+ tool_content(&consult)["requested_session_id"].as_str(),
+ Some(resumed_session)
+ );
+ assert_eq!(
tool_content(&consult)["cwd"].as_str(),
Some(sandbox.display().to_string().as_str())
);
assert_eq!(tool_content(&consult)["num_turns"].as_u64(), Some(2));
+ assert_eq!(
+ tool_content(&consult)["session_id"].as_str(),
+ Some(resumed_session)
+ );
let pwd = must(fs::read_to_string(&pwd_file), "read fake pwd file")?;
assert_eq!(pwd.trim(), sandbox.display().to_string());
@@ -315,6 +331,8 @@ fn consult_uses_read_only_toolset_and_requested_working_directory() -> TestResul
assert!(lines.contains(&"Bash,Read,Grep,Glob,LS,WebFetch,WebSearch"));
assert!(lines.contains(&"--permission-mode"));
assert!(lines.contains(&"dontAsk"));
+ assert!(lines.contains(&"--resume"));
+ assert!(lines.contains(&resumed_session));
assert!(lines.contains(&"--max-turns"));
assert!(lines.contains(&"7"));
assert_eq!(lines.last().copied(), Some("say oracle"));
@@ -334,6 +352,37 @@ fn consult_uses_read_only_toolset_and_requested_working_directory() -> TestResul
}
#[test]
+fn consult_rejects_invalid_session_handles() -> TestResult {
+ let root = temp_root("consult_invalid_session")?;
+ let state_home = root.join("state-home");
+ must(fs::create_dir_all(&state_home), "create state home")?;
+
+ let mut harness = McpHarness::spawn(&state_home, &[])?;
+ let _ = harness.initialize()?;
+ harness.notify_initialized()?;
+
+ let consult = harness.call_tool(
+ 3,
+ "consult",
+ json!({
+ "prompt": "fail",
+ "session_id": "not-a-uuid"
+ }),
+ )?;
+ assert_tool_error(&consult);
+ assert_eq!(
+ tool_content(&consult)["fault"]["class"].as_str(),
+ Some("protocol")
+ );
+ assert!(
+ tool_content(&consult)["fault"]["detail"]
+ .as_str()
+ .is_some_and(|value| value.contains("session_id must be a valid UUID"))
+ );
+ Ok(())
+}
+
+#[test]
fn consult_surfaces_downstream_cli_failures() -> TestResult {
let root = temp_root("consult_failure")?;
let state_home = root.join("state-home");