"""StreamQueue 原语单测(设计 §9.4):XADD/XREADGROUP/XACK,at-least-once。"""
import fakeredis.aioredis
import pytest
from openjiuwen_runtime.service.context.primitives.stream_queue import StreamQueue
@pytest.mark.unit
async def test_enqueue_consume_ack():
sq = StreamQueue(fakeredis.aioredis.FakeRedis(), prefix="svc")
await sq.enqueue("tasks", {"x": 1})
got = []
async for item in sq.consume("g1", "c1", stream="tasks", block=0):
got.append(item.data)
await item.ack()
break
assert got == [{"x": 1}]
@pytest.mark.unit
async def test_unacked_message_stays_pending():
sq = StreamQueue(fakeredis.aioredis.FakeRedis(), prefix="svc")
await sq.enqueue("tasks", {"x": 1})
async for item in sq.consume("g1", "c1", stream="tasks", block=0):
break
pending = await sq._redis.xpending("svc:tasks", "g1")
assert pending["pending"] == 1
@pytest.mark.unit
async def test_group_does_not_double_deliver_same_message():
sq = StreamQueue(fakeredis.aioredis.FakeRedis(), prefix="svc")
await sq.enqueue("tasks", {"x": 1})
taken = []
async for item in sq.consume("g1", "c1", stream="tasks", block=0, count=1):
taken.append(item.data)
await item.ack()
break
async for item in sq.consume("g1", "c2", stream="tasks", block=0, count=1):
pytest.fail("同组已 ack 的消息不应再投给 c2")
assert taken == [{"x": 1}]
@pytest.mark.unit
async def test_ack_makes_message_not_redelivered():
sq = StreamQueue(fakeredis.aioredis.FakeRedis(), prefix="svc")
await sq.enqueue("tasks", {"x": 1})
async for item in sq.consume("g1", "c1", stream="tasks", block=0):
await item.ack()
break
redelivered = []
async for item in sq.consume("g1", "c1", stream="tasks", block=0):
redelivered.append(item.data)
break
assert redelivered == []