dita_v2(test): preserve indeterminate post-ack state
This commit is contained in:
@@ -29,6 +29,7 @@ from prod.clean_arch.dita_v2.contracts import (
|
|||||||
TradeStage,
|
TradeStage,
|
||||||
)
|
)
|
||||||
from prod.clean_arch.dita_v2.rust_backend import ExecutionKernel
|
from prod.clean_arch.dita_v2.rust_backend import ExecutionKernel
|
||||||
|
from prod.clean_arch.dita_v2.venue import VenuePostAckError
|
||||||
|
|
||||||
|
|
||||||
def _intent(*, trade_id: str = "post-ack-1") -> KernelIntent:
|
def _intent(*, trade_id: str = "post-ack-1") -> KernelIntent:
|
||||||
@@ -186,6 +187,58 @@ def test_async_kernel_does_not_roll_back_acknowledged_fill(monkeypatch):
|
|||||||
_assert_fill_trace(outcome.emitted_events)
|
_assert_fill_trace(outcome.emitted_events)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("submit_method", ["sync", "async"])
|
||||||
|
def test_adapter_types_post_ack_event_conversion_failure(monkeypatch, submit_method):
|
||||||
|
backend = _SyncBackend() if submit_method == "sync" else _AsyncBackend()
|
||||||
|
venue = _venue(backend)
|
||||||
|
monkeypatch.setattr(venue, "_publish_telemetry", lambda **_fields: None)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
venue,
|
||||||
|
"_events_from_submit",
|
||||||
|
lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("bad receipt")),
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(VenuePostAckError, match="post-ack failure") as captured:
|
||||||
|
if submit_method == "sync":
|
||||||
|
venue.submit(_intent(trade_id="sync-typed-post-ack"))
|
||||||
|
else:
|
||||||
|
asyncio.run(venue.submit_async(_intent(trade_id="async-typed-post-ack")))
|
||||||
|
|
||||||
|
assert backend.submit_count == 1
|
||||||
|
assert captured.value.receipt.order_id == "venue-order-1"
|
||||||
|
assert isinstance(captured.value.__cause__, ValueError)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("submit_method", ["sync", "async"])
|
||||||
|
def test_kernel_never_rolls_back_indeterminate_post_ack_outcome(monkeypatch, submit_method):
|
||||||
|
backend = _SyncBackend() if submit_method == "sync" else _AsyncBackend()
|
||||||
|
venue = _venue(backend)
|
||||||
|
monkeypatch.setattr(venue, "_publish_telemetry", lambda **_fields: None)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
venue,
|
||||||
|
"_events_from_submit",
|
||||||
|
lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("bad receipt")),
|
||||||
|
)
|
||||||
|
intent = _intent(trade_id=f"{submit_method}-kernel-indeterminate")
|
||||||
|
|
||||||
|
with ExecutionKernel(max_slots=1, venue=venue) as kernel:
|
||||||
|
if submit_method == "sync":
|
||||||
|
outcome = kernel.process_intent(intent)
|
||||||
|
else:
|
||||||
|
outcome = asyncio.run(kernel.process_intent_async(intent))
|
||||||
|
slot = kernel._get_slot(0)
|
||||||
|
|
||||||
|
assert outcome.accepted is True
|
||||||
|
assert outcome.emitted_events == []
|
||||||
|
assert slot.fsm_state is TradeStage.ENTRY_WORKING
|
||||||
|
assert slot.trade_id == intent.trade_id
|
||||||
|
assert slot.size == pytest.approx(0.0)
|
||||||
|
assert all(
|
||||||
|
event.kind is not KernelEventKind.ORDER_REJECT
|
||||||
|
for event in outcome.emitted_events
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_every_publish_telemetry_call_site_binds_to_live_signature():
|
def test_every_publish_telemetry_call_site_binds_to_live_signature():
|
||||||
"""Catch call/signature skew before any order path can execute it."""
|
"""Catch call/signature skew before any order path can execute it."""
|
||||||
source_path = Path(inspect.getsourcefile(BingxVenueAdapter) or "")
|
source_path = Path(inspect.getsourcefile(BingxVenueAdapter) or "")
|
||||||
|
|||||||
Reference in New Issue
Block a user