Deliver BAT-003: daemon .env loading (REQ-010, minor-change)
DaemonConfig.from_env() now best-effort loads a .env file (find_dotenv usecwd, load_dotenv override=False) so operators can manage daemon env vars via .env, with real OS env taking precedence. Add python-dotenv dependency, gitignore .env, ship .env.example, and add config tests (load / OS-env precedence / absence regression / missing-DSN guard). Verification: 78 passed, ruff clean, .env ignored + .env.example tracked, and a .env-only DaemonConfig smoke. Processed via the minor-change fast path: REQ-010 (Configuration) -> Implemented, BAT-003 (batch-lite, no design) -> release-candidate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""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")
|
||||
|
||||
|
||||
@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()
|
||||
Reference in New Issue
Block a user