fix(mcp): 修复前端空输入重置为不超时,增加超时路径单元测试
P3: 清空输入框时回退到默认值 300 而非 0;新增两个 tokio 测试覆盖有超时和无超时(error pass-through)路径
This commit is contained in:
parent
3e97ed903c
commit
77a0eac2c8
@ -281,4 +281,49 @@ mod tests {
|
|||||||
// Empty stays empty
|
// Empty stays empty
|
||||||
assert_eq!(sanitize_tool_name(""), "");
|
assert_eq!(sanitize_tool_name(""), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_execute_returns_error_when_server_not_connected() {
|
||||||
|
// McpClientManager with no connected servers — call should fail immediately
|
||||||
|
// with "not connected" error, not hang or timeout.
|
||||||
|
let manager = Arc::new(McpClientManager::new());
|
||||||
|
let schema: serde_json::Map<String, serde_json::Value> =
|
||||||
|
serde_json::json!({"type": "object"})
|
||||||
|
.as_object()
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let tool_info = Tool::new("echo", "Echo tool", schema);
|
||||||
|
let wrapper = McpToolWrapper::new(manager, "ghost".to_string(), tool_info, 300);
|
||||||
|
|
||||||
|
let result = wrapper.execute(serde_json::json!({})).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
let msg = result.unwrap_err().to_string();
|
||||||
|
assert!(
|
||||||
|
msg.contains("not connected"),
|
||||||
|
"expected 'not connected' error, got: {msg}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_timeout_zero_does_not_wrap() {
|
||||||
|
// With timeout_secs = 0, the wrapper should pass through directly
|
||||||
|
// without tokio::time::timeout. The call still fails because no server
|
||||||
|
// is connected, but the error path is the non-timeout branch.
|
||||||
|
let manager = Arc::new(McpClientManager::new());
|
||||||
|
let schema: serde_json::Map<String, serde_json::Value> =
|
||||||
|
serde_json::json!({"type": "object"})
|
||||||
|
.as_object()
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
let tool_info = Tool::new("echo", "Echo tool", schema);
|
||||||
|
let wrapper = McpToolWrapper::new(manager, "ghost".to_string(), tool_info, 0);
|
||||||
|
|
||||||
|
let result = wrapper.execute(serde_json::json!({})).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
let msg = result.unwrap_err().to_string();
|
||||||
|
assert!(
|
||||||
|
msg.contains("not connected"),
|
||||||
|
"expected 'not connected' error, got: {msg}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,7 +63,10 @@ export function McpTab({ config, update, setToast }: Props) {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={config.mcp_tool_timeout_secs ?? 300}
|
value={config.mcp_tool_timeout_secs ?? 300}
|
||||||
onChange={(e) => update('mcp_tool_timeout_secs', Number(e.target.value))}
|
onChange={(e) => {
|
||||||
|
const v = e.target.value;
|
||||||
|
update('mcp_tool_timeout_secs', v === '' ? 300 : Number(v));
|
||||||
|
}}
|
||||||
className={inputCls}
|
className={inputCls}
|
||||||
min={0}
|
min={0}
|
||||||
step={30}
|
step={30}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user