test_timeutils.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. from __future__ import absolute_import
  2. import pytz
  3. from datetime import datetime, timedelta, tzinfo
  4. from mock import Mock, patch
  5. from pytz import AmbiguousTimeError
  6. from celery.utils.timeutils import (
  7. delta_resolution,
  8. humanize_seconds,
  9. maybe_iso8601,
  10. maybe_timedelta,
  11. timedelta_seconds,
  12. timezone,
  13. rate,
  14. remaining,
  15. make_aware,
  16. maybe_make_aware,
  17. localize,
  18. LocalTimezone,
  19. ffwd,
  20. utcoffset,
  21. )
  22. from celery.utils.iso8601 import parse_iso8601
  23. from celery.tests.case import Case
  24. class test_LocalTimezone(Case):
  25. def test_daylight(self):
  26. with patch('celery.utils.timeutils._time') as time:
  27. time.timezone = 3600
  28. time.daylight = False
  29. x = LocalTimezone()
  30. self.assertEqual(x.STDOFFSET, timedelta(seconds=-3600))
  31. self.assertEqual(x.DSTOFFSET, x.STDOFFSET)
  32. time.daylight = True
  33. time.altzone = 3600
  34. y = LocalTimezone()
  35. self.assertEqual(y.STDOFFSET, timedelta(seconds=-3600))
  36. self.assertEqual(y.DSTOFFSET, timedelta(seconds=-3600))
  37. self.assertTrue(repr(y))
  38. y._isdst = Mock()
  39. y._isdst.return_value = True
  40. self.assertTrue(y.utcoffset(datetime.now()))
  41. self.assertFalse(y.dst(datetime.now()))
  42. y._isdst.return_value = False
  43. self.assertTrue(y.utcoffset(datetime.now()))
  44. self.assertFalse(y.dst(datetime.now()))
  45. self.assertTrue(y.tzname(datetime.now()))
  46. class test_iso8601(Case):
  47. def test_parse_with_timezone(self):
  48. d = datetime.utcnow().replace(tzinfo=pytz.utc)
  49. self.assertEqual(parse_iso8601(d.isoformat()), d)
  50. # 2013-06-07T20:12:51.775877+00:00
  51. iso = d.isoformat()
  52. iso1 = iso.replace('+00:00', '-01:00')
  53. d1 = parse_iso8601(iso1)
  54. self.assertEqual(d1.tzinfo._minutes, -60)
  55. iso2 = iso.replace('+00:00', '+01:00')
  56. d2 = parse_iso8601(iso2)
  57. self.assertEqual(d2.tzinfo._minutes, +60)
  58. class test_timeutils(Case):
  59. def test_delta_resolution(self):
  60. D = delta_resolution
  61. dt = datetime(2010, 3, 30, 11, 50, 58, 41065)
  62. deltamap = ((timedelta(days=2), datetime(2010, 3, 30, 0, 0)),
  63. (timedelta(hours=2), datetime(2010, 3, 30, 11, 0)),
  64. (timedelta(minutes=2), datetime(2010, 3, 30, 11, 50)),
  65. (timedelta(seconds=2), dt))
  66. for delta, shoulda in deltamap:
  67. self.assertEqual(D(dt, delta), shoulda)
  68. def test_timedelta_seconds(self):
  69. deltamap = ((timedelta(seconds=1), 1),
  70. (timedelta(seconds=27), 27),
  71. (timedelta(minutes=3), 3 * 60),
  72. (timedelta(hours=4), 4 * 60 * 60),
  73. (timedelta(days=3), 3 * 86400))
  74. for delta, seconds in deltamap:
  75. self.assertEqual(timedelta_seconds(delta), seconds)
  76. def test_timedelta_seconds_returns_0_on_negative_time(self):
  77. delta = timedelta(days=-2)
  78. self.assertEqual(timedelta_seconds(delta), 0)
  79. def test_humanize_seconds(self):
  80. t = ((4 * 60 * 60 * 24, '4.00 days'),
  81. (1 * 60 * 60 * 24, '1.00 day'),
  82. (4 * 60 * 60, '4.00 hours'),
  83. (1 * 60 * 60, '1.00 hour'),
  84. (4 * 60, '4.00 minutes'),
  85. (1 * 60, '1.00 minute'),
  86. (4, '4.00 seconds'),
  87. (1, '1.00 second'),
  88. (4.3567631221, '4.36 seconds'),
  89. (0, 'now'))
  90. for seconds, human in t:
  91. self.assertEqual(humanize_seconds(seconds), human)
  92. self.assertEqual(humanize_seconds(4, prefix='about '),
  93. 'about 4.00 seconds')
  94. def test_maybe_iso8601_datetime(self):
  95. now = datetime.now()
  96. self.assertIs(maybe_iso8601(now), now)
  97. def test_maybe_timedelta(self):
  98. D = maybe_timedelta
  99. for i in (30, 30.6):
  100. self.assertEqual(D(i), timedelta(seconds=i))
  101. self.assertEqual(D(timedelta(days=2)), timedelta(days=2))
  102. def test_remaining_relative(self):
  103. remaining(datetime.utcnow(), timedelta(hours=1), relative=True)
  104. class test_timezone(Case):
  105. def test_get_timezone_with_pytz(self):
  106. self.assertTrue(timezone.get_timezone('UTC'))
  107. def test_tz_or_local(self):
  108. self.assertEqual(timezone.tz_or_local(), timezone.local)
  109. self.assertTrue(timezone.tz_or_local(timezone.utc))
  110. def test_to_local(self):
  111. self.assertTrue(
  112. timezone.to_local(make_aware(datetime.utcnow(), timezone.utc)),
  113. )
  114. self.assertTrue(
  115. timezone.to_local(datetime.utcnow())
  116. )
  117. def test_to_local_fallback(self):
  118. self.assertTrue(
  119. timezone.to_local_fallback(
  120. make_aware(datetime.utcnow(), timezone.utc)),
  121. )
  122. self.assertTrue(
  123. timezone.to_local_fallback(datetime.utcnow())
  124. )
  125. class test_make_aware(Case):
  126. def test_tz_without_localize(self):
  127. tz = tzinfo()
  128. self.assertFalse(hasattr(tz, 'localize'))
  129. wtz = make_aware(datetime.utcnow(), tz)
  130. self.assertEqual(wtz.tzinfo, tz)
  131. def test_when_has_localize(self):
  132. class tzz(tzinfo):
  133. raises = False
  134. def localize(self, dt, is_dst=None):
  135. self.localized = True
  136. if self.raises and is_dst is None:
  137. self.raised = True
  138. raise AmbiguousTimeError()
  139. return 1 # needed by min() in Python 3 (None not hashable)
  140. tz = tzz()
  141. make_aware(datetime.utcnow(), tz)
  142. self.assertTrue(tz.localized)
  143. tz2 = tzz()
  144. tz2.raises = True
  145. make_aware(datetime.utcnow(), tz2)
  146. self.assertTrue(tz2.localized)
  147. self.assertTrue(tz2.raised)
  148. def test_maybe_make_aware(self):
  149. aware = datetime.utcnow().replace(tzinfo=timezone.utc)
  150. self.assertTrue(maybe_make_aware(aware), timezone.utc)
  151. naive = datetime.utcnow()
  152. self.assertTrue(maybe_make_aware(naive))
  153. class test_localize(Case):
  154. def test_tz_without_normalize(self):
  155. tz = tzinfo()
  156. self.assertFalse(hasattr(tz, 'normalize'))
  157. self.assertTrue(localize(make_aware(datetime.utcnow(), tz), tz))
  158. def test_when_has_normalize(self):
  159. class tzz(tzinfo):
  160. raises = None
  161. def normalize(self, dt, **kwargs):
  162. self.normalized = True
  163. if self.raises and kwargs and kwargs.get('is_dst') is None:
  164. self.raised = True
  165. raise self.raises
  166. return 1 # needed by min() in Python 3 (None not hashable)
  167. tz = tzz()
  168. localize(make_aware(datetime.utcnow(), tz), tz)
  169. self.assertTrue(tz.normalized)
  170. tz2 = tzz()
  171. tz2.raises = AmbiguousTimeError()
  172. localize(make_aware(datetime.utcnow(), tz2), tz2)
  173. self.assertTrue(tz2.normalized)
  174. self.assertTrue(tz2.raised)
  175. tz3 = tzz()
  176. tz3.raises = TypeError()
  177. localize(make_aware(datetime.utcnow(), tz3), tz3)
  178. self.assertTrue(tz3.normalized)
  179. self.assertTrue(tz3.raised)
  180. class test_rate_limit_string(Case):
  181. def test_conversion(self):
  182. self.assertEqual(rate(999), 999)
  183. self.assertEqual(rate(7.5), 7.5)
  184. self.assertEqual(rate('2.5/s'), 2.5)
  185. self.assertEqual(rate('1456/s'), 1456)
  186. self.assertEqual(rate('100/m'),
  187. 100 / 60.0)
  188. self.assertEqual(rate('10/h'),
  189. 10 / 60.0 / 60.0)
  190. for zero in (0, None, '0', '0/m', '0/h', '0/s', '0.0/s'):
  191. self.assertEqual(rate(zero), 0)
  192. class test_ffwd(Case):
  193. def test_repr(self):
  194. x = ffwd(year=2012)
  195. self.assertTrue(repr(x))
  196. def test_radd_with_unknown_gives_NotImplemented(self):
  197. x = ffwd(year=2012)
  198. self.assertEqual(x.__radd__(object()), NotImplemented)
  199. class test_utcoffset(Case):
  200. def test_utcoffset(self):
  201. with patch('celery.utils.timeutils._time') as _time:
  202. _time.daylight = True
  203. self.assertIsNotNone(utcoffset())
  204. _time.daylight = False
  205. self.assertIsNotNone(utcoffset())