"""DaemonConfig .env loading tests (REQ-010).""" from __future__ import annotations import pytest from trex_core.runtime.config import DaemonConfig _KEYS = ( "TREX_POSTGRESQL_DSN", "TREX_EXECUTION_INTERVAL_SEC", "TREX_API_HOST", "TREX_API_PORT", "TREX_PAPER_FILL_AFTER_POLLS", "TREX_PAPER_QTY_PER_POLL", "TREX_PAPER_REJECT_SYMBOLS", ) @pytest.fixture(autouse=True) def _clean_env(monkeypatch): for k in _KEYS: monkeypatch.delenv(k, raising=False) def test_loads_values_from_dotenv(tmp_path, monkeypatch): """AC-1: .env in CWD is loaded when the OS env var is unset.""" (tmp_path / ".env").write_text( "TREX_POSTGRESQL_DSN=dbname=from_dotenv\nTREX_EXECUTION_INTERVAL_SEC=7.0\n" ) monkeypatch.chdir(tmp_path) cfg = DaemonConfig.from_env() assert cfg.dsn == "dbname=from_dotenv" assert cfg.execution_interval_sec == 7.0 def test_os_env_takes_precedence_over_dotenv(tmp_path, monkeypatch): """AC-2: real OS env wins over .env (override=False).""" (tmp_path / ".env").write_text("TREX_POSTGRESQL_DSN=dbname=from_dotenv\n") monkeypatch.chdir(tmp_path) monkeypatch.setenv("TREX_POSTGRESQL_DSN", "dbname=from_os_env") cfg = DaemonConfig.from_env() assert cfg.dsn == "dbname=from_os_env" def test_no_dotenv_uses_os_env_only(tmp_path, monkeypatch): """AC-3: with no .env, behaviour is unchanged (os.environ only).""" monkeypatch.chdir(tmp_path) # empty dir, no .env monkeypatch.setenv("TREX_POSTGRESQL_DSN", "dbname=os_only") cfg = DaemonConfig.from_env() assert cfg.dsn == "dbname=os_only" assert cfg.execution_interval_sec == 1.0 # default def test_missing_dsn_raises(tmp_path, monkeypatch): """No .env and no env var -> required DSN error (regression guard).""" monkeypatch.chdir(tmp_path) with pytest.raises(RuntimeError): DaemonConfig.from_env() def test_paper_broker_defaults(tmp_path, monkeypatch): """Unset paper env == immediate full fills, no rejects (REQ-011).""" monkeypatch.chdir(tmp_path) monkeypatch.setenv("TREX_POSTGRESQL_DSN", "dbname=x") cfg = DaemonConfig.from_env() assert cfg.paper.fill_after_polls == 0 assert cfg.paper.qty_per_poll is None assert cfg.paper.reject_symbols == frozenset() def test_paper_broker_env_tuning(tmp_path, monkeypatch): """Paper broker scenario knobs are parsed from env (REQ-011).""" monkeypatch.chdir(tmp_path) monkeypatch.setenv("TREX_POSTGRESQL_DSN", "dbname=x") monkeypatch.setenv("TREX_PAPER_FILL_AFTER_POLLS", "2") monkeypatch.setenv("TREX_PAPER_QTY_PER_POLL", "4") monkeypatch.setenv("TREX_PAPER_REJECT_SYMBOLS", "005930, 000660 ,") cfg = DaemonConfig.from_env() assert cfg.paper.fill_after_polls == 2 assert cfg.paper.qty_per_poll == 4 assert cfg.paper.reject_symbols == frozenset({"005930", "000660"})