Skip to content

Commit

Permalink
Using custom utcnow method in storage.connection to avoid test hacks.
Browse files Browse the repository at this point in the history
H/T: @tseaver for feedback
  • Loading branch information
dhermes committed Oct 14, 2014
1 parent 4707e31 commit 76a8d05
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 36 deletions.
11 changes: 10 additions & 1 deletion gcloud/storage/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
42 changes: 7 additions & 35 deletions gcloud/storage/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down

0 comments on commit 76a8d05

Please sign in to comment.