Files
trex-core/tests/runtime/test_config_dotenv.py
T
genichinandClaude Opus 4.8 2f57aad7b2 feat(config): expose paper broker tuning via env (REQ-010 AC-5, BAT-009)
Wire the existing PaperBroker scenario knobs (fill_after_polls /
qty_per_poll / reject_symbols) to daemon env so REQ-011 AC-2 e2e
scenarios (delayed / partial / reject) can be reproduced by a daemon
restart. Unset == prior PaperBroker() behaviour, byte-for-byte (no
regression).

- config.py: PaperBrokerConfig + from_env parsing (TREX_PAPER_*)
- daemon.py: _build_broker injects config.paper into PaperBroker
- .env.example: document the 3 paper tuning keys (paper-only, e2e)
- tests: paper broker defaults + env tuning parsing

SDLC: REQ-010 CHG-20260606-01 (AC-5 added) / -02 (Implemented);
BAT-009 batch-lite release-candidate; REL-001 feedback handoff records
pre-deployment e2e observations incl. event-publisher idle-drop and
paper correlation_id collision (GitHub #4, #5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:49:51 +09:00

78 lines
2.8 KiB
Python

"""DaemonConfig .env loading tests (REQ-010)."""
from __future__ import annotations
import pytest
from trex_core.runtime.config import DaemonConfig
_KEYS = (
"TREX_POSTGRESQL_DSN", "TREX_TOTAL_SLOTS", "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_TOTAL_SLOTS=7\n"
)
monkeypatch.chdir(tmp_path)
cfg = DaemonConfig.from_env()
assert cfg.dsn == "dbname=from_dotenv"
assert cfg.total_slots == 7
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.total_slots == 10 # 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"})