1#![forbid(unsafe_code)]
21
22mod auth;
23
24pub mod app;
25pub mod handlers;
26pub mod state;
27
28use tokio::{net::TcpListener, task::JoinHandle};
29
30pub use app::{build_app, build_app_from_env, build_app_with_state};
31pub use state::{
32 AdminStateResponse, DEFAULT_STOCK_SYMBOL, InjectedHttpFault, InstrumentSnapshot,
33 LiveMarketDataBridge, MarketDataBridgeError, MockServerState,
34};
35
36pub const BINARY_NAME: &str = "alpaca-mock";
37
38#[derive(Debug)]
39pub struct TestServer {
40 pub base_url: String,
41 _task: JoinHandle<()>,
42}
43
44pub async fn spawn_test_server() -> TestServer {
45 spawn_test_server_with_state(MockServerState::new()).await
46}
47
48pub async fn spawn_test_server_with_state(state: MockServerState) -> TestServer {
49 let listener = TcpListener::bind("127.0.0.1:0")
50 .await
51 .expect("listener should bind");
52 let address = listener.local_addr().expect("local addr should exist");
53 let app = build_app_with_state(state);
54
55 let task = tokio::spawn(async move {
56 axum::serve(listener, app).await.expect("server should run");
57 });
58
59 TestServer {
60 base_url: format!("http://{address}"),
61 _task: task,
62 }
63}