Skip to main content

tooltest_core/runner/
transport.rs

1use std::future::Future;
2use std::pin::Pin;
3
4use crate::{HttpConfig, RunConfig, RunFailure, RunResult, SessionDriver, StdioConfig};
5
6use super::execution::{run_with_session, RunnerOptions};
7use super::result::failure_result;
8
9pub(super) type ConnectFuture<'a> =
10    Pin<Box<dyn Future<Output = Result<SessionDriver, crate::SessionError>> + Send + 'a>>;
11
12/// Execute a tooltest run against a stdio MCP endpoint.
13///
14/// Uses the same default and declarative assertions as [`run_with_session`].
15pub async fn run_stdio(
16    endpoint: &StdioConfig,
17    config: &RunConfig,
18    options: RunnerOptions,
19) -> RunResult {
20    let mut config = config.clone();
21    config.apply_stdio_pre_run_context(endpoint);
22    run_with_transport(
23        Box::pin(SessionDriver::connect_stdio(endpoint)),
24        "stdio",
25        &config,
26        options,
27    )
28    .await
29}
30
31/// Execute a tooltest run against an HTTP MCP endpoint.
32///
33/// Uses the same default and declarative assertions as [`run_with_session`].
34pub async fn run_http(
35    endpoint: &HttpConfig,
36    config: &RunConfig,
37    options: RunnerOptions,
38) -> RunResult {
39    run_with_transport(
40        Box::pin(SessionDriver::connect_http(endpoint)),
41        "http",
42        config,
43        options,
44    )
45    .await
46}
47
48pub(super) async fn run_with_transport(
49    connect: ConnectFuture<'_>,
50    label: &str,
51    config: &RunConfig,
52    options: RunnerOptions,
53) -> RunResult {
54    let session = match connect.await {
55        Ok(session) => session,
56        Err(error) => {
57            return failure_result(
58                RunFailure::new(format!("failed to connect {label} transport: {error}")),
59                Vec::new(),
60                None,
61                Vec::new(),
62                None,
63                None,
64            );
65        }
66    };
67    run_with_session(&session, config, options).await
68}