You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
5.2 KiB

  1. from datetime import timedelta as td
  2. from io import StringIO
  3. from mock import Mock, patch
  4. from django.core.management import call_command
  5. from django.utils.timezone import now
  6. from hc.api.management.commands.sendalerts import Command, notify
  7. from hc.api.models import Flip, Check
  8. from hc.test import BaseTestCase
  9. class SendAlertsTestCase(BaseTestCase):
  10. def test_it_handles_grace_period(self):
  11. check = Check(user=self.alice, status="up")
  12. # 1 day 30 minutes after ping the check is in grace period:
  13. check.last_ping = now() - td(days=1, minutes=30)
  14. check.alert_after = check.last_ping + td(days=1, hours=1)
  15. check.save()
  16. Command().handle_going_down()
  17. check.refresh_from_db()
  18. self.assertEqual(check.status, "up")
  19. self.assertEqual(Flip.objects.count(), 0)
  20. def test_it_creates_a_flip_when_check_goes_down(self):
  21. check = Check(user=self.alice, status="up")
  22. check.last_ping = now() - td(days=2)
  23. check.alert_after = check.last_ping + td(days=1, hours=1)
  24. check.save()
  25. result = Command().handle_going_down()
  26. # If it finds work, it should return True
  27. self.assertTrue(result)
  28. # It should create a flip object
  29. flip = Flip.objects.get()
  30. self.assertEqual(flip.owner_id, check.id)
  31. self.assertEqual(flip.created, check.alert_after)
  32. self.assertEqual(flip.new_status, "down")
  33. # It should change stored status to "down", and clear out alert_after
  34. check.refresh_from_db()
  35. self.assertEqual(check.status, "down")
  36. self.assertEqual(check.alert_after, None)
  37. @patch("hc.api.management.commands.sendalerts.notify_on_thread")
  38. def test_it_processes_flip(self, mock_notify):
  39. check = Check(user=self.alice, status="up")
  40. check.last_ping = now()
  41. check.alert_after = check.last_ping + td(days=1, hours=1)
  42. check.save()
  43. flip = Flip(owner=check, created=check.last_ping)
  44. flip.old_status = "down"
  45. flip.new_status = "up"
  46. flip.save()
  47. result = Command().process_one_flip()
  48. # If it finds work, it should return True
  49. self.assertTrue(result)
  50. # It should set the processed date
  51. flip.refresh_from_db()
  52. self.assertTrue(flip.processed)
  53. # It should call `notify_on_thread`
  54. self.assertTrue(mock_notify.called)
  55. @patch("hc.api.management.commands.sendalerts.notify_on_thread")
  56. def test_it_updates_alert_after(self, mock_notify):
  57. check = Check(user=self.alice, status="up")
  58. check.last_ping = now() - td(hours=1)
  59. check.alert_after = check.last_ping
  60. check.save()
  61. result = Command().handle_going_down()
  62. # If it finds work, it should return True
  63. self.assertTrue(result)
  64. # alert_after should have been increased
  65. expected_aa = check.last_ping + td(days=1, hours=1)
  66. check.refresh_from_db()
  67. self.assertEqual(check.alert_after, expected_aa)
  68. # a flip should have not been created
  69. self.assertEqual(Flip.objects.count(), 0)
  70. @patch("hc.api.management.commands.sendalerts.notify")
  71. def test_it_works_synchronously(self, mock_notify):
  72. check = Check(user=self.alice, status="up")
  73. check.last_ping = now() - td(days=2)
  74. check.alert_after = check.last_ping + td(days=1, hours=1)
  75. check.save()
  76. call_command("sendalerts", loop=False, use_threads=False,
  77. stdout=StringIO())
  78. # It should call `notify` instead of `notify_on_thread`
  79. self.assertTrue(mock_notify.called)
  80. def test_it_updates_owners_next_nag_date(self):
  81. self.profile.nag_period = td(hours=1)
  82. self.profile.save()
  83. check = Check(user=self.alice, status="down")
  84. check.last_ping = now() - td(days=2)
  85. check.save()
  86. flip = Flip(owner=check, created=check.last_ping)
  87. flip.old_status = "up"
  88. flip.new_status = "down"
  89. flip.save()
  90. notify(flip.id, Mock())
  91. self.profile.refresh_from_db()
  92. self.assertIsNotNone(self.profile.next_nag_date)
  93. def test_it_updates_members_next_nag_date(self):
  94. self.bobs_profile.nag_period = td(hours=1)
  95. self.bobs_profile.save()
  96. check = Check(user=self.alice, status="down")
  97. check.last_ping = now() - td(days=2)
  98. check.save()
  99. flip = Flip(owner=check, created=check.last_ping)
  100. flip.old_status = "up"
  101. flip.new_status = "down"
  102. flip.save()
  103. notify(flip.id, Mock())
  104. self.bobs_profile.refresh_from_db()
  105. self.assertIsNotNone(self.bobs_profile.next_nag_date)
  106. def test_it_does_not_touch_already_set_next_nag_dates(self):
  107. original_nag_date = now() - td(minutes=30)
  108. self.profile.nag_period = td(hours=1)
  109. self.profile.next_nag_date = original_nag_date
  110. self.profile.save()
  111. check = Check(user=self.alice, status="down")
  112. check.last_ping = now() - td(days=2)
  113. check.save()
  114. flip = Flip(owner=check, created=check.last_ping)
  115. flip.old_status = "up"
  116. flip.new_status = "down"
  117. flip.save()
  118. notify(flip.id, Mock())
  119. self.profile.refresh_from_db()
  120. self.assertEqual(self.profile.next_nag_date, original_nag_date)