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:
co-authored by
genichin
parent
f0ac909958
commit
65df10542b
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user