@ -1,11 +1,11 @@
import os
import os
import time
import time
from datetime import datetime , timedelta
from datetime import datetime , timedelta , timezone
from multiprocessing import Process
from multiprocessing import Process
from rq import Queue
from rq import Queue
from rq . compat import utc, PY2
from rq . compat import PY2
from rq . exceptions import NoSuchJobError
from rq . exceptions import NoSuchJobError
from rq . job import Job , Retry
from rq . job import Job , Retry
from rq . registry import FinishedJobRegistry , ScheduledJobRegistry
from rq . registry import FinishedJobRegistry , ScheduledJobRegistry
@ -57,8 +57,8 @@ class TestScheduledJobRegistry(RQTestCase):
job = Job . create ( ' myfunc ' , connection = self . testconn )
job = Job . create ( ' myfunc ' , connection = self . testconn )
job . save ( )
job . save ( )
dt = datetime ( 2019 , 1 , 1 , tzinfo = utc)
dt = datetime ( 2019 , 1 , 1 , tzinfo = timezone. utc)
registry . schedule ( job , datetime ( 2019 , 1 , 1 , tzinfo = utc) )
registry . schedule ( job , datetime ( 2019 , 1 , 1 , tzinfo = timezone. utc) )
self . assertEqual ( registry . get_scheduled_time ( job ) , dt )
self . assertEqual ( registry . get_scheduled_time ( job ) , dt )
# get_scheduled_time() should also work with job ID
# get_scheduled_time() should also work with job ID
self . assertEqual ( registry . get_scheduled_time ( job . id ) , dt )
self . assertEqual ( registry . get_scheduled_time ( job . id ) , dt )
@ -74,35 +74,28 @@ class TestScheduledJobRegistry(RQTestCase):
job . save ( )
job . save ( )
registry = ScheduledJobRegistry ( queue = queue )
registry = ScheduledJobRegistry ( queue = queue )
if PY2 :
from datetime import timezone
# On Python 2, datetime needs to have timezone
# If we pass in a datetime with no timezone, `schedule()`
self . assertRaises ( ValueError , registry . schedule , job , datetime ( 2019 , 1 , 1 ) )
# assumes local timezone so depending on your local timezone,
registry . schedule ( job , datetime ( 2019 , 1 , 1 , tzinfo = utc ) )
# the timestamp maybe different
# we need to account for the difference between a timezone
# with DST active and without DST active. The time.timezone
# property isn't accurate when time.daylight is non-zero,
# we'll test both.
# first, time.daylight == 0 (not in DST).
# mock the sitatuoin for American/New_York not in DST (UTC - 5)
# time.timezone = 18000
# time.daylight = 0
# time.altzone = 14400
mock_day = mock . patch ( ' time.daylight ' , 0 )
mock_tz = mock . patch ( ' time.timezone ' , 18000 )
mock_atz = mock . patch ( ' time.altzone ' , 14400 )
with mock_tz , mock_day , mock_atz :
registry . schedule ( job , datetime ( 2019 , 1 , 1 ) )
self . assertEqual ( self . testconn . zscore ( registry . key , job . id ) ,
self . assertEqual ( self . testconn . zscore ( registry . key , job . id ) ,
1546300800 ) # 2019-01-01 UTC in Unix timestamp
1546300800 + 18000 ) # 2019-01-01 UTC in Unix timestamp
else :
from datetime import timezone
# If we pass in a datetime with no timezone, `schedule()`
# assumes local timezone so depending on your local timezone,
# the timestamp maybe different
# we need to account for the difference between a timezone
# with DST active and without DST active. The time.timezone
# property isn't accurate when time.daylight is non-zero,
# we'll test both.
# first, time.daylight == 0 (not in DST).
# mock the sitatuoin for American/New_York not in DST (UTC - 5)
# time.timezone = 18000
# time.daylight = 0
# time.altzone = 14400
mock_day = mock . patch ( ' time.daylight ' , 0 )
mock_tz = mock . patch ( ' time.timezone ' , 18000 )
mock_atz = mock . patch ( ' time.altzone ' , 14400 )
with mock_tz , mock_day , mock_atz :
registry . schedule ( job , datetime ( 2019 , 1 , 1 ) )
self . assertEqual ( self . testconn . zscore ( registry . key , job . id ) ,
1546300800 + 18000 ) # 2019-01-01 UTC in Unix timestamp
# second, time.daylight != 0 (in DST)
# second, time.daylight != 0 (in DST)
# mock the sitatuoin for American/New_York not in DST (UTC - 4)
# mock the sitatuoin for American/New_York not in DST (UTC - 4)
@ -227,7 +220,7 @@ class TestScheduler(RQTestCase):
registry = ScheduledJobRegistry ( queue = queue )
registry = ScheduledJobRegistry ( queue = queue )
job = Job . create ( ' myfunc ' , connection = self . testconn )
job = Job . create ( ' myfunc ' , connection = self . testconn )
job . save ( )
job . save ( )
registry . schedule ( job , datetime ( 2019 , 1 , 1 , tzinfo = utc) )
registry . schedule ( job , datetime ( 2019 , 1 , 1 , tzinfo = timezone. utc) )
scheduler = RQScheduler ( [ queue ] , connection = self . testconn )
scheduler = RQScheduler ( [ queue ] , connection = self . testconn )
scheduler . acquire_locks ( )
scheduler . acquire_locks ( )
scheduler . enqueue_scheduled_jobs ( )
scheduler . enqueue_scheduled_jobs ( )
@ -237,7 +230,7 @@ class TestScheduler(RQTestCase):
self . assertEqual ( len ( registry ) , 0 )
self . assertEqual ( len ( registry ) , 0 )
# Jobs scheduled in the far future should not be affected
# Jobs scheduled in the far future should not be affected
registry . schedule ( job , datetime ( 2100 , 1 , 1 , tzinfo = utc) )
registry . schedule ( job , datetime ( 2100 , 1 , 1 , tzinfo = timezone. utc) )
scheduler . enqueue_scheduled_jobs ( )
scheduler . enqueue_scheduled_jobs ( )
self . assertEqual ( len ( queue ) , 1 )
self . assertEqual ( len ( queue ) , 1 )
@ -294,7 +287,7 @@ class TestWorker(RQTestCase):
p = Process ( target = kill_worker , args = ( os . getpid ( ) , False , 5 ) )
p = Process ( target = kill_worker , args = ( os . getpid ( ) , False , 5 ) )
p . start ( )
p . start ( )
queue . enqueue_at ( datetime ( 2019 , 1 , 1 , tzinfo = utc) , say_hello )
queue . enqueue_at ( datetime ( 2019 , 1 , 1 , tzinfo = timezone. utc) , say_hello )
worker . work ( burst = False , with_scheduler = True )
worker . work ( burst = False , with_scheduler = True )
p . join ( 1 )
p . join ( 1 )
self . assertIsNotNone ( worker . scheduler )
self . assertIsNotNone ( worker . scheduler )
@ -311,7 +304,7 @@ class TestQueue(RQTestCase):
scheduler = RQScheduler ( [ queue ] , connection = self . testconn )
scheduler = RQScheduler ( [ queue ] , connection = self . testconn )
scheduler . acquire_locks ( )
scheduler . acquire_locks ( )
# Jobs created using enqueue_at is put in the ScheduledJobRegistry
# Jobs created using enqueue_at is put in the ScheduledJobRegistry
job = queue . enqueue_at ( datetime ( 2019 , 1 , 1 , tzinfo = utc) , say_hello )
job = queue . enqueue_at ( datetime ( 2019 , 1 , 1 , tzinfo = timezone. utc) , say_hello )
self . assertEqual ( len ( queue ) , 0 )
self . assertEqual ( len ( queue ) , 0 )
self . assertEqual ( len ( registry ) , 1 )
self . assertEqual ( len ( registry ) , 1 )
@ -330,7 +323,7 @@ class TestQueue(RQTestCase):
registry = ScheduledJobRegistry ( queue = queue )
registry = ScheduledJobRegistry ( queue = queue )
job = queue . enqueue_in ( timedelta ( seconds = 30 ) , say_hello )
job = queue . enqueue_in ( timedelta ( seconds = 30 ) , say_hello )
now = datetime . now ( utc)
now = datetime . now ( timezone. utc)
scheduled_time = registry . get_scheduled_time ( job )
scheduled_time = registry . get_scheduled_time ( job )
# Ensure that job is scheduled roughly 30 seconds from now
# Ensure that job is scheduled roughly 30 seconds from now
self . assertTrue (
self . assertTrue (