Skip to content

Commit ba4d793

Browse files
committed
Improve test coverage
1 parent cebbd9f commit ba4d793

File tree

6 files changed

+53
-17
lines changed

6 files changed

+53
-17
lines changed

django_tasks/backends/base.py

+7-11
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,14 @@ def __init__(self, alias: str, params: dict) -> None:
4141
def _get_enqueue_on_commit_for_task(self, task: Task) -> bool:
4242
"""
4343
Determine the correct `enqueue_on_commit` setting to use for a given task.
44-
45-
If the task defines it, use that, otherwise, fall back to the backend.
4644
"""
47-
# If this project doesn't use a database, there's nothing to commit to
48-
if not connections.settings:
49-
return False
50-
51-
if task.enqueue_on_commit is not None:
52-
return task.enqueue_on_commit
5345

54-
return self.enqueue_on_commit
46+
# If the task defines it, use that, otherwise, fall back to the backend.
47+
return (
48+
task.enqueue_on_commit
49+
if task.enqueue_on_commit is not None
50+
else self.enqueue_on_commit
51+
)
5552

5653
def validate_task(self, task: Task) -> None:
5754
"""
@@ -121,8 +118,7 @@ async def aget_result(self, result_id: str) -> TaskResult:
121118

122119
def check(self, **kwargs: Any) -> Iterable[messages.CheckMessage]:
123120
if self.enqueue_on_commit and not connections.settings:
124-
yield messages.CheckMessage(
125-
messages.ERROR,
121+
yield messages.Error(
126122
"`ENQUEUE_ON_COMMIT` cannot be used when no databases are configured",
127123
hint="Set `ENQUEUE_ON_COMMIT` to False",
128124
)

django_tasks/backends/database/backend.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ def check(self, **kwargs: Any) -> Iterable[messages.CheckMessage]:
8888
backend_name = self.__class__.__name__
8989

9090
if not apps.is_installed("django_tasks.backends.database"):
91-
yield messages.CheckMessage(
92-
messages.ERROR,
91+
yield messages.Error(
9392
f"{backend_name} configured as django_tasks backend, but database app not installed",
9493
"Insert 'django_tasks.backends.database' in INSTALLED_APPS",
9594
)
@@ -102,8 +101,7 @@ def check(self, **kwargs: Any) -> Iterable[messages.CheckMessage]:
102101
django.VERSION >= (5, 1)
103102
and connection_requires_manual_exclusive_transaction(db_connection)
104103
):
105-
yield messages.CheckMessage(
106-
messages.ERROR,
104+
yield messages.Error(
107105
f"{backend_name} is using SQLite non-exclusive transactions",
108106
f"Set settings.DATABASES[{db_connection.alias!r}]['OPTIONS']['transaction_mode'] to 'EXCLUSIVE'",
109107
)

tests/tests/test_database_backend.py

+16
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,22 @@ def test_database_backend_app_missing(self) -> None:
264264
self.assertEqual(len(errors), 1)
265265
self.assertIn("django_tasks.backends.database", errors[0].hint) # type:ignore[arg-type]
266266

267+
@skipIf(
268+
connection.vendor != "sqlite", "Transaction mode is only applicable on SQLite"
269+
)
270+
def test_check_non_exclusive_transaction(self) -> None:
271+
try:
272+
with mock.patch.dict(
273+
connection.settings_dict["OPTIONS"], {"transaction_mode": None}
274+
):
275+
errors = list(default_task_backend.check())
276+
277+
self.assertEqual(len(errors), 1)
278+
self.assertIn("['transaction_mode'] to 'EXCLUSIVE'", errors[0].hint) # type:ignore[arg-type]
279+
finally:
280+
connection.close()
281+
connection.get_connection_params()
282+
267283
def test_priority_range_check(self) -> None:
268284
with self.assertRaises(IntegrityError):
269285
DBTaskResult.objects.create(

tests/tests/test_dummy_backend.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import json
22
from typing import cast
3+
from unittest import mock
34

45
from django.db import transaction
5-
from django.test import SimpleTestCase, TransactionTestCase, override_settings
6+
from django.test import (
7+
SimpleTestCase,
8+
TransactionTestCase,
9+
override_settings,
10+
)
611
from django.urls import reverse
712

813
from django_tasks import ResultStatus, Task, default_task_backend, tasks
914
from django_tasks.backends.dummy import DummyBackend
10-
from django_tasks.exceptions import ResultDoesNotExist
15+
from django_tasks.exceptions import InvalidTaskError, ResultDoesNotExist
1116
from tests import tasks as test_tasks
1217

1318

@@ -162,6 +167,13 @@ def test_exceptions(self) -> None:
162167
with self.assertRaisesMessage(ValueError, "Task has not finished yet"):
163168
result.traceback # noqa: B018
164169

170+
def test_validate_disallowed_async_task(self) -> None:
171+
with mock.patch.multiple(default_task_backend, supports_async_task=False):
172+
with self.assertRaisesMessage(
173+
InvalidTaskError, "Backend does not support async tasks"
174+
):
175+
default_task_backend.validate_task(test_tasks.noop_task_async)
176+
165177

166178
class DummyBackendTransactionTestCase(TransactionTestCase):
167179
@override_settings(

tests/tests/test_tasks.py

+6
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ def test_invalid_priority(self) -> None:
176176
test_tasks.noop_task.using(priority=-100)
177177
test_tasks.noop_task.using(priority=0)
178178

179+
def test_unknown_queue_name(self) -> None:
180+
with self.assertRaisesMessage(
181+
InvalidTaskError, "Queue 'queue-2' is not valid for backend"
182+
):
183+
test_tasks.noop_task.using(queue_name="queue-2")
184+
179185
def test_call_task(self) -> None:
180186
self.assertEqual(test_tasks.calculate_meaning_of_life.call(), 42)
181187

tests/tests/test_utils.py

+8
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ def test_keeps_return_value(self) -> None:
7373
self.assertTrue(utils.retry()(lambda: True)())
7474
self.assertFalse(utils.retry()(lambda: False)())
7575

76+
def test_skip_retry_on_keyboard_interrupt(self) -> None:
77+
sentinel = Mock(side_effect=KeyboardInterrupt(""))
78+
79+
with self.assertRaises(KeyboardInterrupt):
80+
utils.retry()(sentinel)()
81+
82+
self.assertEqual(sentinel.call_count, 1)
83+
7684

7785
class RandomIdTestCase(SimpleTestCase):
7886
def test_correct_length(self) -> None:

0 commit comments

Comments
 (0)