Browse Source

During DST transition, handle ambiguous dates as pre-transition. Fixes #196

pull/199/head
Pēteris Caune 6 years ago
parent
commit
df86fd29b3
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
4 changed files with 27 additions and 2 deletions
  1. +3
    -0
      CHANGELOG.md
  2. +1
    -1
      hc/api/models.py
  3. +22
    -0
      hc/front/tests/test_cron_preview.py
  4. +1
    -1
      hc/front/views.py

+ 3
- 0
CHANGELOG.md View File

@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file.
- Load settings from environment variables
- Add "List-Unsubscribe" header to alert and report emails
### Bug Fixes
- During DST transition, handle ambiguous dates as pre-transition
## 1.2.0 - 2018-10-20


+ 1
- 1
hc/api/models.py View File

@ -116,7 +116,7 @@ class Check(models.Model):
last_naive = timezone.make_naive(self.last_ping)
it = croniter(self.schedule, last_naive)
next_naive = it.get_next(datetime)
return timezone.make_aware(next_naive, is_dst=False)
return timezone.make_aware(next_naive, is_dst=True)
def get_status(self, now=None):
""" Return "up" if the check is up or in grace, otherwise "down". """


+ 22
- 0
hc/front/tests/test_cron_preview.py View File

@ -1,4 +1,8 @@
from datetime import datetime
from hc.test import BaseTestCase
from mock import patch
import pytz
class CronPreviewTestCase(BaseTestCase):
@ -30,3 +34,21 @@ class CronPreviewTestCase(BaseTestCase):
def test_it_rejects_get(self):
r = self.client.get("/checks/cron_preview/", {})
self.assertEqual(r.status_code, 405)
@patch("hc.front.views.timezone.now")
def test_it_handles_dst_transition(self, mock_now):
# Consider year 2018, Riga, Latvia:
# The daylight-saving-time ends at 4AM on October 28.
# At that time, the clock is turned back one hour.
# So, on that date, 3AM happens *twice* and saying
# "3AM on October 28" is ambiguous.
mock_now.return_value = datetime(2018, 10, 26, tzinfo=pytz.UTC)
# This schedule will hit the ambiguous date. Cron preview must
# be able to handle this:
payload = {
"schedule": "0 3 * * *",
"tz": "Europe/Riga"
}
r = self.client.post("/checks/cron_preview/", payload)
self.assertNotContains(r, "Invalid cron expression", status_code=200)

+ 1
- 1
hc/front/views.py View File

@ -281,7 +281,7 @@ def cron_preview(request):
it = croniter(schedule, now_naive)
for i in range(0, 6):
naive = it.get_next(datetime)
aware = timezone.make_aware(naive)
aware = timezone.make_aware(naive, is_dst=True)
ctx["dates"].append((naive, aware))
except UnknownTimeZoneError:
ctx["bad_tz"] = True


Loading…
Cancel
Save