test: make context-failure regressions deterministic and simplify alarm log handling

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-08-26 05:07:35 +00:00
committed by GitHub
co-authored by genichin
parent 1ca9e60c98
commit 75406af970
2 changed files with 22 additions and 19 deletions
@@ -101,22 +101,29 @@ class DuplicateInFlightIntentStore:
raise AssertionError("finalize must not be called for duplicate_in_flight")
class ContextFailingSlotRepository(InMemorySlotRepository):
"""Raise only on the N+1th fetch_slot to simulate post-finalize lookup failure."""
class PostFinalizeContextFailingSlotRepository(InMemorySlotRepository):
"""Raise fetch_slot only after explicitly armed by finalize."""
def __init__(self, *, fail_on_fetch_call_no=None):
def __init__(self):
super().__init__()
self._fetch_calls = 0
self._fail_on_fetch_call_no = fail_on_fetch_call_no
self._raise_on_fetch = False
def fetch_slot(self, slot_id):
self._fetch_calls += 1
if self._fail_on_fetch_call_no == self._fetch_calls:
if self._raise_on_fetch:
raise RuntimeError("context lookup failed")
return super().fetch_slot(slot_id)
def fail_on_next_fetch(self):
self._fail_on_fetch_call_no = self._fetch_calls + 1
class FinalizeArmingIntentStore(InMemoryIntentStore):
"""Arm repo fetch failure immediately after finalize persistence."""
def __init__(self, repo):
super().__init__()
self._repo = repo
def finalize(self, intent_id, status, slot_id, reason):
super().finalize(intent_id, status, slot_id, reason)
self._repo._raise_on_fetch = True
def _make_holding_slot(repo, svc, instance_key="default", portfolio_id="pf-A", symbol="005930", qty=10):
@@ -531,10 +538,10 @@ def test_reconcile_warned_alarm_finalize_failure_and_publish_failure_are_isolate
def test_reconcile_warned_buy_context_lookup_failure_does_not_change_response():
repo = ContextFailingSlotRepository(fail_on_fetch_call_no=2)
repo = PostFinalizeContextFailingSlotRepository()
svc = SlotService(repo)
warn_store = InMemoryReconcileWarningStore()
intent_store = InMemoryIntentStore()
intent_store = FinalizeArmingIntentStore(repo)
alarms = RecordingAlarmEmitter()
repo.reconcile_universe("default", {"pf-A": "005930"})
slot = repo.find_slot_by_portfolio("default", "pf-A")
@@ -558,13 +565,12 @@ def test_reconcile_warned_buy_context_lookup_failure_does_not_change_response():
def test_reconcile_warned_sell_context_lookup_failure_does_not_change_response():
repo = ContextFailingSlotRepository()
repo = PostFinalizeContextFailingSlotRepository()
svc = SlotService(repo)
warn_store = InMemoryReconcileWarningStore()
intent_store = InMemoryIntentStore()
intent_store = FinalizeArmingIntentStore(repo)
alarms = RecordingAlarmEmitter()
slot = _make_holding_slot(repo, svc, qty=10, portfolio_id="pf-A", symbol="005930")
repo._fail_on_fetch_call_no = repo._fetch_calls + 2
warn_store.set_warned(str(slot.slot_id), portfolio_id="pf-A", case_code="C")
intent_svc = IntentService(
svc, repo, intent_store, instance_key="default", warn_store=warn_store, alarm_emitter=alarms