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§
Required Methods§
Sourcefn launch(
&self,
listener: TcpListener,
) -> impl Future<Output = Result<(), Self::Error>> + Send
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 successfullyErr(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§
Sourcefn is_healthy(
&self,
_client: &mut ApiClient,
) -> impl Future<Output = Result<HealthStatus, Self::Error>> + Send
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 readyOk(HealthStatus::Unhealthy)
- Server is not healthyOk(HealthStatus::Uncheckable)
- Use default TCP connection testErr(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),
}
}
}
Sourcefn config(&self) -> TestServerConfig
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.