1+ import datetime
2+ import sys
3+
14import pytest
25
36from sentry_sdk .integrations .celery import (
@@ -207,25 +210,65 @@ def test_crons_task_retry():
207210
208211def test_get_monitor_config_crontab ():
209212 app = MagicMock ()
210- app .conf = MagicMock ()
211- app .conf .timezone = "Europe/Vienna"
213+ app .timezone = "Europe/Vienna"
212214
215+ # schedule with the default timezone
213216 celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" )
217+
214218 monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
215219 assert monitor_config == {
216220 "schedule" : {
217221 "type" : "crontab" ,
218222 "value" : "*/10 12 3 * *" ,
219223 },
220- "timezone" : "Europe/Vienna" ,
224+ "timezone" : "UTC" , # the default because `crontab` does not know about the app
221225 }
222226 assert "unit" not in monitor_config ["schedule" ]
223227
228+ # schedule with the timezone from the app
229+ celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" , app = app )
230+
231+ monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
232+ assert monitor_config == {
233+ "schedule" : {
234+ "type" : "crontab" ,
235+ "value" : "*/10 12 3 * *" ,
236+ },
237+ "timezone" : "Europe/Vienna" , # the timezone from the app
238+ }
239+
240+ # schedule without a timezone, the celery integration will read the config from the app
241+ celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" )
242+ celery_schedule .tz = None
243+
244+ monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
245+ assert monitor_config == {
246+ "schedule" : {
247+ "type" : "crontab" ,
248+ "value" : "*/10 12 3 * *" ,
249+ },
250+ "timezone" : "Europe/Vienna" , # the timezone from the app
251+ }
252+
253+ # schedule without a timezone, and an app without timezone, the celery integration will fall back to UTC
254+ app = MagicMock ()
255+ app .timezone = None
256+
257+ celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" )
258+ celery_schedule .tz = None
259+ monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
260+ assert monitor_config == {
261+ "schedule" : {
262+ "type" : "crontab" ,
263+ "value" : "*/10 12 3 * *" ,
264+ },
265+ "timezone" : "UTC" , # default timezone from celery integration
266+ }
267+
224268
225269def test_get_monitor_config_seconds ():
226270 app = MagicMock ()
227- app .conf = MagicMock ()
228- app .conf .timezone = "Europe/Vienna"
271+ app .timezone = "Europe/Vienna"
229272
230273 celery_schedule = schedule (run_every = 3 ) # seconds
231274
@@ -243,25 +286,69 @@ def test_get_monitor_config_seconds():
243286
244287def test_get_monitor_config_minutes ():
245288 app = MagicMock ()
246- app .conf = MagicMock ()
247- app .conf .timezone = "Europe/Vienna"
289+ app .timezone = "Europe/Vienna"
290+
291+ # schedule with the default timezone
292+ celery_schedule = schedule (run_every = 60 ) # seconds
293+
294+ monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
295+ assert monitor_config == {
296+ "schedule" : {
297+ "type" : "interval" ,
298+ "value" : 1 ,
299+ "unit" : "minute" ,
300+ },
301+ "timezone" : "UTC" ,
302+ }
303+
304+ # schedule with the timezone from the app
305+ celery_schedule = schedule (run_every = 60 , app = app ) # seconds
306+
307+ monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
308+ assert monitor_config == {
309+ "schedule" : {
310+ "type" : "interval" ,
311+ "value" : 1 ,
312+ "unit" : "minute" ,
313+ },
314+ "timezone" : "Europe/Vienna" , # the timezone from the app
315+ }
316+
317+ # schedule without a timezone, the celery integration will read the config from the app
318+ celery_schedule = schedule (run_every = 60 ) # seconds
319+ celery_schedule .tz = None
320+
321+ monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
322+ assert monitor_config == {
323+ "schedule" : {
324+ "type" : "interval" ,
325+ "value" : 1 ,
326+ "unit" : "minute" ,
327+ },
328+ "timezone" : "Europe/Vienna" , # the timezone from the app
329+ }
330+
331+ # schedule without a timezone, and an app without timezone, the celery integration will fall back to UTC
332+ app = MagicMock ()
333+ app .timezone = None
248334
249335 celery_schedule = schedule (run_every = 60 ) # seconds
336+ celery_schedule .tz = None
337+
250338 monitor_config = _get_monitor_config (celery_schedule , app , "foo" )
251339 assert monitor_config == {
252340 "schedule" : {
253341 "type" : "interval" ,
254342 "value" : 1 ,
255343 "unit" : "minute" ,
256344 },
257- "timezone" : "Europe/Vienna" ,
345+ "timezone" : "UTC" , # default timezone from celery integration
258346 }
259347
260348
261349def test_get_monitor_config_unknown ():
262350 app = MagicMock ()
263- app .conf = MagicMock ()
264- app .conf .timezone = "Europe/Vienna"
351+ app .timezone = "Europe/Vienna"
265352
266353 unknown_celery_schedule = MagicMock ()
267354 monitor_config = _get_monitor_config (unknown_celery_schedule , app , "foo" )
@@ -270,16 +357,45 @@ def test_get_monitor_config_unknown():
270357
271358def test_get_monitor_config_default_timezone ():
272359 app = MagicMock ()
273- app .conf = MagicMock ()
274- app .conf .timezone = None
360+ app .timezone = None
275361
276362 celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" )
277363
278- monitor_config = _get_monitor_config (celery_schedule , app , "foo " )
364+ monitor_config = _get_monitor_config (celery_schedule , app , "dummy_monitor_name " )
279365
280366 assert monitor_config ["timezone" ] == "UTC"
281367
282368
369+ def test_get_monitor_config_timezone_in_app_conf ():
370+ app = MagicMock ()
371+ app .timezone = "Asia/Karachi"
372+
373+ celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" )
374+ celery_schedule .tz = None
375+
376+ monitor_config = _get_monitor_config (celery_schedule , app , "dummy_monitor_name" )
377+
378+ assert monitor_config ["timezone" ] == "Asia/Karachi"
379+
380+
381+ @pytest .mark .skipif (
382+ sys .version_info < (3 , 0 ),
383+ reason = "no datetime.timezone for Python 2, so skipping this test." ,
384+ )
385+ def test_get_monitor_config_timezone_in_celery_schedule ():
386+ app = MagicMock ()
387+ app .timezone = "Asia/Karachi"
388+
389+ panama_tz = datetime .timezone (datetime .timedelta (hours = - 5 ), name = "America/Panama" )
390+
391+ celery_schedule = crontab (day_of_month = "3" , hour = "12" , minute = "*/10" )
392+ celery_schedule .tz = panama_tz
393+
394+ monitor_config = _get_monitor_config (celery_schedule , app , "dummy_monitor_name" )
395+
396+ assert monitor_config ["timezone" ] == str (panama_tz )
397+
398+
283399@pytest .mark .parametrize (
284400 "task_name,exclude_beat_tasks,task_in_excluded_beat_tasks" ,
285401 [
0 commit comments