from __future__ import annotations from src.bootstrap.trade_stream_runtime import ( build_trade_stream_production_runtime, ) from src.core.config import Settings, TradeStreamSettings from src.market_data.acquisition.runtime.trade_stream_production_runtime import ( TradeStreamProductionRuntime, TradeStreamProductionRuntimeState, ) def make_settings( *, enabled: bool = True, api_key: str = "api-key", ) -> Settings: return Settings( bot_token="test-token", bot_parse_mode="HTML", app_env="test", log_level="INFO", tz="UTC", exchange_enabled=False, exchange_name="dzengi", exchange_base_url="https://rest.example.test/", exchange_ws_url="wss://legacy.example.test", exchange_api_key=api_key, exchange_api_secret="secret", exchange_timeout_sec=17, exchange_testnet=True, default_symbol="LEGACY", trade_stream=TradeStreamSettings( enabled=enabled, websocket_url="wss://stream.example.test/root", symbols=( "ETH/USD_LEVERAGE", "BTC/USD_LEVERAGE", ), open_timeout_seconds=11.0, probe_timeout_seconds=21.0, close_timeout_seconds=9.0, heartbeat_timeout_seconds=31.0, scheduler_interval_seconds=6.0, recovery_window_ms=123_456, ), db_host="localhost", db_port=5432, db_name="test", db_user="test", db_password="test", debug_enabled=False, journal_debug_enabled=False, ) def test_disabled_feature_does_not_build_runtime() -> None: settings = make_settings(enabled=False) assert build_trade_stream_production_runtime(settings) is None def test_builds_runtime_without_starting_lifecycle() -> None: runtime = build_trade_stream_production_runtime( make_settings(), ) assert isinstance(runtime, TradeStreamProductionRuntime) assert runtime.state is TradeStreamProductionRuntimeState.STOPPED assert runtime.running is False assert runtime._startup_task is None assert runtime._receive_task is None assert runtime._scheduler_task is None def test_uses_one_shared_stateful_dependency_graph() -> None: runtime = build_trade_stream_production_runtime( make_settings(), ) assert isinstance(runtime, TradeStreamProductionRuntime) transport = runtime._transport service = runtime._trade_stream_service reconnect_recovery = runtime._reconnect_recovery_coordinator recovery = reconnect_recovery._recovery_coordinator assert runtime._session._transport is transport assert runtime._subscription_manager._transport is transport assert runtime._runtime_scheduler.liveness_probe is transport assert ( service._consistency_controller is recovery._recovery_controller._consistency_controller ) assert runtime._live_processing_gate is ( reconnect_recovery.live_processing_gate ) assert runtime._runtime_scheduler.runtime_supervisor is ( runtime._runtime_supervisor ) def test_applies_explicit_transport_and_runtime_settings() -> None: settings = make_settings() runtime = build_trade_stream_production_runtime(settings) assert isinstance(runtime, TradeStreamProductionRuntime) transport = runtime._transport assert transport._url == "wss://stream.example.test/root/connect" assert transport._headers == { "Origin": "https://rest.example.test", "Content-Type": "application/json", "X-MBX-APIKEY": "api-key", } assert transport._open_timeout == 11.0 assert transport._probe_timeout == 21.0 assert transport._close_timeout == 9.0 assert transport._ping_interval is None assert transport._ping_timeout is None assert runtime._symbols == ( "BTC/USD_LEVERAGE", "ETH/USD_LEVERAGE", ) assert runtime._runtime_scheduler.interval_seconds == 6.0 assert ( runtime._runtime_supervisor._heartbeat_monitor.timeout_seconds == 31.0 ) assert ( runtime._reconnect_recovery_coordinator ._recovery_coordinator ._window_planner .max_window_ms == 123_456 ) def test_recovery_rest_client_reuses_settings_snapshot() -> None: settings = make_settings(api_key="") runtime = build_trade_stream_production_runtime(settings) assert isinstance(runtime, TradeStreamProductionRuntime) document_source = ( runtime._reconnect_recovery_coordinator ._recovery_coordinator ._recovery_controller ._document_source ) rest_client = document_source._client assert rest_client.settings is settings assert rest_client.base_url == "https://rest.example.test" assert rest_client.timeout == 17 assert "X-MBX-APIKEY" not in runtime._transport._headers