From 260fd84f5148997ad07dfaed0c3c2016a5c74d8d Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Sat, 9 Sep 2017 20:28:53 +0100 Subject: [PATCH] add milliseconds into timestamps, fix #721 --- rq/utils.py | 11 +++++++---- tests/helpers.py | 9 --------- tests/test_job.py | 10 +++------- tests/test_utils.py | 8 +++++--- tests/test_worker.py | 5 ++--- 5 files changed, 17 insertions(+), 26 deletions(-) delete mode 100644 tests/helpers.py diff --git a/rq/utils.py b/rq/utils.py index 92da52138..4d1bbeac8 100644 --- a/rq/utils.py +++ b/rq/utils.py @@ -157,16 +157,19 @@ def utcnow(): return datetime.datetime.utcnow() +_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' + + def utcformat(dt): - return dt.strftime(as_text('%Y-%m-%dT%H:%M:%SZ')) + return dt.strftime(as_text(_TIMESTAMP_FORMAT)) def utcparse(string): try: - return datetime.datetime.strptime(string, '%Y-%m-%dT%H:%M:%SZ') + return datetime.datetime.strptime(string, _TIMESTAMP_FORMAT) except ValueError: - # This catches RQ < 0.4 datetime format - return datetime.datetime.strptime(string, '%Y-%m-%dT%H:%M:%S.%f+00:00') + # This catches any jobs remain with old datetime format + return datetime.datetime.strptime(string, '%Y-%m-%dT%H:%M:%SZ') def first(iterable, default=None, key=None): diff --git a/tests/helpers.py b/tests/helpers.py deleted file mode 100644 index 1475cf0a4..000000000 --- a/tests/helpers.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, print_function, - unicode_literals) - -from datetime import timedelta - - -def strip_microseconds(date): - return date - timedelta(microseconds=date.microsecond) diff --git a/tests/test_job.py b/tests/test_job.py index e715fbfa7..fe9afcdf4 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -14,7 +14,6 @@ import queue as queue from tests import fixtures, RQTestCase -from tests.helpers import strip_microseconds from rq.compat import PY2 from rq.exceptions import NoSuchJobError, UnpickleError @@ -170,7 +169,7 @@ def test_fetch(self): self.testconn.hset('rq:job:some_id', 'data', "(S'tests.fixtures.some_calculation'\nN(I3\nI4\nt(dp1\nS'z'\nI2\nstp2\n.") self.testconn.hset('rq:job:some_id', 'created_at', - '2012-02-07T22:13:24Z') + '2012-02-07T22:13:24.123456Z') # Fetch returns a job job = Job.fetch('some_id') @@ -179,7 +178,7 @@ def test_fetch(self): self.assertIsNone(job.instance) self.assertEqual(job.args, (3, 4)) self.assertEqual(job.kwargs, dict(z=2)) - self.assertEqual(job.created_at, datetime(2012, 2, 7, 22, 13, 24)) + self.assertEqual(job.created_at, datetime(2012, 2, 7, 22, 13, 24, 123456)) def test_persistence_of_empty_jobs(self): # noqa """Storing empty jobs.""" @@ -192,11 +191,8 @@ def test_persistence_of_typical_jobs(self): job = Job.create(func=fixtures.some_calculation, args=(3, 4), kwargs=dict(z=2)) job.save() - expected_date = strip_microseconds(job.created_at) stored_date = self.testconn.hget(job.key, 'created_at').decode('utf-8') - self.assertEqual( - stored_date, - utcformat(expected_date)) + self.assertEqual(stored_date, utcformat(job.created_at)) # ... and no other keys are stored self.assertEqual( diff --git a/tests/test_utils.py b/tests/test_utils.py index 529c61e5f..b66237e15 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -51,11 +51,13 @@ def test_ensure_list(self): def test_utcparse(self): """Ensure function utcparse works correctly""" - utc_formated_time = '2017-08-31T10:14:02Z' - utc_compat_formated_time = '2017-08-31T10:20:56.226733+00:00' + utc_formated_time = '2017-08-31T10:14:02.123456Z' + self.assertEqual(datetime.datetime(2017, 8, 31, 10, 14, 2, 123456), utcparse(utc_formated_time)) + def test_utcparse_legacy(self): + """Ensure function utcparse works correctly""" + utc_formated_time = '2017-08-31T10:14:02Z' self.assertEqual(datetime.datetime(2017, 8, 31, 10, 14, 2), utcparse(utc_formated_time)) - self.assertEqual(datetime.datetime(2017, 8, 31, 10, 20, 56, 226733), utcparse(utc_compat_formated_time)) def test_backend_class(self): """Ensure function backend_class works correctly""" diff --git a/tests/test_worker.py b/tests/test_worker.py index eb0ce05ce..85435e745 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -22,7 +22,6 @@ div_by_zero, do_nothing, say_hello, say_pid, run_dummy_heroku_worker, access_self, modify_self, modify_self_and_error) -from tests.helpers import strip_microseconds from rq import (get_failed_queue, Queue, SimpleWorker, Worker, get_current_connection) @@ -212,7 +211,7 @@ def test_work_fails(self): self.assertEqual(q.count, 1) # keep for later - enqueued_at_date = strip_microseconds(job.enqueued_at) + enqueued_at_date = str(job.enqueued_at) w = Worker([q]) w.work(burst=True) # should silently pass @@ -228,7 +227,7 @@ def test_work_fails(self): # Should be the original enqueued_at date, not the date of enqueueing # to the failed queue - self.assertEqual(job.enqueued_at, enqueued_at_date) + self.assertEqual(str(job.enqueued_at), enqueued_at_date) self.assertIsNotNone(job.exc_info) # should contain exc_info def test_custom_exc_handling(self):