|
1 | | -import pytest |
2 | | -import datetime |
3 | | - |
| 1 | +import contextlib |
| 2 | +from datetime import timedelta |
4 | 3 | from unittest import mock |
5 | 4 |
|
| 5 | +import pytest |
6 | 6 | from django.utils import timezone |
7 | 7 |
|
8 | 8 | from share.celery import TaskResultCleaner, CeleryTaskResult |
9 | | - |
10 | 9 | from tests import factories |
11 | 10 |
|
12 | 11 |
|
13 | | -@pytest.mark.usefixtures('nested_django_db') |
14 | | -class TestResultArchiver: |
| 12 | +@contextlib.contextmanager |
| 13 | +def long_now(new_now=None): |
| 14 | + _now = new_now or timezone.now() |
| 15 | + with mock.patch.object(timezone, 'now', return_value=_now): |
| 16 | + yield _now |
15 | 17 |
|
16 | | - @pytest.fixture(scope='class', autouse=True) |
17 | | - def task_result_data(self, class_scoped_django_db): |
18 | | - return factories.CeleryTaskResultFactory.create_batch(100) |
| 18 | + |
| 19 | +@pytest.mark.django_db |
| 20 | +class TestResultCleaner: |
19 | 21 |
|
20 | 22 | def test_delete_false(self): |
21 | | - trc = TaskResultCleaner(datetime.timedelta(weeks=520), delete=False) |
| 23 | + factories.CeleryTaskResultFactory.create_batch(10) |
| 24 | + trc = TaskResultCleaner(timedelta(weeks=520), delete=False) |
22 | 25 | assert trc.delete_queryset(CeleryTaskResult.objects.all()) == 0 |
23 | | - assert CeleryTaskResult.objects.count() != 0 |
| 26 | + assert CeleryTaskResult.objects.count() == 10 |
24 | 27 |
|
25 | 28 | def test_delete_queryset(self): |
26 | | - trc = TaskResultCleaner(datetime.timedelta(weeks=520)) |
27 | | - assert trc.delete_queryset(CeleryTaskResult.objects.all()) == 100 |
| 29 | + factories.CeleryTaskResultFactory.create_batch(10) |
| 30 | + trc = TaskResultCleaner(timedelta(weeks=520)) |
| 31 | + assert trc.delete_queryset(CeleryTaskResult.objects.all()) == 10 |
28 | 32 | assert CeleryTaskResult.objects.count() == 0 |
29 | 33 |
|
30 | | - def test_get_ttl_default(self): |
31 | | - trc = TaskResultCleaner(datetime.timedelta(weeks=520)) |
32 | | - assert ((timezone.now() - datetime.timedelta(weeks=520)) - trc.get_ttl('non-existant-task')) < datetime.timedelta(seconds=2) |
33 | | - |
34 | | - def test_get_ttl(self): |
35 | | - trc = TaskResultCleaner(datetime.timedelta(weeks=520)) |
36 | | - trc.TASK_TTLS['existant-task'] = datetime.timedelta(days=1) |
37 | | - assert ((timezone.now() - datetime.timedelta(days=1)) - trc.get_ttl('existant-task')) < datetime.timedelta(seconds=2) |
38 | | - |
39 | | - def test_clean(self): |
40 | | - trc = TaskResultCleaner(0, bucket=mock.Mock()) |
41 | | - factories.CeleryTaskResultFactory.create_batch(100, status='SUCCESS') |
42 | | - trc.clean() |
43 | | - assert CeleryTaskResult.objects.count() <= 100 # There's an autouse fixture that makes 100 |
44 | | - |
45 | | - def test_clean_chunksize(self): |
46 | | - trc = TaskResultCleaner(0, bucket=mock.Mock(), chunk_size=1) |
47 | | - factories.CeleryTaskResultFactory.create_batch(100, status='SUCCESS') |
48 | | - trc.clean() |
49 | | - assert CeleryTaskResult.objects.count() <= 100 # There's an autouse fixture that makes 100 |
| 34 | + def test_success_cutoff(self, settings): |
| 35 | + with long_now() as _now: |
| 36 | + trc = TaskResultCleaner(timedelta(days=3).total_seconds()) |
| 37 | + _expected = _now - timedelta(days=3) |
| 38 | + assert trc.success_cutoff == _expected |
| 39 | + |
| 40 | + def test_nonsuccess_cutoff(self, settings): |
| 41 | + with long_now() as _now: |
| 42 | + trc = TaskResultCleaner( |
| 43 | + success_ttl=timedelta(days=3), |
| 44 | + nonsuccess_ttl=timedelta(days=5), |
| 45 | + ) |
| 46 | + assert trc.success_cutoff == _now - timedelta(days=3) |
| 47 | + assert trc.nonsuccess_cutoff == _now - timedelta(days=5) |
| 48 | + |
| 49 | + @pytest.mark.parametrize('batch_size', [1, 1111]) |
| 50 | + def test_clean(self, batch_size): |
| 51 | + with long_now() as _now: |
| 52 | + with long_now(_now - timedelta(days=7)): |
| 53 | + # all should be deleted: |
| 54 | + factories.CeleryTaskResultFactory.create_batch(10, status='SUCCESS') |
| 55 | + factories.CeleryTaskResultFactory.create_batch(7, status='FAILED') |
| 56 | + with long_now(_now - timedelta(days=4)): |
| 57 | + # successes should be deleted: |
| 58 | + factories.CeleryTaskResultFactory.create_batch(10, status='SUCCESS') |
| 59 | + factories.CeleryTaskResultFactory.create_batch(7, status='FAILED') |
| 60 | + # none should be deleted: |
| 61 | + factories.CeleryTaskResultFactory.create_batch(10, status='SUCCESS') |
| 62 | + factories.CeleryTaskResultFactory.create_batch(7, status='FAILED') |
| 63 | + # end setup |
| 64 | + assert CeleryTaskResult.objects.count() == 51 |
| 65 | + trc = TaskResultCleaner( |
| 66 | + success_ttl=timedelta(days=3), |
| 67 | + nonsuccess_ttl=timedelta(days=5), |
| 68 | + chunk_size=batch_size, |
| 69 | + ) |
| 70 | + trc.clean() |
| 71 | + assert CeleryTaskResult.objects.filter(status='SUCCESS').count() == 10 |
| 72 | + assert CeleryTaskResult.objects.exclude(status='SUCCESS').count() == 14 |
0 commit comments