Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-django-health-check for openSUSE:Factory checked in at 2021-12-26 15:30:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-django-health-check (Old) and /work/SRC/openSUSE:Factory/.python-django-health-check.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-health-check" Sun Dec 26 15:30:37 2021 rev:7 rq:942600 version:3.16.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-django-health-check/python-django-health-check.changes 2020-09-21 17:20:49.599808566 +0200 +++ /work/SRC/openSUSE:Factory/.python-django-health-check.new.2520/python-django-health-check.changes 2021-12-26 15:30:38.079366853 +0100 @@ -1,0 +2,24 @@ +Sun Dec 26 12:08:51 UTC 2021 - John Vandenberg <jay...@gmail.com> + +- Use django-codemod to finish Django 4 compatibility +- Update to 3.16.5 + * Fix default_app_config RemovedInDjango41Warning warning + * Fix Django 4 Exception 'never_cache didn't receive an HttpRequest' +- from v3.16.4 + * Add default_auto_field to satisfy Django 4.0 +- from v3.16.2 + * Fix text alignment for time column in Safari +- from v3.16.1 + * Fix Celery ping health check functionality with multiple workers +- from v3.16.0 + * Add second celery health chat that uses ping instead of executing a task +- from v3.15.0 + * Split celery timeout into two separate settings +- from v3.14.3 + * Use default cache timeout instead of 1s +- from v3.14.2 + * Resolve Django 4.0 deprecation warnings +- from v3.14.1 + * Revert "Clean results task Health Check" + +------------------------------------------------------------------- Old: ---- django-health-check-3.14.0.tar.gz New: ---- django-health-check-3.16.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-django-health-check.spec ++++++ --- /var/tmp/diff_new_pack.PasyBh/_old 2021-12-26 15:30:38.707367148 +0100 +++ /var/tmp/diff_new_pack.PasyBh/_new 2021-12-26 15:30:38.719367153 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-django-health-check # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,13 +19,14 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-django-health-check -Version: 3.14.0 +Version: 3.16.5 Release: 0 Summary: Run checks on Django and is dependent services License: MIT URL: https://github.com/KristianOellegaard/django-health-check Source: https://github.com/KristianOellegaard/django-health-check/archive/%{version}.tar.gz#/django-health-check-%{version}.tar.gz BuildRequires: %{python_module Django >= 1.11} +BuildRequires: %{python_module django-codemod} BuildRequires: %{python_module celery} BuildRequires: %{python_module mock} BuildRequires: %{python_module pytest-django} @@ -57,12 +58,18 @@ # do not nedlessly pull extra deps sed -i -e '/sphinx/d;/pytest-runner/d;/--cov[-=]/d' setup.cfg +# Workaround https://github.com/KristianOellegaard/django-health-check/pull/315 +djcodemod run --removed-in 4.0 tests/testapp/urls.py health_check/urls.py + %build %python_build %install %python_install -%{python_expand rm -r %{buildroot}%{$python_sitelib}/tests/ +%{python_expand # https://github.com/KristianOellegaard/django-health-check/issues/268 +rm -rf %{buildroot}%{$python_sitelib}/tests/ +if [[ -f %{buildroot}%{$python_sitelib}/health_check/templates/health_check/index.html ]]; then false; fi +ls %{buildroot}%{$python_sitelib}/health_check/cache/ mkdir -p %{buildroot}%{$python_sitelib}/health_check/templates/health_check cp health_check/templates/health_check/index.html %{buildroot}%{$python_sitelib}/health_check/templates/health_check %fdupes %{buildroot}%{$python_sitelib} @@ -79,6 +86,6 @@ %files %{python_files} %doc README.rst %license LICENSE -%{python_sitelib}/* +%{python_sitelib}/*health[-_]check*/ %changelog ++++++ django-health-check-3.14.0.tar.gz -> django-health-check-3.16.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/.github/workflows/ci.yml new/django-health-check-3.16.5/.github/workflows/ci.yml --- old/django-health-check-3.14.0/.github/workflows/ci.yml 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/.github/workflows/ci.yml 2021-12-09 09:33:44.000000000 +0100 @@ -36,6 +36,8 @@ django-version: - 2.2.* - 3.1.* + - 3.2.* + - 4.* steps: - uses: actions/checkout@v2 - name: Setup Python version ${{ matrix.python-version }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/README.rst new/django-health-check-3.16.5/README.rst --- old/django-health-check-3.14.0/README.rst 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/README.rst 2021-12-09 09:33:44.000000000 +0100 @@ -15,6 +15,7 @@ - disk and memory utilization (via ``psutil``) - AWS S3 storage - Celery task queue +- Celery ping - RabbitMQ - Migrations @@ -70,10 +71,11 @@ 'health_check.storage', 'health_check.contrib.migrations', 'health_check.contrib.celery', # requires celery + 'health_check.contrib.celery_ping', # requires celery 'health_check.contrib.psutil', # disk and memory utilization; requires psutil 'health_check.contrib.s3boto3_storage', # requires boto3 and S3BotoStorage backend 'health_check.contrib.rabbitmq', # requires RabbitMQ broker - 'health_check.contrib.redis', # required Redis broker + 'health_check.contrib.redis', # requires Redis broker ] Note : If using ``boto 2.x.x`` use ``health_check.contrib.s3boto_storage`` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/docs/contrib.rst new/django-health-check-3.16.5/docs/contrib.rst --- old/django-health-check-3.14.0/docs/contrib.rst 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/docs/contrib.rst 2021-12-09 09:33:44.000000000 +0100 @@ -35,3 +35,24 @@ 'DISK_USAGE_MAX': 90, # percent 'MEMORY_MIN' = 100, # in MB } + +``celery`` +---------- + +If you are using Celery you may choose between two different Celery checks. + +`health_check.contrib.celery` sends a task to the queue and it expects that task +to be executed in `HEALTHCHECK_CELERY_TIMEOUT` seconds which by default is three seconds. +You may override that in your Django settings module. This check is suitable for use cases +which require that tasks can be processed frequently all the time. + +`health_check.contrib.celery_ping` is a different check. It checks that each predefined +Celery task queue has a consumer (i.e. worker) that responds `{"ok": "pong"}` in +`HEALTHCHECK_CELERY_PING_TIMEOUT` seconds. The default for this is one second. +You may override that in your Django settings module. This check is suitable for use cases +which don't require that tasks are executed almost instantly but require that they are going +to be executed in sometime the future i.e. that the worker process is alive and processing tasks +all the time. + +You may also use both of them. To use these checks add them to `INSTALLED_APPS` in your +Django settings module. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/docs/settings.rst new/django-health-check-3.16.5/docs/settings.rst --- old/django-health-check-3.14.0/docs/settings.rst 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/docs/settings.rst 2021-12-09 09:33:44.000000000 +0100 @@ -69,3 +69,24 @@ Specify the desired memory utilization threshold, in megabytes. When available memory falls below the specified value, a warning will be reported. + +Celery Health Check +---------------------- +Using `django.settings` you may exert more fine-grained control over the behavior of the celery health check + +.. list-table:: Additional Settings + :widths: 25 10 10 55 + :header-rows: 1 + + * - Name + - Type + - Default + - Description + * - `HEALTHCHECK_CELERY_QUEUE_TIMEOUT` + - Number + - 3 + - Specifies the maximum amount of time a task may spend in the queue before being automatically revoked with a `TaskRevokedError`. + * - `HEALTHCHECK_CELERY_RESULT_TIMEOUT` + - Number + - 3 + - Specifies the maximum total time for a task to complete and return a result, including queue time. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/cache/__init__.py new/django-health-check-3.16.5/health_check/cache/__init__.py --- old/django-health-check-3.14.0/health_check/cache/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/cache/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.cache.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.cache.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/cache/backends.py new/django-health-check-3.16.5/health_check/cache/backends.py --- old/django-health-check-3.14.0/health_check/cache/backends.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/cache/backends.py 2021-12-09 09:33:44.000000000 +0100 @@ -18,7 +18,7 @@ cache = caches[self.backend] try: - cache.set('djangohealtcheck_test', 'itworks', 1) + cache.set('djangohealtcheck_test', 'itworks') if not cache.get("djangohealtcheck_test") == "itworks": raise ServiceUnavailable("Cache key does not match") except CacheKeyWarning as e: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/celery/__init__.py new/django-health-check-3.16.5/health_check/contrib/celery/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/celery/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/celery/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.celery.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.celery.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/celery/apps.py new/django-health-check-3.16.5/health_check/contrib/celery/apps.py --- old/django-health-check-3.14.0/health_check/contrib/celery/apps.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/celery/apps.py 2021-12-09 09:33:44.000000000 +0100 @@ -1,5 +1,8 @@ from celery import current_app from django.apps import AppConfig +from django.conf import settings +import warnings + from health_check.plugins import plugin_dir @@ -9,6 +12,10 @@ def ready(self): from .backends import CeleryHealthCheck + if hasattr(settings, "HEALTHCHECK_CELERY_TIMEOUT"): + warnings.warn("HEALTHCHECK_CELERY_TIMEOUT is depricated and may be removed in the " + "future. Please use HEALTHCHECK_CELERY_RESULT_TIMEOUT and " + "HEALTHCHECK_CELERY_QUEUE_TIMEOUT instead.", DeprecationWarning) for queue in current_app.amqp.queues: celery_class_name = 'CeleryHealthCheck' + queue.title() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/celery/backends.py new/django-health-check-3.16.5/health_check/contrib/celery/backends.py --- old/django-health-check-3.14.0/health_check/contrib/celery/backends.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/celery/backends.py 2021-12-09 09:33:44.000000000 +0100 @@ -6,25 +6,32 @@ ) from .tasks import add +from celery.exceptions import TaskRevokedError, TimeoutError class CeleryHealthCheck(BaseHealthCheckBackend): def check_status(self): timeout = getattr(settings, 'HEALTHCHECK_CELERY_TIMEOUT', 3) + result_timeout = getattr(settings, 'HEALTHCHECK_CELERY_RESULT_TIMEOUT', timeout) + queue_timeout = getattr(settings, 'HEALTHCHECK_CELERY_QUEUE_TIMEOUT', timeout) try: result = add.apply_async( args=[4, 4], - expires=timeout, + expires=queue_timeout, queue=self.queue ) - result.get(timeout=timeout) + result.get(timeout=result_timeout) if result.result != 8: self.add_error(ServiceReturnedUnexpectedResult("Celery returned wrong result")) - add.forget() except IOError as e: self.add_error(ServiceUnavailable("IOError"), e) except NotImplementedError as e: self.add_error(ServiceUnavailable("NotImplementedError: Make sure CELERY_RESULT_BACKEND is set"), e) + except TaskRevokedError as e: + self.add_error(ServiceUnavailable("TaskRevokedError: The task was revoked, likely because it spent " + "too long in the queue"), e) + except TimeoutError as e: + self.add_error(ServiceUnavailable("TimeoutError: The task took too long to return a result"), e) except BaseException as e: self.add_error(ServiceUnavailable("Unknown error"), e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/celery_ping/__init__.py new/django-health-check-3.16.5/health_check/contrib/celery_ping/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/celery_ping/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/django-health-check-3.16.5/health_check/contrib/celery_ping/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -0,0 +1,4 @@ +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.celery_ping.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/celery_ping/apps.py new/django-health-check-3.16.5/health_check/contrib/celery_ping/apps.py --- old/django-health-check-3.14.0/health_check/contrib/celery_ping/apps.py 1970-01-01 01:00:00.000000000 +0100 +++ new/django-health-check-3.16.5/health_check/contrib/celery_ping/apps.py 2021-12-09 09:33:44.000000000 +0100 @@ -0,0 +1,12 @@ +from django.apps import AppConfig + +from health_check.plugins import plugin_dir + + +class HealthCheckConfig(AppConfig): + name = 'health_check.contrib.celery_ping' + + def ready(self): + from .backends import CeleryPingHealthCheck + + plugin_dir.register(CeleryPingHealthCheck) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/celery_ping/backends.py new/django-health-check-3.16.5/health_check/contrib/celery_ping/backends.py --- old/django-health-check-3.14.0/health_check/contrib/celery_ping/backends.py 1970-01-01 01:00:00.000000000 +0100 +++ new/django-health-check-3.16.5/health_check/contrib/celery_ping/backends.py 2021-12-09 09:33:44.000000000 +0100 @@ -0,0 +1,67 @@ +from celery.app import default_app as app +from django.conf import settings + +from health_check.backends import BaseHealthCheckBackend +from health_check.exceptions import ServiceUnavailable + + +class CeleryPingHealthCheck(BaseHealthCheckBackend): + CORRECT_PING_RESPONSE = {"ok": "pong"} + + def check_status(self): + timeout = getattr(settings, "HEALTHCHECK_CELERY_PING_TIMEOUT", 1) + + try: + ping_result = app.control.ping(timeout=timeout) + except IOError as e: + self.add_error(ServiceUnavailable("IOError"), e) + except NotImplementedError as exc: + self.add_error( + ServiceUnavailable( + "NotImplementedError: Make sure CELERY_RESULT_BACKEND is set" + ), + exc, + ) + except BaseException as exc: + self.add_error(ServiceUnavailable("Unknown error"), exc) + else: + if not ping_result: + self.add_error( + ServiceUnavailable("Celery workers unavailable"), + ) + else: + self._check_ping_result(ping_result) + + def _check_ping_result(self, ping_result): + active_workers = [] + + for result in ping_result: + worker, response = list(result.items())[0] + if response != self.CORRECT_PING_RESPONSE: + self.add_error( + ServiceUnavailable( + f"Celery worker {worker} response was incorrect" + ), + ) + continue + active_workers.append(worker) + + if not self.errors: + self._check_active_queues(active_workers) + + def _check_active_queues(self, active_workers): + defined_queues = app.conf.CELERY_QUEUES + + if not defined_queues: + return + + defined_queues = set([queue.name for queue in defined_queues]) + active_queues = set() + + for queues in app.control.inspect(active_workers).active_queues().values(): + active_queues.update([queue.get("name") for queue in queues]) + + for queue in defined_queues.difference(active_queues): + self.add_error( + ServiceUnavailable(f"No worker for Celery task queue {queue}"), + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/migrations/__init__.py new/django-health-check-3.16.5/health_check/contrib/migrations/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/migrations/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/migrations/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.migrations.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.migrations.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/psutil/__init__.py new/django-health-check-3.16.5/health_check/contrib/psutil/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/psutil/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/psutil/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.psutil.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.psutil.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/rabbitmq/__init__.py new/django-health-check-3.16.5/health_check/contrib/rabbitmq/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/rabbitmq/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/rabbitmq/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.rabbitmq.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.rabbitmq.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/redis/__init__.py new/django-health-check-3.16.5/health_check/contrib/redis/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/redis/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/redis/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.redis.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.redis.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/s3boto3_storage/__init__.py new/django-health-check-3.16.5/health_check/contrib/s3boto3_storage/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/s3boto3_storage/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/s3boto3_storage/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.s3boto3_storage.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.s3boto3_storage.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/contrib/s3boto_storage/__init__.py new/django-health-check-3.16.5/health_check/contrib/s3boto_storage/__init__.py --- old/django-health-check-3.14.0/health_check/contrib/s3boto_storage/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/contrib/s3boto_storage/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.contrib.s3boto_storage.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.contrib.s3boto_storage.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/db/__init__.py new/django-health-check-3.16.5/health_check/db/__init__.py --- old/django-health-check-3.14.0/health_check/db/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/db/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.db.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.db.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/db/apps.py new/django-health-check-3.16.5/health_check/db/apps.py --- old/django-health-check-3.14.0/health_check/db/apps.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/db/apps.py 2021-12-09 09:33:44.000000000 +0100 @@ -4,6 +4,7 @@ class HealthCheckConfig(AppConfig): + default_auto_field = 'django.db.models.AutoField' name = 'health_check.db' def ready(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/storage/__init__.py new/django-health-check-3.16.5/health_check/storage/__init__.py --- old/django-health-check-3.14.0/health_check/storage/__init__.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/storage/__init__.py 2021-12-09 09:33:44.000000000 +0100 @@ -1 +1,4 @@ -default_app_config = 'health_check.storage.apps.HealthCheckConfig' +import django + +if django.VERSION < (3, 2): + default_app_config = 'health_check.storage.apps.HealthCheckConfig' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/templates/health_check/index.html new/django-health-check-3.16.5/health_check/templates/health_check/index.html --- old/django-health-check-3.14.0/health_check/templates/health_check/index.html 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/templates/health_check/index.html 2021-12-09 09:33:44.000000000 +0100 @@ -13,7 +13,7 @@ <tr class="w3-blue"> <th colspan="2">Service</th> <th>Status</th> - <th class="w3-hide-small w3-hide-medium w3-right">Time Taken</th> + <th class="w3-hide-small w3-hide-medium w3-right w3-right-align">Time Taken</th> </tr> {% for plugin in plugins %} <tr> @@ -26,7 +26,7 @@ </td> <td>{{ plugin.identifier }}</td> <td>{{ plugin.pretty_status }}</td> - <td class="w3-hide-small w3-hide-medium w3-right">{{ plugin.time_taken|floatformat:4 }} seconds</td> + <td class="w3-hide-small w3-hide-medium w3-right w3-right-align">{{ plugin.time_taken|floatformat:4 }} seconds</td> </tr> {% endfor %} </table> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/urls.py new/django-health-check-3.16.5/health_check/urls.py --- old/django-health-check-3.14.0/health_check/urls.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/urls.py 2021-12-09 09:33:44.000000000 +0100 @@ -1,9 +1,9 @@ -from django.conf.urls import url +from django.urls import path from health_check.views import MainView app_name = 'health_check' urlpatterns = [ - url(r'^$', MainView.as_view(), name='health_check_home'), + path('', MainView.as_view(), name='health_check_home'), ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/health_check/views.py new/django-health-check-3.16.5/health_check/views.py --- old/django-health-check-3.14.0/health_check/views.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/health_check/views.py 2021-12-09 09:33:44.000000000 +0100 @@ -1,6 +1,7 @@ import re from django.http import HttpResponse, JsonResponse +from django.utils.decorators import method_decorator from django.views.decorators.cache import never_cache from django.views.generic import TemplateView @@ -80,7 +81,7 @@ class MainView(CheckMixin, TemplateView): template_name = 'health_check/index.html' - @never_cache + @method_decorator(never_cache) def get(self, request, *args, **kwargs): status_code = 500 if self.errors else 200 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/setup.cfg new/django-health-check-3.16.5/setup.cfg --- old/django-health-check-3.14.0/setup.cfg 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/setup.cfg 2021-12-09 09:33:44.000000000 +0100 @@ -10,10 +10,18 @@ classifier = Development Status :: 5 - Production/Stable Framework :: Django + Framework :: Django :: 2.2 + Framework :: Django :: 3.1 + Framework :: Django :: 3.2 Intended Audience :: Developers License :: OSI Approved :: MIT License Operating System :: OS Independent + Programming Language :: Python Programming Language :: Python :: 3 + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 Topic :: Software Development :: Quality Assurance Topic :: System :: Logging Topic :: System :: Monitoring @@ -26,7 +34,7 @@ include_package_data = True packages = health_check install_requires = - django>=1.11 + django>=2.2 setup_requires = setuptools_scm sphinx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/tests/test_autodiscover.py new/django-health-check-3.16.5/tests/test_autodiscover.py --- old/django-health-check-3.14.0/tests/test_autodiscover.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/tests/test_autodiscover.py 2021-12-09 09:33:44.000000000 +0100 @@ -2,17 +2,20 @@ from django.conf import settings from health_check.contrib.celery.backends import CeleryHealthCheck +from health_check.contrib.celery_ping.backends import CeleryPingHealthCheck from health_check.plugins import plugin_dir class TestAutoDiscover: + def test_autodiscover(self): health_check_plugins = list(filter( - lambda x: 'health_check.' in x and 'celery' not in x, + lambda x: x.startswith('health_check.') and 'celery' not in x, settings.INSTALLED_APPS )) - non_celery_plugins = [x for x in plugin_dir._registry if not issubclass(x[0], CeleryHealthCheck)] + non_celery_plugins = [x for x in plugin_dir._registry + if not issubclass(x[0], (CeleryHealthCheck, CeleryPingHealthCheck))] # The number of installed apps excluding celery should equal to all plugins except celery assert len(non_celery_plugins) == len(health_check_plugins) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/tests/test_celery_ping.py new/django-health-check-3.16.5/tests/test_celery_ping.py --- old/django-health-check-3.14.0/tests/test_celery_ping.py 1970-01-01 01:00:00.000000000 +0100 +++ new/django-health-check-3.16.5/tests/test_celery_ping.py 2021-12-09 09:33:44.000000000 +0100 @@ -0,0 +1,131 @@ +import pytest +from django.apps import apps +from django.conf import settings +from mock import patch + +from health_check.contrib.celery_ping.apps import HealthCheckConfig +from health_check.contrib.celery_ping.backends import CeleryPingHealthCheck + + +class TestCeleryPingHealthCheck: + CELERY_APP_CONTROL_PING = ( + "health_check.contrib.celery_ping.backends.app.control.ping" + ) + CELERY_APP_CONTROL_INSPECT_ACTIVE_QUEUES = ( + "health_check.contrib.celery_ping.backends.app.control.inspect.active_queues" + ) + + @pytest.fixture + def health_check(self): + return CeleryPingHealthCheck() + + def test_check_status_doesnt_add_errors_when_ping_successfull(self, health_check): + celery_worker = "celery@4cc150a7b49b" + + with patch( + self.CELERY_APP_CONTROL_PING, + return_value=[ + {celery_worker: CeleryPingHealthCheck.CORRECT_PING_RESPONSE}, + {f"{celery_worker}-2": CeleryPingHealthCheck.CORRECT_PING_RESPONSE}, + ], + ), patch( + self.CELERY_APP_CONTROL_INSPECT_ACTIVE_QUEUES, + return_value={ + celery_worker: [ + {"name": queue.name} for queue in settings.CELERY_QUEUES + ] + }, + ): + health_check.check_status() + + assert not health_check.errors + + def test_check_status_reports_errors_if_ping_responses_are_incorrect( + self, health_check + ): + with patch( + self.CELERY_APP_CONTROL_PING, + return_value=[ + {"celery1@4cc150a7b49b": CeleryPingHealthCheck.CORRECT_PING_RESPONSE}, + {"celery2@4cc150a7b49b": {}}, + {"celery3@4cc150a7b49b": {"error": "pong"}}, + ], + ): + health_check.check_status() + + assert len(health_check.errors) == 2 + + def test_check_status_adds_errors_when_ping_successfull_but_not_all_defined_queues_have_consumers( + self, + health_check, + ): + celery_worker = "celery@4cc150a7b49b" + queues = list(settings.CELERY_QUEUES) + + with patch( + self.CELERY_APP_CONTROL_PING, + return_value=[{celery_worker: CeleryPingHealthCheck.CORRECT_PING_RESPONSE}], + ), patch( + self.CELERY_APP_CONTROL_INSPECT_ACTIVE_QUEUES, + return_value={celery_worker: [{"name": queues.pop().name}]}, + ): + health_check.check_status() + + assert len(health_check.errors) == len(queues) + + @pytest.mark.parametrize( + "exception_to_raise", + [ + IOError, + TimeoutError, + ], + ) + def test_check_status_add_error_when_io_error_raised_from_ping( + self, exception_to_raise, health_check + ): + with patch(self.CELERY_APP_CONTROL_PING, side_effect=exception_to_raise): + health_check.check_status() + + assert len(health_check.errors) == 1 + assert "ioerror" in health_check.errors[0].message.lower() + + @pytest.mark.parametrize( + "exception_to_raise", [ValueError, SystemError, IndexError, MemoryError] + ) + def test_check_status_add_error_when_any_exception_raised_from_ping( + self, exception_to_raise, health_check + ): + with patch(self.CELERY_APP_CONTROL_PING, side_effect=exception_to_raise): + health_check.check_status() + + assert len(health_check.errors) == 1 + assert health_check.errors[0].message.lower() == "unknown error" + + def test_check_status_when_raised_exception_notimplementederror(self, health_check): + expected_error_message = ( + "notimplementederror: make sure celery_result_backend is set" + ) + + with patch(self.CELERY_APP_CONTROL_PING, side_effect=NotImplementedError): + health_check.check_status() + + assert len(health_check.errors) == 1 + assert health_check.errors[0].message.lower() == expected_error_message + + @pytest.mark.parametrize("ping_result", [None, list()]) + def test_check_status_add_error_when_ping_result_failed( + self, ping_result, health_check + ): + with patch(self.CELERY_APP_CONTROL_PING, return_value=ping_result): + health_check.check_status() + + assert len(health_check.errors) == 1 + assert "workers unavailable" in health_check.errors[0].message.lower() + + +class TestCeleryPingHealthCheckApps: + def test_apps(self): + assert HealthCheckConfig.name == "health_check.contrib.celery_ping" + + celery_ping = apps.get_app_config("celery_ping") + assert celery_ping.name == "health_check.contrib.celery_ping" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/tests/testapp/celery.py new/django-health-check-3.16.5/tests/testapp/celery.py --- old/django-health-check-3.14.0/tests/testapp/celery.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/tests/testapp/celery.py 2021-12-09 09:33:44.000000000 +0100 @@ -1,4 +1,4 @@ from celery import Celery -app = Celery('testapp') +app = Celery('testapp', broker='memory://') app.config_from_object('django.conf:settings', namespace='CELERY') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-health-check-3.14.0/tests/testapp/settings.py new/django-health-check-3.16.5/tests/testapp/settings.py --- old/django-health-check-3.14.0/tests/testapp/settings.py 2020-09-16 08:01:23.000000000 +0200 +++ new/django-health-check-3.16.5/tests/testapp/settings.py 2021-12-09 09:33:44.000000000 +0100 @@ -2,6 +2,8 @@ import os.path import uuid +from kombu import Queue + BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DEBUG = True @@ -28,6 +30,7 @@ 'health_check.storage', 'health_check.contrib.celery', 'health_check.contrib.migrations', + 'health_check.contrib.celery_ping', 'health_check.contrib.s3boto_storage', 'tests', ) @@ -59,7 +62,7 @@ USE_L10N = True -CELERY_TASK_QUEUES = { - 'default': {}, - 'queue2': {} -} +CELERY_QUEUES = [ + Queue('default'), + Queue('queue2'), +]