Trait TestServer

Source
pub trait TestServer {
    type Error: Error + Send + Sync + 'static;

    // Required method
    fn launch(
        &self,
        listener: TcpListener,
    ) -> impl Future<Output = Result<(), Self::Error>> + Send;

    // Provided methods
    fn is_healthy(
        &self,
        _client: &mut ApiClient,
    ) -> impl Future<Output = Result<HealthStatus, Self::Error>> + Send { ... }
    fn config(&self) -> TestServerConfig { ... }
}

Required Associated Types§

Source

type Error: Error + Send + Sync + 'static

The error type that can be returned by server operations.

This should implement std::error::Error to provide proper error handling and error chain support.

Required Methods§

Source

fn launch( &self, listener: TcpListener, ) -> impl Future<Output = Result<(), Self::Error>> + Send

Launch the server using the provided TcpListener.

This method should start the web server and bind it to the given listener. The implementation should convert the std::net::TcpListener to a tokio::net::TcpListener for async compatibility.

§Arguments
  • listener - A TcpListener bound to a random port for testing
§Returns
  • Ok(()) - Server launched successfully
  • Err(Self::Error) - Server failed to launch
§Example
impl TestServer for MyServer {
    type Error = ServerError;

    async fn launch(&self, listener: TcpListener) -> Result<(), Self::Error> {
        listener.set_nonblocking(true).map_err(|_| ServerError)?;
        let tokio_listener = tokio::net::TcpListener::from_std(listener)
            .map_err(|_| ServerError)?;
         
        // Start your server here
        loop {
            if let Ok((stream, _)) = tokio_listener.accept().await {
                // Handle connection
            }
        }
    }
}

Provided Methods§

Source

fn is_healthy( &self, _client: &mut ApiClient, ) -> impl Future<Output = Result<HealthStatus, Self::Error>> + Send

Check if the server is healthy and ready to accept requests.

This method is called periodically during server startup to determine when the server is ready. The default implementation returns HealthStatus::Uncheckable, which triggers a TCP connection test.

§Arguments
  • client - An ApiClient configured for this test server
§Returns
  • Ok(HealthStatus::Healthy) - Server is healthy and ready
  • Ok(HealthStatus::Unhealthy) - Server is not healthy
  • Ok(HealthStatus::Uncheckable) - Use default TCP connection test
  • Err(Self::Error) - Error occurred during health check
§Example
impl TestServer for MyServer {
    async fn is_healthy(&self, client: &mut ApiClient) -> Result<HealthStatus, Self::Error> {
        // Try to make a health check request
        match client.get("/health").unwrap().await {
            Ok(_) => Ok(HealthStatus::Healthy),
            Err(_) => Ok(HealthStatus::Unhealthy),
        }
    }
}
Source

fn config(&self) -> TestServerConfig

Provide configuration for the test framework.

This method allows customizing the ApiClient and health check behavior for the specific server implementation.

§Returns

A TestServerConfig with custom settings, or default if not overridden.

§Example
impl TestServer for MyServer {
    fn config(&self) -> TestServerConfig {
        TestServerConfig {
            api_client: Some(
                ApiClient::builder()
                    .with_host("localhost")
                    .with_base_path("/api").unwrap()
            ),
            min_backoff_delay: Duration::from_millis(10),
            max_backoff_delay: Duration::from_secs(1),
            backoff_jitter: true,
            max_retry_attempts: 10,
        }
    }
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§