From a1fa9134af4f7b7a01895b8c1f7c418447f0d8cc Mon Sep 17 00:00:00 2001 From: Gagan Deep Date: Tue, 21 Jan 2025 17:29:10 +0530 Subject: [PATCH] [chores] Added check for OPENWISP_MONITORING_WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE --- openwisp_monitoring/check/apps.py | 1 + openwisp_monitoring/check/checks.py | 76 ++++++++++++++++ openwisp_monitoring/check/tests/test_utils.py | 89 ++++++++++++++++++- 3 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 openwisp_monitoring/check/checks.py diff --git a/openwisp_monitoring/check/apps.py b/openwisp_monitoring/check/apps.py index 7518271d5..e07c36795 100644 --- a/openwisp_monitoring/check/apps.py +++ b/openwisp_monitoring/check/apps.py @@ -3,6 +3,7 @@ from django.utils.translation import gettext_lazy as _ from swapper import load_model +from openwisp_monitoring.check import checks # noqa from openwisp_monitoring.check import settings as app_settings diff --git a/openwisp_monitoring/check/checks.py b/openwisp_monitoring/check/checks.py new file mode 100644 index 000000000..e80146d4a --- /dev/null +++ b/openwisp_monitoring/check/checks.py @@ -0,0 +1,76 @@ +from datetime import datetime + +from django.core.checks import Error, register + +from . import settings as app_settings + + +@register() +def check_wifi_clients_snooze_schedule(app_configs, **kwargs): + errors = [] + setting_name = 'OPENWISP_MONITORING_WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE' + schedule = app_settings.WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE + + if not isinstance(schedule, (list, tuple)): + errors.append( + Error( + 'Invalid schedule format', + hint='Schedule must be a list of date-time ranges', + obj=setting_name, + ) + ) + return errors + + for item in schedule: + if not isinstance(item, (list, tuple)) or len(item) != 2: + errors.append( + Error( + f'Invalid schedule entry format: {item}', + hint='Each schedule entry must be a pair of start and end times', + obj=setting_name, + ) + ) + continue + + start, end = item + if not isinstance(start, str) or not isinstance(end, str): + errors.append( + Error( + f'Invalid time format: {item}', + hint='Use format "MM-DD HH:MM", "MM-DD", or "HH:MM"', + obj=setting_name, + ) + ) + continue + + try: + # Check if both are time format (HH:MM) + if '-' not in start and '-' not in end: + datetime.strptime(start, '%H:%M') + datetime.strptime(end, '%H:%M') + # Check if both are date format (MM-DD) + elif ':' not in start and ':' not in end: + datetime.strptime(start, '%m-%d') + datetime.strptime(end, '%m-%d') + # Check if both are date-time format (MM-DD HH:MM) + elif len(start.split()) == 2 and len(end.split()) == 2: + datetime.strptime(start, '%m-%d %H:%M') + datetime.strptime(end, '%m-%d %H:%M') + else: + errors.append( + Error( + f'Inconsistent format: {item}', + hint='Both start and end must be in the same format (either both time or both date)', + obj=setting_name, + ) + ) + except ValueError: + errors.append( + Error( + f'Invalid date-time format: {item}', + hint='Use format "MM-DD HH:MM", "MM-DD", or "HH:MM"', + obj=setting_name, + ) + ) + + return errors diff --git a/openwisp_monitoring/check/tests/test_utils.py b/openwisp_monitoring/check/tests/test_utils.py index c83e0993a..be4f1f4bf 100644 --- a/openwisp_monitoring/check/tests/test_utils.py +++ b/openwisp_monitoring/check/tests/test_utils.py @@ -1,10 +1,13 @@ from unittest.mock import patch from django.core import management -from django.test import TransactionTestCase +from django.core.checks import Error +from django.test import TestCase, TransactionTestCase from swapper import load_model from ...device.tests import TestDeviceMonitoringMixin +from .. import settings as app_settings +from ..checks import check_wifi_clients_snooze_schedule from ..classes import Ping from ..settings import CHECK_CLASSES from ..tasks import perform_check @@ -38,3 +41,87 @@ def test_perform_check_task_resiliency(self, mock): check = Check(name='Test check') perform_check.delay(check.pk) mock.assert_called_with(f'The check with uuid {check.pk} has been deleted') + + +class TestCheckWifiClientsSnoozeSchedule(TestCase): + def setUp(self): + self.setting_name = 'OPENWISP_MONITORING_WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE' + + @patch.object(app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', 'invalid_format') + def test_invalid_schedule_format(self): + errors = check_wifi_clients_snooze_schedule(None) + expected_error = Error( + 'Invalid schedule format', + hint='Schedule must be a list of date-time ranges', + obj=self.setting_name, + ) + self.assertIn(expected_error, errors) + + @patch.object( + app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', [('invalid_entry',)] + ) + def test_invalid_schedule_entry_format(self): + errors = check_wifi_clients_snooze_schedule(None) + expected_error = Error( + 'Invalid schedule entry format: (\'invalid_entry\',)', + hint='Each schedule entry must be a pair of start and end times', + obj=self.setting_name, + ) + self.assertIn(expected_error, errors) + + @patch.object( + app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', [('invalid_time', '12:00')] + ) + def test_invalid_date_time_format(self): + errors = check_wifi_clients_snooze_schedule(None) + expected_error = Error( + 'Invalid date-time format: (\'invalid_time\', \'12:00\')', + hint='Use format "MM-DD HH:MM", "MM-DD", or "HH:MM"', + obj=self.setting_name, + ) + self.assertIn(expected_error, errors) + + @patch.object(app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', [(11, 12)]) + def test_invalid_time_format(self): + errors = check_wifi_clients_snooze_schedule(None) + expected_error = Error( + 'Invalid time format: (11, 12)', + hint='Use format "MM-DD HH:MM", "MM-DD", or "HH:MM"', + obj=self.setting_name, + ) + self.assertIn(expected_error, errors) + + @patch.object( + app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', [('12:00', '01-01')] + ) + def test_inconsistent_format(self): + errors = check_wifi_clients_snooze_schedule(None) + expected_error = Error( + 'Inconsistent format: (\'12:00\', \'01-01\')', + hint='Both start and end must be in the same format (either both time or both date)', + obj=self.setting_name, + ) + self.assertIn(expected_error, errors) + + @patch.object( + app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', [('12:00', '13:00')] + ) + def test_valid_time_format(self): + errors = check_wifi_clients_snooze_schedule(None) + self.assertEqual(errors, []) + + @patch.object( + app_settings, 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', [('01-01', '01-02')] + ) + def test_valid_date_format(self): + errors = check_wifi_clients_snooze_schedule(None) + self.assertEqual(errors, []) + + @patch.object( + app_settings, + 'WIFI_CLIENTS_CHECK_SNOOZE_SCHEDULE', + [('01-01 12:00', '01-01 13:00')], + ) + def test_valid_date_time_format(self): + errors = check_wifi_clients_snooze_schedule(None) + self.assertEqual(errors, [])