chore: consolidate repeated rmcp tests (#931)
This commit is contained in:
parent
4b9bea7e7d
commit
e1af378949
9 changed files with 306 additions and 332 deletions
|
|
@ -23,6 +23,7 @@ use tokio::io::{AsyncRead, ReadBuf};
|
|||
// A slow tool server that sleeps before returning a response.
|
||||
#[derive(Debug, Clone)]
|
||||
struct SlowToolServer {
|
||||
#[expect(dead_code, reason = "tool_handler macro accesses this router field")]
|
||||
tool_router: ToolRouter<Self>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use serde_json::json;
|
|||
use tokio::sync::{Mutex, Notify};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
pub struct Server {}
|
||||
struct Server {}
|
||||
|
||||
impl ServerHandler for Server {
|
||||
fn get_info(&self) -> ServerInfo {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ impl ClientHandler for MyClient {
|
|||
}
|
||||
|
||||
pub struct MyServer {
|
||||
#[expect(dead_code, reason = "tool_handler macro accesses this router field")]
|
||||
tool_router: ToolRouter<Self>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ use schemars::JsonSchema;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||
pub struct CodeReviewRequest {
|
||||
pub file_path: String,
|
||||
pub language: String,
|
||||
struct CodeReviewRequest {
|
||||
file_path: String,
|
||||
language: String,
|
||||
}
|
||||
|
||||
#[prompt_handler(router = self.prompt_router)]
|
||||
|
|
@ -194,17 +194,17 @@ impl CodeReviewRequest {}
|
|||
|
||||
// Struct defined for testing optional field schema generation
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct OptionalFieldTestSchema {
|
||||
struct OptionalFieldTestSchema {
|
||||
#[schemars(description = "An optional description field")]
|
||||
pub description: Option<String>,
|
||||
description: Option<String>,
|
||||
}
|
||||
|
||||
// Struct defined for testing optional i64 field schema generation and null handling
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct OptionalI64TestSchema {
|
||||
struct OptionalI64TestSchema {
|
||||
#[schemars(description = "An optional i64 field")]
|
||||
pub count: Option<i64>,
|
||||
pub mandatory_field: String, // Added to ensure non-empty object schema
|
||||
count: Option<i64>,
|
||||
mandatory_field: String, // Added to ensure non-empty object schema
|
||||
}
|
||||
|
||||
// Dummy struct to host the test prompt method
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@ use rmcp::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TestHandler<T: 'static = ()> {
|
||||
pub _marker: std::marker::PhantomData<fn(*const T)>,
|
||||
struct TestHandler<T: 'static = ()> {
|
||||
_marker: std::marker::PhantomData<fn(*const T)>,
|
||||
}
|
||||
|
||||
impl<T: 'static> ServerHandler for TestHandler<T> {}
|
||||
|
||||
#[derive(Debug, schemars::JsonSchema, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Request {
|
||||
pub fields: HashMap<String, String>,
|
||||
struct Request {
|
||||
fields: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, schemars::JsonSchema, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Sum {
|
||||
pub a: i32,
|
||||
pub b: i32,
|
||||
struct Sum {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[rmcp::prompt_router(router = "test_router")]
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use rmcp::{
|
|||
/// Server with tools having different task support modes.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TaskSupportTestServer {
|
||||
#[expect(dead_code, reason = "tool_handler macro accesses this router field")]
|
||||
tool_router: ToolRouter<Self>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,33 +45,26 @@ impl ServerHandler for TestToolServer {
|
|||
ServerInfo::new(ServerCapabilities::builder().enable_tools().build())
|
||||
}
|
||||
|
||||
fn call_tool(
|
||||
async fn call_tool(
|
||||
&self,
|
||||
request: rmcp::model::CallToolRequestParams,
|
||||
context: rmcp::service::RequestContext<RoleServer>,
|
||||
) -> impl std::future::Future<Output = Result<CallToolResult, rmcp::ErrorData>> + MaybeSendFuture + '_
|
||||
{
|
||||
async move {
|
||||
let router = self.router.read().await;
|
||||
let tcc = ToolCallContext::new(self, request, context);
|
||||
router.call(tcc).await
|
||||
}
|
||||
) -> Result<CallToolResult, rmcp::ErrorData> {
|
||||
let router = self.router.read().await;
|
||||
let tcc = ToolCallContext::new(self, request, context);
|
||||
router.call(tcc).await
|
||||
}
|
||||
|
||||
fn list_tools(
|
||||
async fn list_tools(
|
||||
&self,
|
||||
_request: Option<rmcp::model::PaginatedRequestParams>,
|
||||
_context: rmcp::service::RequestContext<RoleServer>,
|
||||
) -> impl std::future::Future<Output = Result<rmcp::model::ListToolsResult, rmcp::ErrorData>>
|
||||
+ MaybeSendFuture
|
||||
+ '_ {
|
||||
async move {
|
||||
let router = self.router.read().await;
|
||||
Ok(rmcp::model::ListToolsResult {
|
||||
tools: router.list_all(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
) -> Result<rmcp::model::ListToolsResult, rmcp::ErrorData> {
|
||||
let router = self.router.read().await;
|
||||
Ok(rmcp::model::ListToolsResult {
|
||||
tools: router.list_all(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn on_initialized(
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
/// Parameters for weather tool.
|
||||
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||
pub struct GetWeatherRequest {
|
||||
struct GetWeatherRequest {
|
||||
/// City of interest.
|
||||
pub city: String,
|
||||
city: String,
|
||||
/// Date of interest.
|
||||
pub date: String,
|
||||
date: String,
|
||||
}
|
||||
|
||||
#[tool_handler(router = self.tool_router)]
|
||||
|
|
@ -162,21 +162,21 @@ impl GetWeatherRequest {}
|
|||
|
||||
/// Struct defined for testing optional field schema generation.
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct OptionalFieldTestSchema {
|
||||
struct OptionalFieldTestSchema {
|
||||
/// Field description.
|
||||
#[schemars(description = "An optional description field")]
|
||||
pub description: Option<String>,
|
||||
description: Option<String>,
|
||||
}
|
||||
|
||||
/// Struct defined for testing optional i64 field schema generation and null handling.
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct OptionalI64TestSchema {
|
||||
struct OptionalI64TestSchema {
|
||||
/// Optional count field.
|
||||
#[schemars(description = "An optional i64 field")]
|
||||
pub count: Option<i64>,
|
||||
count: Option<i64>,
|
||||
|
||||
/// Added to ensure non-empty object schema.
|
||||
pub mandatory_field: String,
|
||||
mandatory_field: String,
|
||||
}
|
||||
|
||||
/// Dummy struct to host the test tool method.
|
||||
|
|
@ -370,7 +370,7 @@ async fn test_optional_i64_field_with_null_input() -> anyhow::Result<()> {
|
|||
|
||||
/// Minimal server: no tool_router field, no new(), no get_info().
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MinimalServer;
|
||||
struct MinimalServer;
|
||||
|
||||
#[tool_router]
|
||||
impl MinimalServer {
|
||||
|
|
@ -452,7 +452,7 @@ async fn test_minimal_server_tool_call() -> anyhow::Result<()> {
|
|||
/// Same minimal pattern as [`MinimalServer`], but `#[tool_handler]` is omitted using
|
||||
/// `#[tool_router(server_handler)]` (emits `#[tool_handler]` for a second macro pass).
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ElidedToolHandlerServer;
|
||||
struct ElidedToolHandlerServer;
|
||||
|
||||
#[tool_router(server_handler)]
|
||||
impl ElidedToolHandlerServer {
|
||||
|
|
@ -509,7 +509,7 @@ async fn test_tool_router_server_handler_flag_end_to_end_tool_call() -> anyhow::
|
|||
|
||||
/// Server with custom name/version/instructions via tool_handler attributes.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CustomInfoServer;
|
||||
struct CustomInfoServer;
|
||||
|
||||
#[tool_router]
|
||||
impl CustomInfoServer {
|
||||
|
|
@ -539,7 +539,7 @@ fn test_custom_info_server() {
|
|||
|
||||
/// Server that provides its own get_info() — macro should not override it.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ManualInfoServer;
|
||||
struct ManualInfoServer;
|
||||
|
||||
#[tool_router]
|
||||
impl ManualInfoServer {
|
||||
|
|
|
|||
|
|
@ -11,20 +11,20 @@ use rmcp::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TestHandler<T: 'static = ()> {
|
||||
pub _marker: std::marker::PhantomData<fn(*const T)>,
|
||||
struct TestHandler<T: 'static = ()> {
|
||||
_marker: std::marker::PhantomData<fn(*const T)>,
|
||||
}
|
||||
|
||||
impl<T: 'static> ServerHandler for TestHandler<T> {}
|
||||
#[derive(Debug, schemars::JsonSchema, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Request {
|
||||
pub fields: HashMap<String, String>,
|
||||
struct Request {
|
||||
fields: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, schemars::JsonSchema, serde::Deserialize, serde::Serialize)]
|
||||
pub struct Sum {
|
||||
pub a: i32,
|
||||
pub b: i32,
|
||||
struct Sum {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[rmcp::tool_router(router = test_router_1)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue