Files
app/backend/tests/flow/test_redis_queue.py
T
stroblme 75b3a93094
Docs / docs (push) Successful in 33s
Playwright Tests / test-playwright (1, 2) (push) Failing after 1m37s
Playwright Tests / test-playwright (2, 2) (push) Failing after 27s
pre-commit / pre-commit (push) Failing after 2m37s
Test Backend / test-backend (3.12) (push) Successful in 5m7s
Test Backend / test-backend (3.14) (push) Successful in 5m2s
Compose Smoke Test / test-compose (push) Failing after 28s
Playwright Tests / merge-reports (push) Failing after 2m29s
Fix work recovery and reduce engine and chart overhead
2026-10-29 14:24:17 +01:00

69 lines
2.3 KiB
Python

"""Redis delivery checks, enabled by FLUKSIO_TEST_REDIS_HOST (and optional PORT)."""
import os
import uuid
from concurrent.futures import ThreadPoolExecutor
import pytest
import redis
from fluksio.flow.queue import RedisWorkQueue, WorkItem
@pytest.fixture
def queue():
host = os.environ.get("FLUKSIO_TEST_REDIS_HOST")
if not host:
pytest.skip("Set FLUKSIO_TEST_REDIS_HOST to run Redis integration checks")
queue = RedisWorkQueue(
host=host,
port=int(os.environ.get("FLUKSIO_TEST_REDIS_PORT", "6379")),
namespace=f"test-queue-{uuid.uuid4().hex}",
)
try:
yield queue
finally:
keys = list(queue._redis.scan_iter(match=f"{queue._ns}:*"))
if keys:
queue._redis.delete(*keys)
queue.close()
def test_concurrent_promotions_deliver_each_due_item_once(queue):
for i in range(150):
queue.add_delayed(
WorkItem(kind="cascade", node=f"f.n{i}", flow="f", outputs={"f.x": i}),
100.0,
)
queue.add_delayed(WorkItem(kind="cascade", node="f.later", flow="f"), 300.0)
with ThreadPoolExecutor(max_workers=2) as pool:
moved = list(pool.map(queue.move_due, [200.0, 200.0]))
assert sorted(moved) == [50, 100]
assert queue.move_due(200.0) == 0
assert queue.next_due() == 300.0
claimed = queue.claim(200, 10, due_only=True)
assert len(claimed) == 150
assert {item.outputs["f.x"] for item in claimed} == set(range(150))
assert all(item.not_before == 100.0 for item in claimed)
assert all(item.entry_id.startswith("due:") for item in claimed)
def test_a_refused_stream_write_keeps_the_timer_for_retry(queue):
queue.add_delayed(WorkItem(kind="cascade", node="f.stop", flow="f"), 100.0)
# A Redis command error does not roll a Lua script back. The stream write
# must succeed before the delayed entry is removed.
queue._redis.delete(queue._due_stream)
queue._redis.set(queue._due_stream, "not a stream")
with pytest.raises(redis.ResponseError, match="WRONGTYPE"):
queue.move_due(200.0)
assert queue.next_due() == 100.0
queue._redis.delete(queue._due_stream)
queue._ensure_group()
assert queue.move_due(200.0) == 1
assert queue.move_due(200.0) == 0
assert [item.node for item in queue.claim(10, 10, due_only=True)] == ["f.stop"]