|
1 | 1 | import time
|
2 | 2 | from datetime import timedelta
|
3 | 3 |
|
| 4 | +import time_machine |
4 | 5 | from django.core.exceptions import ValidationError
|
5 | 6 | from django.test import TransactionTestCase
|
6 | 7 | from django.utils import timezone
|
@@ -137,3 +138,45 @@ def test_end_time_and_max_number_of_executions_validation(self):
|
137 | 138 | p_task.max_number_of_executions = 42
|
138 | 139 | p_task.end_time = timezone.now()
|
139 | 140 | self.assertRaises(ValidationError, p_task.save)
|
| 141 | + |
| 142 | + |
| 143 | +class TestSkipPeriodicFutureTasks(TransactionTestCase): |
| 144 | + """Test class for IntegrityError handling without background command threading""" |
| 145 | + |
| 146 | + @time_machine.travel("2025-01-01 12:00:00+0000", tick=False) |
| 147 | + def test_populate_skips_duplicate_task_id_integrity_error(self): |
| 148 | + # Create periodic task that will generate tasks |
| 149 | + PeriodicFutureTask.objects.create( |
| 150 | + periodic_task_id="Fetch Data", |
| 151 | + type=settings.FUTURE_TASK_TYPE_ONE, |
| 152 | + cron_string="0 * * * *", |
| 153 | + last_task_creation=timezone.now() - timedelta(hours=2), |
| 154 | + ) |
| 155 | + |
| 156 | + # Create conflicting task that will cause IntegrityError |
| 157 | + conflicting_task_id = "Fetch Data (2025-01-01 12:00:00+0000)" |
| 158 | + FutureTask.objects.create( |
| 159 | + task_id=conflicting_task_id, |
| 160 | + eta=timezone.now(), |
| 161 | + type=settings.FUTURE_TASK_TYPE_ONE, |
| 162 | + ) |
| 163 | + |
| 164 | + initial_task_count = FutureTask.objects.count() |
| 165 | + |
| 166 | + # Run populate command and verify IntegrityError handling |
| 167 | + from django_future_tasks.management.commands.populate_periodic_future_tasks import ( |
| 168 | + Command, |
| 169 | + ) |
| 170 | + |
| 171 | + command = Command() |
| 172 | + command.tick = 1 |
| 173 | + |
| 174 | + with self.assertLogs( |
| 175 | + "populate_periodic_future_tasks", |
| 176 | + level="WARNING", |
| 177 | + ) as log_capture: |
| 178 | + command.handle_tick() |
| 179 | + |
| 180 | + # Verify warning was logged and task count unchanged |
| 181 | + self.assertIn("Skipping duplicate task", log_capture.records[0].getMessage()) |
| 182 | + self.assertEqual(FutureTask.objects.count(), initial_task_count) |
0 commit comments