From 45d7f2018a19948d36036efd8dc22c411add64da Mon Sep 17 00:00:00 2001 From: djperrefort Date: Sun, 11 Aug 2024 16:16:10 -0400 Subject: [PATCH] Use mock to control time values in logging tests --- .../tests/tasks/test_rotate_log_files.py | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/keystone_api/apps/logging/tests/tasks/test_rotate_log_files.py b/keystone_api/apps/logging/tests/tasks/test_rotate_log_files.py index 374dd87f..c6f63610 100644 --- a/keystone_api/apps/logging/tests/tasks/test_rotate_log_files.py +++ b/keystone_api/apps/logging/tests/tasks/test_rotate_log_files.py @@ -1,8 +1,10 @@ """Unit tests for the `rotate_log_files` task.""" -from time import sleep +from datetime import datetime, timedelta +from unittest.mock import Mock, patch from django.test import override_settings, TestCase +from django.utils.timezone import now from apps.logging.models import AppLog, RequestLog from apps.logging.tasks import rotate_log_files @@ -11,40 +13,57 @@ class LogFileDeletion(TestCase): """Test the deletion of log records.""" - def create_dummy_records(self) -> None: - """Create a single record in each logging database table.""" + def create_dummy_records(self, timestamp: datetime) -> None: + """Create a single record in each logging database table. + + Args: + timestamp: The creation time of the records. + """ AppLog.objects.create( name='mock.log.test', level=10, pathname='/test', lineno=100, - message='This is a log' + message='This is a log', + time=timestamp ) + RequestLog.objects.create( endpoint='/api', response_code=200, body_request='', - body_response='' + body_response='', + time=timestamp ) @override_settings(LOG_RECORD_ROTATION=4) - def test_log_files_rotated(self) -> None: + @patch('django.utils.timezone.now') + def test_log_files_rotated(self, mock_now: Mock) -> None: """Test expired log files are deleted.""" - # Create a set of older and younger records - self.create_dummy_records() - sleep(2) - self.create_dummy_records() + # Mock the current time + initial_time = now() + mock_now.return_value = initial_time + + # Create an older set of records + self.create_dummy_records(timestamp=initial_time) - # Make sure records exist + # Simulate the passage of time + later_time = initial_time + timedelta(seconds=5) + mock_now.return_value = later_time + + # Create a newer set of records + self.create_dummy_records(timestamp=later_time) + + # Ensure records exist self.assertEqual(2, AppLog.objects.count()) self.assertEqual(2, RequestLog.objects.count()) - # Wait for first set of records to expire - # Assert only the expired records are removed - sleep(2) + # Run rotation rotate_log_files() + + # Assert only the newer records remain self.assertEqual(1, AppLog.objects.count()) self.assertEqual(1, RequestLog.objects.count()) @@ -52,7 +71,7 @@ def test_log_files_rotated(self) -> None: def test_rotation_disabled(self) -> None: """Test log files are not deleted when rotation is disabled.""" - self.create_dummy_records() + self.create_dummy_records(now()) rotate_log_files() self.assertEqual(1, AppLog.objects.count())