fix(acp): fixtures now raise content mismatch errors (#6912)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -30,7 +30,7 @@ pub async fn run_basic_completion<S: Session>() {
|
|||||||
let output = session
|
let output = session
|
||||||
.prompt("what is 1+1", PermissionDecision::Cancel)
|
.prompt("what is 1+1", PermissionDecision::Cancel)
|
||||||
.await;
|
.await;
|
||||||
assert!(output.text.contains("2"));
|
assert_eq!(output.text, "2");
|
||||||
expected_session_id.assert_matches(&session.id().0);
|
expected_session_id.assert_matches(&session.id().0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ pub async fn run_mcp_http_server<S: Session>() {
|
|||||||
PermissionDecision::Cancel,
|
PermissionDecision::Cancel,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert!(output.text.contains(FAKE_CODE));
|
assert_eq!(output.text, FAKE_CODE);
|
||||||
expected_session_id.assert_matches(&session.id().0);
|
expected_session_id.assert_matches(&session.id().0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ pub async fn run_builtin_and_mcp<S: Session>() {
|
|||||||
include_str!("../test_data/openai_builtin_execute.txt"),
|
include_str!("../test_data/openai_builtin_execute.txt"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
r#""writeResult": "Successfully wrote to /tmp/result.txt"#.into(),
|
r#"\"writeResult\": \"Successfully wrote to /tmp/result.txt"#.into(),
|
||||||
include_str!("../test_data/openai_builtin_final.txt"),
|
include_str!("../test_data/openai_builtin_final.txt"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -104,10 +104,13 @@ pub async fn run_builtin_and_mcp<S: Session>() {
|
|||||||
let mut session = S::new(config, openai).await;
|
let mut session = S::new(config, openai).await;
|
||||||
expected_session_id.set(session.id());
|
expected_session_id.set(session.id());
|
||||||
|
|
||||||
let _ = session.prompt(prompt, PermissionDecision::Cancel).await;
|
let output = session.prompt(prompt, PermissionDecision::Cancel).await;
|
||||||
|
if matches!(output.tool_status, Some(ToolCallStatus::Failed)) || output.text.contains("error") {
|
||||||
|
panic!("{}", output.text);
|
||||||
|
}
|
||||||
|
|
||||||
let result = fs::read_to_string("/tmp/result.txt").unwrap_or_default();
|
let result = fs::read_to_string("/tmp/result.txt").unwrap_or_default();
|
||||||
assert!(result.contains(FAKE_CODE));
|
assert_eq!(result, format!("{FAKE_CODE}\n"));
|
||||||
expected_session_id.assert_matches(&session.id().0);
|
expected_session_id.assert_matches(&session.id().0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,6 +218,6 @@ pub async fn run_configured_extension<S: Session>() {
|
|||||||
expected_session_id.set(session.id());
|
expected_session_id.set(session.id());
|
||||||
|
|
||||||
let output = session.prompt(prompt, PermissionDecision::Cancel).await;
|
let output = session.prompt(prompt, PermissionDecision::Cancel).await;
|
||||||
assert!(output.text.contains(FAKE_CODE));
|
assert_eq!(output.text, FAKE_CODE);
|
||||||
expected_session_id.assert_matches(&session.id().0);
|
expected_session_id.assert_matches(&session.id().0);
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-18
@@ -1,7 +1,6 @@
|
|||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(unused_attributes)]
|
#![allow(unused_attributes)]
|
||||||
|
|
||||||
use assert_json_diff::{assert_json_matches_no_panic, CompareMode, Config};
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
use goose::builtin_extension::register_builtin_extensions;
|
use goose::builtin_extension::register_builtin_extensions;
|
||||||
@@ -153,8 +152,9 @@ impl OpenAiFixture {
|
|||||||
let queue = queue.clone();
|
let queue = queue.clone();
|
||||||
let expected_session_id = expected_session_id.clone();
|
let expected_session_id = expected_session_id.clone();
|
||||||
move |req: &wiremock::Request| {
|
move |req: &wiremock::Request| {
|
||||||
let body = String::from_utf8_lossy(&req.body);
|
let body = std::str::from_utf8(&req.body).unwrap_or("");
|
||||||
|
|
||||||
|
// Validate session ID header
|
||||||
let actual = req
|
let actual = req
|
||||||
.headers
|
.headers
|
||||||
.get(SESSION_ID_HEADER)
|
.get(SESSION_ID_HEADER)
|
||||||
@@ -174,28 +174,30 @@ impl OpenAiFixture {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (expected_body, response) = {
|
// See if the actual request matches the expected pattern
|
||||||
let mut q = queue.lock().unwrap();
|
let mut q = queue.lock().unwrap();
|
||||||
q.pop_front().unwrap_or_default()
|
let (expected_body, response) = q.front().cloned().unwrap_or_default();
|
||||||
};
|
if !expected_body.is_empty() && body.contains(&expected_body) {
|
||||||
|
q.pop_front();
|
||||||
if body.contains(&expected_body) && !expected_body.is_empty() {
|
|
||||||
return ResponseTemplate::new(200)
|
return ResponseTemplate::new(200)
|
||||||
.insert_header("content-type", "text/event-stream")
|
.insert_header("content-type", "text/event-stream")
|
||||||
.set_body_string(response);
|
.set_body_string(response);
|
||||||
}
|
}
|
||||||
|
drop(q);
|
||||||
|
|
||||||
// Coerce non-json to allow a uniform JSON diff error response.
|
// If there was no body, the request was unexpected. Otherwise, it is a mismatch.
|
||||||
let exp = serde_json::from_str(&expected_body)
|
let message = if expected_body.is_empty() {
|
||||||
.unwrap_or(serde_json::Value::String(expected_body.clone()));
|
format!("Unexpected request:\n {}", body)
|
||||||
let act = serde_json::from_str(&body)
|
} else {
|
||||||
.unwrap_or(serde_json::Value::String(body.to_string()));
|
format!(
|
||||||
let diff =
|
"Expected body to contain:\n {}\n\nActual body:\n {}",
|
||||||
assert_json_matches_no_panic(&exp, &act, Config::new(CompareMode::Strict))
|
expected_body, body
|
||||||
.unwrap_err();
|
)
|
||||||
|
};
|
||||||
|
// Use OpenAI's error response schema so the provider will pass the error through.
|
||||||
ResponseTemplate::new(417)
|
ResponseTemplate::new(417)
|
||||||
.insert_header("content-type", "application/json")
|
.insert_header("content-type", "application/json")
|
||||||
.set_body_json(serde_json::json!({"error": {"message": diff}}))
|
.set_body_json(serde_json::json!({"error": {"message": message}}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.mount(&mock_server)
|
.mount(&mock_server)
|
||||||
@@ -464,7 +466,10 @@ where
|
|||||||
runtime.block_on(fut);
|
runtime.block_on(fut);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
handle.join().unwrap();
|
if let Err(err) = handle.join() {
|
||||||
|
// Re-raise the original panic so the test shows the real failure message.
|
||||||
|
std::panic::resume_unwind(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|||||||
Reference in New Issue
Block a user