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.

188 lines
6.3 KiB

  1. from datetime import timedelta as td
  2. from django.test import Client
  3. from django.utils.timezone import now
  4. from hc.api.models import Check, Flip, Ping
  5. from hc.test import BaseTestCase
  6. class PingTestCase(BaseTestCase):
  7. def setUp(self):
  8. super().setUp()
  9. self.check = Check.objects.create(project=self.project)
  10. def test_it_works(self):
  11. r = self.client.get("/ping/%s/" % self.check.code)
  12. self.assertEqual(r.status_code, 200)
  13. self.check.refresh_from_db()
  14. self.assertEqual(self.check.status, "up")
  15. expected_aa = self.check.last_ping + td(days=1, hours=1)
  16. self.assertEqual(self.check.alert_after, expected_aa)
  17. ping = Ping.objects.latest("id")
  18. self.assertEqual(ping.scheme, "http")
  19. self.assertEqual(ping.kind, None)
  20. def test_it_changes_status_of_paused_check(self):
  21. self.check.status = "paused"
  22. self.check.save()
  23. r = self.client.get("/ping/%s/" % self.check.code)
  24. self.assertEqual(r.status_code, 200)
  25. self.check.refresh_from_db()
  26. self.assertEqual(self.check.status, "up")
  27. def test_it_clears_last_start(self):
  28. self.check.last_start = now()
  29. self.check.save()
  30. r = self.client.get("/ping/%s/" % self.check.code)
  31. self.assertEqual(r.status_code, 200)
  32. self.check.refresh_from_db()
  33. self.assertEqual(self.check.last_start, None)
  34. def test_post_works(self):
  35. csrf_client = Client(enforce_csrf_checks=True)
  36. r = csrf_client.post(
  37. "/ping/%s/" % self.check.code, "hello world", content_type="text/plain"
  38. )
  39. self.assertEqual(r.status_code, 200)
  40. ping = Ping.objects.latest("id")
  41. self.assertEqual(ping.method, "POST")
  42. self.assertEqual(ping.body, "hello world")
  43. def test_head_works(self):
  44. csrf_client = Client(enforce_csrf_checks=True)
  45. r = csrf_client.head("/ping/%s/" % self.check.code)
  46. self.assertEqual(r.status_code, 200)
  47. self.assertEqual(Ping.objects.count(), 1)
  48. def test_it_handles_bad_uuid(self):
  49. r = self.client.get("/ping/not-uuid/")
  50. self.assertEqual(r.status_code, 404)
  51. def test_it_rejects_alternative_uuid_formats(self):
  52. # This uuid is missing separators. uuid.UUID() would accept it.
  53. r = self.client.get("/ping/07c2f54898504b27af5d6c9dc157ec02/")
  54. self.assertEqual(r.status_code, 404)
  55. def test_it_handles_missing_check(self):
  56. r = self.client.get("/ping/07c2f548-9850-4b27-af5d-6c9dc157ec02/")
  57. self.assertEqual(r.status_code, 404)
  58. def test_it_handles_120_char_ua(self):
  59. ua = (
  60. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) "
  61. "AppleWebKit/537.36 (KHTML, like Gecko) "
  62. "Chrome/44.0.2403.89 Safari/537.36"
  63. )
  64. r = self.client.get("/ping/%s/" % self.check.code, HTTP_USER_AGENT=ua)
  65. self.assertEqual(r.status_code, 200)
  66. ping = Ping.objects.latest("id")
  67. self.assertEqual(ping.ua, ua)
  68. def test_it_truncates_long_ua(self):
  69. ua = "01234567890" * 30
  70. r = self.client.get("/ping/%s/" % self.check.code, HTTP_USER_AGENT=ua)
  71. self.assertEqual(r.status_code, 200)
  72. ping = Ping.objects.latest("id")
  73. self.assertEqual(len(ping.ua), 200)
  74. assert ua.startswith(ping.ua)
  75. def test_it_reads_forwarded_ip(self):
  76. ip = "1.1.1.1"
  77. r = self.client.get("/ping/%s/" % self.check.code, HTTP_X_FORWARDED_FOR=ip)
  78. ping = Ping.objects.latest("id")
  79. self.assertEqual(r.status_code, 200)
  80. self.assertEqual(ping.remote_addr, "1.1.1.1")
  81. ip = "1.1.1.1, 2.2.2.2"
  82. r = self.client.get(
  83. "/ping/%s/" % self.check.code,
  84. HTTP_X_FORWARDED_FOR=ip,
  85. REMOTE_ADDR="3.3.3.3",
  86. )
  87. ping = Ping.objects.latest("id")
  88. self.assertEqual(r.status_code, 200)
  89. self.assertEqual(ping.remote_addr, "1.1.1.1")
  90. def test_it_reads_forwarded_protocol(self):
  91. r = self.client.get(
  92. "/ping/%s/" % self.check.code, HTTP_X_FORWARDED_PROTO="https"
  93. )
  94. ping = Ping.objects.latest("id")
  95. self.assertEqual(r.status_code, 200)
  96. self.assertEqual(ping.scheme, "https")
  97. def test_it_never_caches(self):
  98. r = self.client.get("/ping/%s/" % self.check.code)
  99. assert "no-cache" in r.get("Cache-Control")
  100. def test_it_updates_confirmation_flag(self):
  101. payload = "Please Confirm ..."
  102. r = self.client.post(
  103. "/ping/%s/" % self.check.code, data=payload, content_type="text/plain"
  104. )
  105. self.assertEqual(r.status_code, 200)
  106. self.check.refresh_from_db()
  107. self.assertTrue(self.check.has_confirmation_link)
  108. def test_fail_endpoint_works(self):
  109. r = self.client.get("/ping/%s/fail" % self.check.code)
  110. self.assertEqual(r.status_code, 200)
  111. self.check.refresh_from_db()
  112. self.assertEqual(self.check.status, "down")
  113. self.assertEqual(self.check.alert_after, None)
  114. ping = Ping.objects.get()
  115. self.assertEqual(ping.kind, "fail")
  116. flip = Flip.objects.get()
  117. self.assertEqual(flip.owner, self.check)
  118. self.assertEqual(flip.new_status, "down")
  119. def test_start_endpoint_works(self):
  120. last_ping = now() - td(hours=2)
  121. self.check.last_ping = last_ping
  122. self.check.save()
  123. r = self.client.get("/ping/%s/start" % self.check.code)
  124. self.assertEqual(r.status_code, 200)
  125. self.check.refresh_from_db()
  126. self.assertTrue(self.check.last_start)
  127. self.assertEqual(self.check.last_ping, last_ping)
  128. ping = Ping.objects.get()
  129. self.assertEqual(ping.kind, "start")
  130. def test_start_does_not_change_status_of_paused_check(self):
  131. self.check.status = "paused"
  132. self.check.save()
  133. r = self.client.get("/ping/%s/start" % self.check.code)
  134. self.assertEqual(r.status_code, 200)
  135. self.check.refresh_from_db()
  136. self.assertTrue(self.check.last_start)
  137. self.assertEqual(self.check.status, "paused")
  138. def test_it_sets_last_duration(self):
  139. self.check.last_start = now() - td(seconds=10)
  140. self.check.save()
  141. r = self.client.get("/ping/%s/" % self.check.code)
  142. self.assertEqual(r.status_code, 200)
  143. self.check.refresh_from_db()
  144. self.assertTrue(self.check.last_duration.total_seconds() >= 10)