test: add edge case coverage for key fields, default TTL, and task lifecycle (#10)

This commit is contained in:
d3vyce
2026-05-03 17:17:49 +02:00
committed by GitHub
parent 3af968581d
commit 446071924e
+73
View File
@@ -94,6 +94,40 @@ class TestDefaultBuildDeduplicationKey:
key = mw._build_deduplication_key(m)
assert key.startswith("myapp:locks:")
def test_empty_kwargs_produces_consistent_key(self, middleware, make_message):
m1 = make_message(kwargs={})
m2 = make_message(kwargs={})
assert middleware._build_deduplication_key(
m1
) == middleware._build_deduplication_key(m2)
def test_key_fields_empty_list_ignores_all_kwargs(self, middleware, make_message):
m1 = make_message(kwargs={"a": 1}, labels={DEDUP_KEY_FIELDS_LABEL: []})
m2 = make_message(kwargs={"a": 999}, labels={DEDUP_KEY_FIELDS_LABEL: []})
assert middleware._build_deduplication_key(
m1
) == middleware._build_deduplication_key(m2)
def test_key_fields_absent_from_kwargs_are_ignored(self, middleware, make_message):
m1 = make_message(
kwargs={"order_id": 1}, labels={DEDUP_KEY_FIELDS_LABEL: ["user_id"]}
)
m2 = make_message(
kwargs={"order_id": 999}, labels={DEDUP_KEY_FIELDS_LABEL: ["user_id"]}
)
assert middleware._build_deduplication_key(
m1
) == middleware._build_deduplication_key(m2)
def test_explicit_key_takes_precedence_over_key_fields(
self, middleware, make_message
):
m = make_message(
kwargs={"a": 1},
labels={DEDUP_EXPLICIT_KEY_LABEL: "my-lock", DEDUP_KEY_FIELDS_LABEL: ["a"]},
)
assert middleware._build_deduplication_key(m) == "taskiq:deduplication:my-lock"
class TestPreSend:
@pytest.mark.anyio
@@ -140,6 +174,16 @@ class TestPreSend:
await middleware.pre_send(make_message(kwargs={"x": 1}))
await middleware.pre_send(make_message(kwargs={"x": 2}))
@pytest.mark.anyio
async def test_default_ttl_applied(self, fake_redis, make_message):
mw = RedisDeduplicationMiddleware(redis_url="redis://localhost", default_ttl=77)
mw._redis = fake_redis
msg = make_message()
await mw.pre_send(msg)
key = mw._build_deduplication_key(msg)
ttl = await fake_redis.ttl(key)
assert 0 < ttl <= 77
class TestPostExecute:
@pytest.mark.anyio
@@ -166,6 +210,15 @@ class TestPostExecute:
await middleware.post_execute(disabled_msg, make_result())
assert await fake_redis.exists(key)
@pytest.mark.anyio
async def test_post_execute_after_ttl_expiry_is_safe(
self, middleware, fake_redis, make_message, make_result
):
msg = make_message()
await middleware.pre_send(msg)
await fake_redis.delete(middleware._build_deduplication_key(msg))
await middleware.post_execute(msg, make_result())
class TestOnError:
@pytest.mark.anyio
@@ -195,6 +248,26 @@ class TestOnError:
assert await fake_redis.exists(key)
class TestRedispatchAfterRelease:
@pytest.mark.anyio
async def test_redispatch_after_post_execute(
self, middleware, make_message, make_result
):
msg = make_message()
await middleware.pre_send(msg)
await middleware.post_execute(msg, make_result())
await middleware.pre_send(make_message())
@pytest.mark.anyio
async def test_redispatch_after_on_error(
self, middleware, make_message, make_result
):
msg = make_message()
await middleware.pre_send(msg)
await middleware.on_error(msg, make_result(is_err=True), RuntimeError("boom"))
await middleware.pre_send(make_message())
class TestAtomicRelease:
@pytest.mark.anyio
async def test_only_owner_can_release(self, middleware, fake_redis, make_message):