Add index and classifier status
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
import os
|
||||
from unittest import mock
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from paperless import version
|
||||
|
||||
|
||||
class TestSystemStatusView(APITestCase):
|
||||
class TestSystemStatus(APITestCase):
|
||||
ENDPOINT = "/api/status/"
|
||||
|
||||
def setUp(self):
|
||||
@@ -67,3 +69,46 @@ class TestSystemStatusView(APITestCase):
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["tasks"]["celery_status"], "OK")
|
||||
|
||||
@override_settings(INDEX_DIR="/tmp/index")
|
||||
@mock.patch("whoosh.index.FileIndex.last_modified")
|
||||
def test_system_status_index_ok(self, mock_last_modified):
|
||||
mock_last_modified.return_value = 1707839087
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["tasks"]["index_status"], "OK")
|
||||
self.assertIsNotNone(response.data["tasks"]["index_last_modified"])
|
||||
|
||||
@override_settings(INDEX_DIR="/tmp/index/")
|
||||
@mock.patch("documents.index.open_index", autospec=True)
|
||||
def test_system_status_index_error(self, mock_open_index):
|
||||
mock_open_index.return_value = None
|
||||
mock_open_index.side_effect = Exception("Index error")
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
mock_open_index.assert_called_once()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["tasks"]["index_status"], "ERROR")
|
||||
self.assertIsNotNone(response.data["tasks"]["index_error"])
|
||||
|
||||
@override_settings(MODEL_FILE="/tmp/does_not_exist")
|
||||
def test_system_status_classifier_ok(self):
|
||||
with open(settings.MODEL_FILE, "w") as f:
|
||||
f.write("test")
|
||||
f.close()
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["tasks"]["classifier_status"], "OK")
|
||||
self.assertIsNone(response.data["tasks"]["classifier_error"])
|
||||
|
||||
@override_settings(MODEL_FILE="/tmp/does_not_exist")
|
||||
@mock.patch("documents.classifier.load_classifier")
|
||||
def test_system_status_classifier_error(self, mock_load_classifier):
|
||||
mock_load_classifier.side_effect = Exception("Classifier error")
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["tasks"]["classifier_status"], "ERROR")
|
||||
self.assertIsNotNone(response.data["tasks"]["classifier_error"])
|
||||
|
||||
@@ -35,6 +35,7 @@ from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.timezone import make_aware
|
||||
from django.utils.translation import get_language
|
||||
from django.views import View
|
||||
from django.views.decorators.cache import cache_control
|
||||
@@ -66,6 +67,7 @@ from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
from rest_framework.viewsets import ViewSet
|
||||
|
||||
from documents import bulk_edit
|
||||
from documents import index
|
||||
from documents.bulk_download import ArchiveOnlyStrategy
|
||||
from documents.bulk_download import OriginalAndArchiveStrategy
|
||||
from documents.bulk_download import OriginalsOnlyStrategy
|
||||
@@ -1595,13 +1597,39 @@ class SystemStatusView(GenericAPIView, PassUserMixin):
|
||||
redis_error = "Error connecting to redis, check logs for more detail."
|
||||
|
||||
try:
|
||||
ping = celery_app.control.inspect().ping()
|
||||
first_worker_ping = ping[next(iter(ping.keys()))]
|
||||
celery_ping = celery_app.control.inspect().ping()
|
||||
first_worker_ping = celery_ping[next(iter(celery_ping.keys()))]
|
||||
if first_worker_ping["ok"] == "pong":
|
||||
celery_active = "OK"
|
||||
except Exception:
|
||||
celery_active = "ERROR"
|
||||
|
||||
index_error = None
|
||||
try:
|
||||
ix = index.open_index()
|
||||
index_status = "OK"
|
||||
index_last_modified = make_aware(
|
||||
datetime.fromtimestamp(ix.last_modified()),
|
||||
)
|
||||
except Exception as e:
|
||||
index_status = "ERROR"
|
||||
index_error = "Error opening index, check logs for more detail."
|
||||
logger.exception(f"System status error opening index: {e}")
|
||||
index_last_modified = None
|
||||
|
||||
classifier_error = None
|
||||
try:
|
||||
load_classifier()
|
||||
classifier_status = "OK"
|
||||
classifier_last_modified = make_aware(
|
||||
datetime.fromtimestamp(os.path.getmtime(settings.MODEL_FILE)),
|
||||
)
|
||||
except Exception as e:
|
||||
classifier_status = "ERROR"
|
||||
classifier_last_modified = None
|
||||
classifier_error = "Error loading classifier, check logs for more detail."
|
||||
logger.exception(f"System status error loading classifier: {e}")
|
||||
|
||||
return Response(
|
||||
{
|
||||
"pngx_version": current_version,
|
||||
@@ -1628,6 +1656,12 @@ class SystemStatusView(GenericAPIView, PassUserMixin):
|
||||
"redis_status": redis_status,
|
||||
"redis_error": redis_error,
|
||||
"celery_status": celery_active,
|
||||
"index_status": index_status,
|
||||
"index_last_modified": index_last_modified,
|
||||
"index_error": index_error,
|
||||
"classifier_status": classifier_status,
|
||||
"classifier_last_modified": classifier_last_modified,
|
||||
"classifier_error": classifier_error,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user