fix(execution): KIS child cancel identity binding, sanitized logging, PG cancel SQL tests

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-09-01 12:06:45 +00:00
committed by GitHub
co-authored by genichin
parent f0ac909958
commit 65df10542b
5 changed files with 331 additions and 31 deletions
@@ -2,6 +2,8 @@
Skipped without TREX_POSTGRESQL_TEST_DSN."""
from __future__ import annotations
from datetime import UTC, datetime, timedelta
from trex_core.adapters.persistence.in_memory_intent_store import InMemoryIntentStore # noqa: F401
from trex_core.adapters.persistence.postgresql import (
PostgreSQLIntentStore,
@@ -244,3 +246,80 @@ def test_strategy_state_write_cannot_follow_close(pg_clean):
result = store.set(slot.slot_id, "instance", expected_version=1, data="after", slot_active=True)
assert not result.ok and result.reason == "slot_inactive"
assert store.get_for_slots([slot.slot_id])[slot.slot_id]["instance"].data == "before"
# ── Regression: reserve_cancel_attempt() SQL paths (issue #81 Fix A) ─────────
# These tests exercise the real PostgreSQL code path that previously failed with
# IndeterminateDatatype when retry_before=None was bound to %s IS NOT NULL.
def test_reserve_cancel_first_attempt_retry_before_none_pg(pg_clean):
"""First reservation with retry_before=None must succeed exactly once."""
repo, _, intents = _wire(pg_clean)
repo.reconcile_universe(INST, {"PF-1": "005930"})
d = intents.submit_buy(BuyIntent(intent_id="pg-can-first", qty=1, portfolio_id="PF-1"))
repo.mark_dispatched(d.slot_id, "ord-first")
# First reservation: retry_before=None — must not raise IndeterminateDatatype
assert repo.reserve_cancel_attempt(d.slot_id, "ord-first") is True
slot = repo.fetch_slot(d.slot_id)
assert slot.cancel_state == "unknown"
assert slot.cancel_attempts == 1
assert slot.cancel_requested_at is not None
# Duplicate CAS must be rejected (cancel_state is no longer NULL)
assert repo.reserve_cancel_attempt(d.slot_id, "ord-first") is False
assert repo.fetch_slot(d.slot_id).cancel_attempts == 1 # not incremented
def test_reserve_cancel_retry_backoff_gated_pg(pg_clean):
"""Retry path with retry_before is accepted when backoff window passes."""
import psycopg
repo, _, intents = _wire(pg_clean)
repo.reconcile_universe(INST, {"PF-1": "005930"})
d = intents.submit_buy(BuyIntent(intent_id="pg-can-retry", qty=1, portfolio_id="PF-1"))
repo.mark_dispatched(d.slot_id, "ord-retry")
# Simulate a previous cancel attempt that left state=rejected a while ago
past = datetime.now(tz=UTC) - timedelta(seconds=60)
with psycopg.connect(pg_clean, autocommit=False) as conn:
with conn.cursor() as cur:
cur.execute(
"UPDATE daily_slot SET cancel_state='rejected', cancel_requested_at=%s, "
"cancel_attempts=1 WHERE slot_id=%s",
(past, d.slot_id),
)
conn.commit()
# retry_before = now means backoff window has elapsed
retry_before = datetime.now(tz=UTC)
assert repo.reserve_cancel_attempt(d.slot_id, "ord-retry", retry_before=retry_before) is True
slot = repo.fetch_slot(d.slot_id)
assert slot.cancel_state == "unknown"
assert slot.cancel_attempts == 2
def test_reserve_cancel_retry_max_attempts_blocked_pg(pg_clean):
"""Retry is rejected when cancel_attempts >= 4."""
import psycopg
repo, _, intents = _wire(pg_clean)
repo.reconcile_universe(INST, {"PF-1": "005930"})
d = intents.submit_buy(BuyIntent(intent_id="pg-can-max", qty=1, portfolio_id="PF-1"))
repo.mark_dispatched(d.slot_id, "ord-max")
past = datetime.now(tz=UTC) - timedelta(seconds=120)
with psycopg.connect(pg_clean, autocommit=False) as conn:
with conn.cursor() as cur:
cur.execute(
"UPDATE daily_slot SET cancel_state='rejected', cancel_requested_at=%s, "
"cancel_attempts=4 WHERE slot_id=%s",
(past, d.slot_id),
)
conn.commit()
retry_before = datetime.now(tz=UTC)
assert repo.reserve_cancel_attempt(d.slot_id, "ord-max", retry_before=retry_before) is False
assert repo.fetch_slot(d.slot_id).cancel_attempts == 4 # unchanged