test_time_every.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. from datetime import timedelta, datetime
  2. from pprint import pprint
  3. import pytest
  4. from larigira.timegen_every import FrequencyAlarm, SingleAlarm
  5. from larigira.timegen import timegenerate
  6. def eq_(a, b, reason=None):
  7. """migrating tests from nose"""
  8. if reason is not None:
  9. assert a == b, reason
  10. else:
  11. assert a == b
  12. @pytest.fixture
  13. def now():
  14. return datetime.now()
  15. @pytest.fixture(params=["seconds", "human", "humanlong", "coloned"])
  16. def onehour(now, request):
  17. """a FrequencyAlarm: every hour for one day"""
  18. intervals = dict(
  19. seconds=3600, human="1h", humanlong="30m 1800s", coloned="01:00:00"
  20. )
  21. return FrequencyAlarm(
  22. {
  23. "start": now - timedelta(days=1),
  24. "interval": intervals[request.param],
  25. "end": now + days(1),
  26. }
  27. )
  28. @pytest.fixture(params=[1, "1"])
  29. def onehour_monday(request):
  30. weekday = request.param
  31. yield FrequencyAlarm({"interval": 3600 * 12, "weekdays": [weekday], "start": 0})
  32. @pytest.fixture(params=[7, "7"])
  33. def onehour_sunday(request):
  34. weekday = request.param
  35. yield FrequencyAlarm({"interval": 3600 * 12, "weekdays": [weekday], "start": 0})
  36. @pytest.fixture(params=[1, 2, 3, 4, 5, 6, 7])
  37. def singledow(request):
  38. weekday = request.param
  39. yield FrequencyAlarm({"interval": 3600 * 24, "weekdays": [weekday], "start": 0})
  40. @pytest.fixture(params=["seconds", "human", "coloned"])
  41. def tenseconds(now, request):
  42. """a FrequencyAlarm: every 10 seconds for one day"""
  43. intervals = dict(seconds=10, human="10s", coloned="00:10")
  44. return FrequencyAlarm(
  45. {
  46. "start": now - timedelta(days=1),
  47. "interval": intervals[request.param],
  48. "end": now + days(1),
  49. }
  50. )
  51. @pytest.fixture(params=[1, 2, 3, 4, 5, 6, 7, 8])
  52. def manyweeks(request):
  53. yield FrequencyAlarm({"interval": "{}w".format(request.param), "start": 0})
  54. def days(n):
  55. return timedelta(days=n)
  56. def test_single_creations(now):
  57. return SingleAlarm({"timestamp": now})
  58. def test_freq_creations(now):
  59. return FrequencyAlarm(
  60. {"start": now - timedelta(days=1), "interval": 3600, "end": now}
  61. )
  62. @pytest.mark.timeout(1)
  63. def test_single_ring(now):
  64. dt = now + days(1)
  65. s = SingleAlarm({"timestamp": dt})
  66. eq_(s.next_ring(), dt)
  67. eq_(s.next_ring(now), dt)
  68. assert s.next_ring(dt) is None, "%s - %s" % (str(s.next_ring(dt)), str(dt))
  69. assert s.next_ring(now + days(2)) is None
  70. assert s.has_ring(dt)
  71. assert not s.has_ring(now)
  72. assert not s.has_ring(now + days(2))
  73. @pytest.mark.timeout(1)
  74. def test_single_all(now):
  75. dt = now + timedelta(days=1)
  76. s = SingleAlarm({"timestamp": dt})
  77. eq_(list(s.all_rings()), [dt])
  78. eq_(list(s.all_rings(now)), [dt])
  79. eq_(list(s.all_rings(now + days(2))), [])
  80. def test_freq_short(now, tenseconds):
  81. f = tenseconds
  82. assert now in f.all_rings(now - days(3))
  83. assert f.next_ring(now) is not None
  84. assert f.next_ring(now) != now
  85. assert f.next_ring(now) > now
  86. assert now not in f.all_rings(now)
  87. for r in f.all_rings(now):
  88. assert r > now
  89. @pytest.mark.timeout(1)
  90. def test_freq_ring(now, onehour):
  91. f = onehour
  92. assert now in f.all_rings(now - days(3))
  93. assert f.next_ring(now) is not None
  94. assert f.next_ring(now) != now
  95. assert f.next_ring(now) > now
  96. assert now not in f.all_rings(now)
  97. for r in f.all_rings(now):
  98. assert r > now
  99. allr = list(f.all_rings(now))
  100. eq_(len(allr), 24)
  101. eq_(len(tuple(f.all_rings(now + days(2)))), 0)
  102. allr = tuple(f.all_rings(now - days(20)))
  103. eq_(f.next_ring(now - days(20)), now - days(1))
  104. eq_(len(allr), 49, pprint(allr))
  105. def test_weekday_skip(onehour_monday):
  106. t = datetime.fromtimestamp(0)
  107. for _ in range(20): # 20 is an arbitrary number
  108. t = onehour_monday.next_ring(t)
  109. assert t.isoweekday() == 1 # monday; don't get confused by .weekday()
  110. def test_weekday_skip_2(onehour_sunday):
  111. t = datetime.fromtimestamp(0)
  112. for _ in range(20): # 20 is an arbitrary number
  113. t = onehour_sunday.next_ring(t)
  114. assert t.isoweekday() == 7 # monday; don't get confused by .weekday()
  115. def test_sunday_is_not_0():
  116. with pytest.raises(ValueError) as excinfo:
  117. FrequencyAlarm({"interval": 3600 * 12, "weekdays": [0], "start": 0})
  118. assert "Not a valid weekday:" in excinfo.value.args[0]
  119. def test_long_interval(manyweeks):
  120. t = datetime.fromtimestamp(1)
  121. expected = manyweeks.interval
  122. got = manyweeks.next_ring(t)
  123. assert got is not None
  124. assert int(got.strftime("%s")) == expected
  125. assert manyweeks.next_ring(got) is not None
  126. def test_singledow(singledow):
  127. t = datetime.fromtimestamp(1)
  128. got = singledow.next_ring(t)
  129. wd = singledow.weekdays[0]
  130. assert got is not None
  131. assert got.isoweekday() == wd
  132. assert singledow.next_ring(got) is not None
  133. assert singledow.next_ring(got).isoweekday() == wd
  134. def test_single_registered():
  135. timegenerate({"kind": "single", "timestamp": 1234567890})
  136. def test_frequency_registered():
  137. timegenerate({"kind": "frequency", "start": 1234567890, "interval": 60 * 15})