Skip to content

Commit 9cb8198

Browse files
committed
Use centralized check runner in Django
1 parent d27b778 commit 9cb8198

File tree

2 files changed

+61
-41
lines changed

2 files changed

+61
-41
lines changed

src/dockerflow/django/views.py

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
# License, v. 2.0. If a copy of the MPL was not distributed with this
33
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
44
from django.conf import settings
5-
from django.core import checks
5+
from django.core.checks.registry import registry as django_check_registry
66
from django.http import HttpResponse, HttpResponseNotFound, JsonResponse
77
from django.utils.module_loading import import_string
88

9-
from .checks import level_to_text
9+
from dockerflow import checks
10+
1011
from .signals import heartbeat_failed, heartbeat_passed
1112

1213
version_callback = getattr(
@@ -42,42 +43,25 @@ def heartbeat(request):
4243
Any check that returns a warning or worse (error, critical) will
4344
return a 500 response.
4445
"""
45-
all_checks = checks.registry.registry.get_checks(
46-
include_deployment_checks=not settings.DEBUG
46+
checks_to_run = (
47+
(check.__name__, lambda: check(app_configs=None))
48+
for check in django_check_registry.get_checks(
49+
include_deployment_checks=not settings.DEBUG
50+
)
4751
)
48-
49-
details = {}
50-
statuses = {}
51-
level = 0
52-
53-
for check in all_checks:
54-
detail = heartbeat_check_detail(check)
55-
statuses[check.__name__] = detail["status"]
56-
level = max(level, detail["level"])
57-
if detail["level"] > 0:
58-
details[check.__name__] = detail
59-
60-
if level < checks.messages.ERROR:
52+
check_results = checks.run_checks(
53+
checks_to_run,
54+
silenced_check_ids=settings.SILENCED_SYSTEM_CHECKS,
55+
)
56+
if check_results.level < checks.ERROR:
6157
status_code = 200
62-
heartbeat_passed.send(sender=heartbeat, level=level)
58+
heartbeat_passed.send(sender=heartbeat, level=check_results.level)
6359
else:
6460
status_code = 500
65-
heartbeat_failed.send(sender=heartbeat, level=level)
61+
heartbeat_failed.send(sender=heartbeat, level=check_results.level)
6662

67-
payload = {"status": level_to_text(level)}
63+
payload = {"status": checks.level_to_text(check_results.level)}
6864
if settings.DEBUG:
69-
payload["checks"] = statuses
70-
payload["details"] = details
65+
payload["checks"] = check_results.statuses
66+
payload["details"] = check_results.details
7167
return JsonResponse(payload, status=status_code)
72-
73-
74-
def heartbeat_check_detail(check):
75-
errors = check(app_configs=None)
76-
errors = list(filter(lambda e: e.id not in settings.SILENCED_SYSTEM_CHECKS, errors))
77-
level = max([0] + [e.level for e in errors])
78-
79-
return {
80-
"status": level_to_text(level),
81-
"level": level,
82-
"messages": {e.id: e.msg for e in errors},
83-
}

tests/django/test_django.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,55 @@ def test_version_missing(dockerflow_middleware, mocker, rf):
5050

5151

5252
@pytest.mark.django_db
53-
def test_heartbeat(dockerflow_middleware, reset_checks, rf, settings):
54-
request = rf.get("/__heartbeat__")
55-
response = dockerflow_middleware.process_request(request)
53+
def test_heartbeat(client, settings):
54+
response = client.get("/__heartbeat__")
5655
assert response.status_code == 200
5756

5857
settings.DOCKERFLOW_CHECKS = [
5958
"tests.django.django_checks.warning",
6059
"tests.django.django_checks.error",
6160
]
6261
checks.register()
63-
response = dockerflow_middleware.process_request(request)
62+
response = client.get("/__heartbeat__")
63+
assert response.status_code == 500
64+
content = response.json()
65+
assert content["status"] == "error"
66+
assert content.get("checks") is None
67+
assert content.get("details") is None
68+
69+
70+
@pytest.mark.django_db
71+
def test_heartbeat_debug(client, settings):
72+
settings.DOCKERFLOW_CHECKS = [
73+
"tests.django.django_checks.warning",
74+
"tests.django.django_checks.error",
75+
]
76+
settings.DEBUG = True
77+
checks.register()
78+
response = client.get("/__heartbeat__")
6479
assert response.status_code == 500
80+
content = response.json()
81+
assert content["status"]
82+
assert content["checks"]
83+
assert content["details"]
84+
85+
86+
@pytest.mark.django_db
87+
def test_heartbeat_silenced(client, settings):
88+
settings.DOCKERFLOW_CHECKS = [
89+
"tests.django.django_checks.warning",
90+
"tests.django.django_checks.error",
91+
]
92+
settings.SILENCED_SYSTEM_CHECKS.append("tests.checks.E001")
93+
settings.DEBUG = True
94+
checks.register()
95+
96+
response = client.get("/__heartbeat__")
97+
assert response.status_code == 200
98+
content = response.json()
99+
assert content["status"] == "warning"
100+
assert "warning" in content["details"]
101+
assert "error" not in content["details"]
65102

66103

67104
@pytest.mark.django_db
@@ -75,11 +112,10 @@ def test_lbheartbeat_makes_no_db_queries(dockerflow_middleware, rf):
75112

76113

77114
@pytest.mark.django_db
78-
def test_redis_check(dockerflow_middleware, reset_checks, rf, settings):
115+
def test_redis_check(client, settings):
79116
settings.DOCKERFLOW_CHECKS = ["dockerflow.django.checks.check_redis_connected"]
80117
checks.register()
81-
request = rf.get("/__heartbeat__")
82-
response = dockerflow_middleware.process_request(request)
118+
response = client.get("/__heartbeat__")
83119
assert response.status_code == 200
84120

85121

0 commit comments

Comments
 (0)