fix(cli): verify 명령 ImportError 핫픽스 — make_broker→_build_broker

운영 배포 스모크(REL-010 STEP2)서 trex-core verify가 ImportError(make_broker 부재)로 실패.
_cmd_verify가 존재하지 않는 trex_core.adapters.broker.make_broker를 import하던 것을
_cmd_sync와 동일한 trex_core.runtime.daemon._build_broker로 교체. 회귀 테스트 2개 추가.
747 passed/회귀 0. CLI 전용, trading/wire 무관.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-06-30 13:30:07 +09:00
co-authored by Claude Opus 4.8
parent ababf80234
commit 51cc3ccb09
2 changed files with 61 additions and 2 deletions
+59
View File
@@ -441,3 +441,62 @@ def test_verify_no_db_no_live_flag_needed(capsys, monkeypatch):
monkeypatch.setattr(cli, "_cmd_verify", _fake_verify) monkeypatch.setattr(cli, "_cmd_verify", _fake_verify)
rc = cli.main(["verify"]) rc = cli.main(["verify"])
assert rc == 0 assert rc == 0
# ---------------------------------------------------------------------------
# REL-010 regression: _cmd_verify broker import must not raise ImportError
# ---------------------------------------------------------------------------
def test_verify_cmd_broker_import_does_not_raise(monkeypatch):
"""REL-010 regression: _cmd_verify must use _build_broker (not missing
make_broker) so it does not raise ImportError at the broker-build step.
Patch all DB/network calls so only the import path is exercised.
Paper broker config is used (no real network needed).
"""
from trex_core.runtime.config import DaemonConfig
from trex_core.adapters.broker.paper import PaperBroker
cfg = DaemonConfig(
dsn="postgresql://x/y",
broker="paper",
execution_interval_sec=1.0,
instance_key="test",
)
# Patch at module level — _cmd_verify uses local `from ... import` so we
# must patch the source module, not the cli namespace.
from trex_core.application.portfolio import InMemoryReconcileWarningStore
from trex_core.domain.slot.in_memory_repository import InMemorySlotRepository
import trex_core.adapters.portfolio.reconcile_warning_store as rws_mod
import trex_core.adapters.persistence.postgresql as pg_mod
monkeypatch.setattr(rws_mod, "PostgreSQLReconcileWarningStore",
lambda dsn: InMemoryReconcileWarningStore())
monkeypatch.setattr(pg_mod, "PostgreSQLSlotRepository",
lambda dsn: InMemorySlotRepository())
# Build args object with no portfolio_id (triggers "no C-warned slots" path).
import argparse
args = argparse.Namespace(
instance=None,
portfolio_id=None,
json=False,
)
# Must not raise ImportError — this is the regression guard.
rc = cli._cmd_verify(args, cfg)
# With no C-warned slots and paper broker the function returns 0.
assert rc == 0
def test_verify_cmd_uses_build_broker_not_make_broker():
"""Structural check: trex_core.adapters.broker has no 'make_broker' symbol.
This ensures the ImportError from REL-010 is permanently absent.
"""
import trex_core.adapters.broker as broker_pkg
assert not hasattr(broker_pkg, "make_broker"), (
"make_broker must not exist in trex_core.adapters.broker — "
"use _build_broker from trex_core.runtime.daemon instead"
)
+2 -2
View File
@@ -582,8 +582,8 @@ def _cmd_verify(args, cfg) -> int:
warn_store = PostgreSQLReconcileWarningStore(cfg.dsn) warn_store = PostgreSQLReconcileWarningStore(cfg.dsn)
slot_repo = PostgreSQLSlotRepository(cfg.dsn) slot_repo = PostgreSQLSlotRepository(cfg.dsn)
from trex_core.adapters.broker import make_broker from trex_core.runtime.daemon import _build_broker
broker_port = make_broker(cfg) broker_port = _build_broker(cfg)
# Build a minimal snapshot store (we only need asset_quantity for C-case check). # Build a minimal snapshot store (we only need asset_quantity for C-case check).
# For verify we use a fresh SnapshotStore populated from warn_store metadata. # For verify we use a fresh SnapshotStore populated from warn_store metadata.