96 lines
2.9 KiB
Python
96 lines
2.9 KiB
Python
"""Strategy RPC responses never expose broker retryability (GitHub #60)."""
|
|
from __future__ import annotations
|
|
|
|
from uuid import uuid4
|
|
|
|
from trex_core.adapters.persistence.in_memory_intent_store import InMemoryIntentStore
|
|
from trex_core.application.intents import IntentService
|
|
from trex_core.application.messaging import RpcRequest
|
|
from trex_core.application.messaging_handlers import make_intent_rpc_handler
|
|
from trex_core.domain.slot import SlotService, SlotState
|
|
from trex_core.domain.slot.in_memory_repository import InMemorySlotRepository
|
|
|
|
INST = "default"
|
|
|
|
|
|
def _wire():
|
|
repo = InMemorySlotRepository()
|
|
svc = SlotService(repo, instance_key=INST)
|
|
intents = IntentService(
|
|
svc,
|
|
repo,
|
|
InMemoryIntentStore(),
|
|
resolve_symbol=lambda pid: "005930",
|
|
instance_key=INST,
|
|
max_active_slots=5,
|
|
)
|
|
repo.reconcile_universe(INST, {"PF-1": "SYM"})
|
|
handler = make_intent_rpc_handler(intents)
|
|
slot = repo.list_slots(INST)[0]
|
|
return repo, svc, intents, handler, slot
|
|
|
|
|
|
def _sell(handler, slot_id, intent_id="s1"):
|
|
return handler(
|
|
RpcRequest(
|
|
payload={
|
|
"intent_type": "sell",
|
|
"intent_id": intent_id,
|
|
"slot_id": str(slot_id),
|
|
},
|
|
correlation_id=intent_id,
|
|
)
|
|
)
|
|
|
|
|
|
def test_rejected_sell_does_not_expose_retryability():
|
|
_, _, _, handler, slot = _wire()
|
|
response = _sell(handler, slot.slot_id)
|
|
assert response.payload["status"] == "rejected"
|
|
assert response.payload["reason"] == "slot_not_holding:inactive"
|
|
assert "retryable" not in response.payload
|
|
|
|
|
|
def test_unknown_slot_sell_does_not_expose_retryability():
|
|
_, _, _, handler, _ = _wire()
|
|
response = _sell(handler, uuid4())
|
|
assert response.payload["status"] == "rejected"
|
|
assert response.payload["reason"] == "slot_not_found"
|
|
assert "retryable" not in response.payload
|
|
|
|
|
|
def test_malformed_sell_does_not_expose_retryability():
|
|
_, _, _, handler, _ = _wire()
|
|
response = handler(
|
|
RpcRequest(
|
|
payload={"intent_type": "sell", "intent_id": "x"},
|
|
correlation_id="x",
|
|
)
|
|
)
|
|
assert response.payload["status"] == "rejected"
|
|
assert response.payload["reason"].startswith("bad_request")
|
|
assert "retryable" not in response.payload
|
|
|
|
|
|
def test_admitted_sell_does_not_expose_retryability():
|
|
_, svc, _, handler, slot = _wire()
|
|
svc.transit_slot(
|
|
slot.slot_id,
|
|
SlotState.INACTIVE,
|
|
SlotState.PENDING_BUY,
|
|
reason="buy",
|
|
actor="test",
|
|
)
|
|
svc.transit_slot(
|
|
slot.slot_id,
|
|
SlotState.PENDING_BUY,
|
|
SlotState.HOLDING,
|
|
reason="filled",
|
|
actor="test",
|
|
qty=10,
|
|
avg_price=100,
|
|
)
|
|
response = _sell(handler, slot.slot_id)
|
|
assert response.payload["status"] == "admitted"
|
|
assert "retryable" not in response.payload
|