11import datetime
2+ import logging
23import os
34import typing
45from collections .abc import AsyncGenerator
78import pytest
89from redis import asyncio as aioredis
910
10- from redis_timers import Timers , settings
11+ from redis_timers import Timers , consume_lock , settings
1112from redis_timers .router import Router
1213
1314
@@ -70,8 +71,7 @@ async def another_handler(data: AnotherPayloadModel, context: dict[str, typing.A
7071 handler_results .add_result (data )
7172 assert context ["some_key" ] == "some_value"
7273
73- timers = Timers (redis_client = redis_client , context = {"some_key" : "some_value" })
74- timers .include_router (router1 )
74+ timers = Timers (redis_client = redis_client , context = {"some_key" : "some_value" }, routers = [router1 ])
7575 timers .include_routers (router2 )
7676
7777 return timers
@@ -104,6 +104,17 @@ async def test_set_and_remove_timer(timers_instance: Timers) -> None:
104104 assert not payloads_dict
105105
106106
107+ async def test_set_undefined_timer (timers_instance : Timers ) -> None :
108+ payload = SomePayloadModel (message = "test" , count = 1 )
109+ with pytest .raises (RuntimeError , match = "Handler is not found, topic='wrong_topic'" ):
110+ await timers_instance .set_timer (
111+ topic = "wrong_topic" ,
112+ timer_id = "test_timer_1" ,
113+ payload = payload ,
114+ activation_period = datetime .timedelta (seconds = 1 ),
115+ )
116+
117+
107118async def test_handle_ready_timers (timers_instance : Timers , handler_results : HandlerResults ) -> None :
108119 payload = SomePayloadModel (message = "ready_timer" , count = 42 )
109120 await timers_instance .set_timer (
@@ -129,6 +140,74 @@ async def test_handle_ready_timers(timers_instance: Timers, handler_results: Han
129140 assert not payloads_dict
130141
131142
143+ async def test_handle_ready_timer_no_handler (timers_instance : Timers , caplog : pytest .LogCaptureFixture ) -> None :
144+ caplog .set_level (logging .INFO )
145+ payload = SomePayloadModel (message = "ready_timer" , count = 42 )
146+ await timers_instance .set_timer (
147+ topic = "some_topic" ,
148+ timer_id = "ready_timer_1" ,
149+ payload = payload ,
150+ activation_period = datetime .timedelta (seconds = 0 ), # Ready immediately
151+ )
152+ del timers_instance .handlers_by_topics ["some_topic" ]
153+ await timers_instance .handle_ready_timers ()
154+
155+ assert len (caplog .records ) == 1
156+ assert "Handler is not found" in caplog .records [0 ].message
157+
158+
159+ async def test_handle_ready_timer_no_payload (timers_instance : Timers , caplog : pytest .LogCaptureFixture ) -> None :
160+ caplog .set_level (logging .INFO )
161+ payload = SomePayloadModel (message = "ready_timer" , count = 42 )
162+ await timers_instance .set_timer (
163+ topic = "some_topic" ,
164+ timer_id = "ready_timer_1" ,
165+ payload = payload ,
166+ activation_period = datetime .timedelta (seconds = 0 ), # Ready immediately
167+ )
168+ await timers_instance .redis_client .hdel (settings .TIMERS_PAYLOADS_KEY , "some_topic--ready_timer_1" )
169+ await timers_instance .handle_ready_timers ()
170+
171+ assert len (caplog .records ) == 1
172+ assert "No payload found" in caplog .records [0 ].message
173+
174+
175+ async def test_handle_ready_timer_invalid_payload (timers_instance : Timers , caplog : pytest .LogCaptureFixture ) -> None :
176+ caplog .set_level (logging .INFO )
177+ payload = SomePayloadModel (message = "ready_timer" , count = 42 )
178+ await timers_instance .set_timer (
179+ topic = "some_topic" ,
180+ timer_id = "ready_timer_1" ,
181+ payload = payload ,
182+ activation_period = datetime .timedelta (seconds = 0 ), # Ready immediately
183+ )
184+ await timers_instance .redis_client .hset (settings .TIMERS_PAYLOADS_KEY , "some_topic--ready_timer_1" , "{}" )
185+ await timers_instance .handle_ready_timers ()
186+
187+ assert len (caplog .records ) == 1
188+ assert "Failed to parse payload" in caplog .records [0 ].message
189+
190+
191+ async def test_handle_ready_timer_locked (timers_instance : Timers , caplog : pytest .LogCaptureFixture ) -> None :
192+ caplog .set_level (logging .DEBUG )
193+ payload = SomePayloadModel (message = "ready_timer" , count = 42 )
194+ await timers_instance .set_timer (
195+ topic = "some_topic" ,
196+ timer_id = "ready_timer_1" ,
197+ payload = payload ,
198+ activation_period = datetime .timedelta (seconds = 0 ), # Ready immediately
199+ )
200+ lock = consume_lock (
201+ redis_client = timers_instance .redis_client ,
202+ key = "some_topic--ready_timer_1" ,
203+ )
204+ async with lock :
205+ await timers_instance .handle_ready_timers ()
206+
207+ assert len (caplog .records ) == 1
208+ assert "Timer is locked" in caplog .records [0 ].message
209+
210+
132211async def test_handle_multiple_ready_timers (timers_instance : Timers , handler_results : HandlerResults ) -> None :
133212 payload1 = SomePayloadModel (message = "timer_1" , count = 1 )
134213 payload2 = AnotherPayloadModel (value = "timer_2" )
0 commit comments