test: validate ledger backfill flow
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
e2c4bbba34
commit
3e74d35299
@@ -1,7 +1,7 @@
|
|||||||
"""LedgerOutbox + LedgerWriter direct unit tests (REQ-019)."""
|
"""LedgerOutbox + LedgerWriter direct unit tests (REQ-019)."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import UTC, datetime, timedelta
|
||||||
|
|
||||||
from trex_core.adapters.ledger.in_memory import InMemoryLedger
|
from trex_core.adapters.ledger.in_memory import InMemoryLedger
|
||||||
from trex_core.application.ledger_outbox import (
|
from trex_core.application.ledger_outbox import (
|
||||||
@@ -17,7 +17,7 @@ def _trade(execution_id="paper:PAPER-1:10") -> LedgerTrade:
|
|||||||
return LedgerTrade(
|
return LedgerTrade(
|
||||||
asset_id="PF-1", order_id="PAPER-1", execution_id=execution_id,
|
asset_id="PF-1", order_id="PAPER-1", execution_id=execution_id,
|
||||||
side="buy", qty=10, price=1000.0,
|
side="buy", qty=10, price=1000.0,
|
||||||
executed_at=datetime(2026, 6, 4, tzinfo=timezone.utc),
|
executed_at=datetime(2026, 6, 4, tzinfo=UTC),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ def test_writer_marks_conflict_blocked_and_does_not_retry():
|
|||||||
def test_writer_retries_until_success():
|
def test_writer_retries_until_success():
|
||||||
# dcy-015: retryable rows now back off; share an injected clock between the
|
# dcy-015: retryable rows now back off; share an injected clock between the
|
||||||
# outbox (list_pending "now") and the writer (next_retry_at) to advance past it.
|
# outbox (list_pending "now") and the writer (next_retry_at) to advance past it.
|
||||||
now = {"t": datetime(2026, 6, 4, tzinfo=timezone.utc)}
|
now = {"t": datetime(2026, 6, 4, tzinfo=UTC)}
|
||||||
outbox = InMemoryLedgerOutbox(clock=lambda: now["t"])
|
outbox = InMemoryLedgerOutbox(clock=lambda: now["t"])
|
||||||
ledger = InMemoryLedger(fail_n_then_succeed=1)
|
ledger = InMemoryLedger(fail_n_then_succeed=1)
|
||||||
writer = LedgerWriter(outbox, ledger, clock=lambda: now["t"])
|
writer = LedgerWriter(outbox, ledger, clock=lambda: now["t"])
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ def test_ledger_backfill_existing_completed_row_is_idempotent(monkeypatch, tmp_p
|
|||||||
def process_correlation_id(self, correlation_id):
|
def process_correlation_id(self, correlation_id):
|
||||||
raise AssertionError("completed execution must not be re-processed")
|
raise AssertionError("completed execution must not be re-processed")
|
||||||
|
|
||||||
import trex_core.adapters.persistence.postgresql as pg_mod
|
|
||||||
import trex_core.adapters.ledger.portfolio_hub as hub_mod
|
import trex_core.adapters.ledger.portfolio_hub as hub_mod
|
||||||
|
import trex_core.adapters.persistence.postgresql as pg_mod
|
||||||
|
|
||||||
monkeypatch.setattr(pg_mod, "PostgreSQLLedgerOutbox", lambda dsn: _Outbox())
|
monkeypatch.setattr(pg_mod, "PostgreSQLLedgerOutbox", lambda dsn: _Outbox())
|
||||||
monkeypatch.setattr(hub_mod, "PortfolioHubLedger", lambda *args, **kwargs: object())
|
monkeypatch.setattr(hub_mod, "PortfolioHubLedger", lambda *args, **kwargs: object())
|
||||||
@@ -195,8 +195,8 @@ def test_ledger_backfill_live_enqueue_and_processes_exact_trade(monkeypatch, tmp
|
|||||||
assert correlation_id == self.seen_outbox.trade.correlation_id
|
assert correlation_id == self.seen_outbox.trade.correlation_id
|
||||||
return OutboxOutcome.COMPLETED
|
return OutboxOutcome.COMPLETED
|
||||||
|
|
||||||
import trex_core.adapters.persistence.postgresql as pg_mod
|
|
||||||
import trex_core.adapters.ledger.portfolio_hub as hub_mod
|
import trex_core.adapters.ledger.portfolio_hub as hub_mod
|
||||||
|
import trex_core.adapters.persistence.postgresql as pg_mod
|
||||||
|
|
||||||
monkeypatch.setattr(pg_mod, "PostgreSQLLedgerOutbox", lambda dsn: outbox)
|
monkeypatch.setattr(pg_mod, "PostgreSQLLedgerOutbox", lambda dsn: outbox)
|
||||||
monkeypatch.setattr(hub_mod, "PortfolioHubLedger", lambda *args, **kwargs: object())
|
monkeypatch.setattr(hub_mod, "PortfolioHubLedger", lambda *args, **kwargs: object())
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import json as _json
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
from pathlib import Path
|
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from pathlib import Path
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from trex_core.adapters.messaging import topology
|
from trex_core.adapters.messaging import topology
|
||||||
@@ -394,7 +394,8 @@ def _write_ledger_backfill_audit(args, report: dict) -> str:
|
|||||||
|
|
||||||
def _lookup_ledger_backfill_evidence(cfg: DaemonConfig, *, trading_date: str, execution_id: str):
|
def _lookup_ledger_backfill_evidence(cfg: DaemonConfig, *, trading_date: str, execution_id: str):
|
||||||
from trex_core.runtime.broker_provider import (
|
from trex_core.runtime.broker_provider import (
|
||||||
BrokerCredentialUnavailable, build_broker_provider,
|
BrokerCredentialUnavailable,
|
||||||
|
build_broker_provider,
|
||||||
)
|
)
|
||||||
|
|
||||||
broker, source = build_broker_provider(cfg).get_broker_for_read()
|
broker, source = build_broker_provider(cfg).get_broker_for_read()
|
||||||
@@ -664,10 +665,11 @@ def _cmd_sync(args, cfg, confirm) -> int:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
# REQ-119/120: resolve and validate broker truth before opening/enumerating DB.
|
# REQ-119/120: resolve and validate broker truth before opening/enumerating DB.
|
||||||
from trex_core.runtime.broker_provider import (
|
|
||||||
BrokerCredentialUnavailable, build_broker_provider,
|
|
||||||
)
|
|
||||||
from trex_core.application.broker_port import BrokerBalanceError
|
from trex_core.application.broker_port import BrokerBalanceError
|
||||||
|
from trex_core.runtime.broker_provider import (
|
||||||
|
BrokerCredentialUnavailable,
|
||||||
|
build_broker_provider,
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
broker_port, _source = build_broker_provider(cfg).get_broker_for_read()
|
broker_port, _source = build_broker_provider(cfg).get_broker_for_read()
|
||||||
broker_port = _CachedBalanceBroker(broker_port, broker_port.get_balance())
|
broker_port = _CachedBalanceBroker(broker_port, broker_port.get_balance())
|
||||||
@@ -787,10 +789,11 @@ def _cmd_verify(args, cfg) -> int:
|
|||||||
|
|
||||||
instance = _resolve_instance(args)
|
instance = _resolve_instance(args)
|
||||||
# REQ-120 no-write/no-enumeration barrier also applies to verify.
|
# REQ-120 no-write/no-enumeration barrier also applies to verify.
|
||||||
from trex_core.runtime.broker_provider import (
|
|
||||||
BrokerCredentialUnavailable, build_broker_provider,
|
|
||||||
)
|
|
||||||
from trex_core.application.broker_port import BrokerBalanceError
|
from trex_core.application.broker_port import BrokerBalanceError
|
||||||
|
from trex_core.runtime.broker_provider import (
|
||||||
|
BrokerCredentialUnavailable,
|
||||||
|
build_broker_provider,
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
broker_port, _source = build_broker_provider(cfg).get_broker_for_read()
|
broker_port, _source = build_broker_provider(cfg).get_broker_for_read()
|
||||||
broker_port = _CachedBalanceBroker(broker_port, broker_port.get_balance())
|
broker_port = _CachedBalanceBroker(broker_port, broker_port.get_balance())
|
||||||
@@ -987,9 +990,9 @@ def _cmd_report(args, cfg) -> int:
|
|||||||
|
|
||||||
|
|
||||||
def _cmd_ledger_backfill(args, cfg, confirm) -> int:
|
def _cmd_ledger_backfill(args, cfg, confirm) -> int:
|
||||||
|
from trex_core.adapters.broker.kis import KISEvidenceLookupError
|
||||||
from trex_core.adapters.ledger.portfolio_hub import PortfolioHubLedger
|
from trex_core.adapters.ledger.portfolio_hub import PortfolioHubLedger
|
||||||
from trex_core.adapters.persistence.postgresql import PostgreSQLLedgerOutbox
|
from trex_core.adapters.persistence.postgresql import PostgreSQLLedgerOutbox
|
||||||
from trex_core.adapters.broker.kis import KISEvidenceLookupError
|
|
||||||
from trex_core.runtime.broker_provider import BrokerCredentialUnavailable
|
from trex_core.runtime.broker_provider import BrokerCredentialUnavailable
|
||||||
|
|
||||||
instance = _resolve_instance(args)
|
instance = _resolve_instance(args)
|
||||||
|
|||||||
Reference in New Issue
Block a user