From 76a8d050f0c85dfa97832a90e2bb602c7cfa5232 Mon Sep 17 00:00:00 2001 From: Danny Hermes Date: Mon, 13 Oct 2014 17:17:33 -0700 Subject: [PATCH] Using custom utcnow method in storage.connection to avoid test hacks. H/T: @tseaver for feedback --- gcloud/storage/connection.py | 11 +++++++- gcloud/storage/test_connection.py | 42 ++++++------------------------- 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/gcloud/storage/connection.py b/gcloud/storage/connection.py index cbdd21c03db3..20b79db232aa 100644 --- a/gcloud/storage/connection.py +++ b/gcloud/storage/connection.py @@ -18,6 +18,15 @@ from gcloud.storage.iterator import BucketIterator +def _utcnow(): # pragma NO COVER + """Returns current time as UTC datetime. + + NOTE: This method is here on the module namespace so tests + can replace it. + """ + return datetime.datetime.utcnow() + + class Connection(connection.Connection): """A connection to Google Cloud Storage via the JSON REST API. @@ -447,7 +456,7 @@ def _get_expiration_seconds(expiration): # If it's a timedelta, add it to `now` in UTC. if isinstance(expiration, datetime.timedelta): - now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) + now = _utcnow().replace(tzinfo=pytz.utc) expiration = now + expiration # If it's a datetime (and/or was a timedelta), convert to a timestamp. diff --git a/gcloud/storage/test_connection.py b/gcloud/storage/test_connection.py index d7eb07594758..f356a776ecfc 100644 --- a/gcloud/storage/test_connection.py +++ b/gcloud/storage/test_connection.py @@ -538,43 +538,14 @@ def test__get_expiration_seconds(self): self.assertRaises(TypeError, CALL_FUT, object()) self.assertRaises(TypeError, CALL_FUT, None) - def _patch_datetime_for_utcnow(self, datetime_module, *date_tuple): - import pytz - - original_datetime = datetime_module.datetime - - class _DateTime(datetime_module.datetime): - - @staticmethod - def utcnow(): - return _DateTime(*date_tuple, tzinfo=pytz.utc) - - def replace(self, *args, **kwargs): - result = original_datetime.replace(self, *args, **kwargs) - # Cast to the correct type so isinstance() succeeds. - return _DateTime(result.year, result.month, result.day, - result.hour, result.minute, result.second, - result.microsecond, tzinfo=result.tzinfo) - - def __add__(self, other): - result = original_datetime.__add__(self, other) - # Cast to the correct type so isinstance() succeeds. - return _DateTime(result.year, result.month, result.day, - result.hour, result.minute, result.second, - result.microsecond, tzinfo=result.tzinfo) - - self._original_datetime_class = datetime_module.datetime - datetime_module.datetime = _DateTime - - def _restore_datetime(self, datetime_module): - datetime_module.datetime = self._original_datetime_class - def test__get_expiration_seconds_w_timedelta(self): + # Patch the utcnow method on the module. import datetime + from gcloud.storage import connection + original_utcnow = connection._utcnow + connection._utcnow = lambda: datetime.datetime(2004, 8, 19, 0, 0, 0, 0) - self._patch_datetime_for_utcnow(datetime, 2004, 8, 19, 0, 0, 0, 0) - # Must do this after patching datetime so that the import - # occurs again with the patched datetime. + # Test the function with timedelta inputs. CALL_FUT = self._getTargetClass()._get_expiration_seconds expiration_as_seconds = 1092873600 @@ -586,7 +557,8 @@ def test__get_expiration_seconds_w_timedelta(self): self.assertEqual(expiration_as_seconds + 10, CALL_FUT(expiration_as_delta)) - self._restore_datetime(datetime) + # Restore utcnow method on the module. + connection._utcnow = original_utcnow class Http(object):