tests: general cleanup and fixes for runnning under docker

This now allows tests to be run under a locally built or production
docker image with something like:

  `docker run --rm -v $PWD:/usr/src/paperless --entrypoint=bash paperlessngx/paperless-ngx:latest -c "uv run pytest"`

Specific fixes:
- fix unreachable code around `assertRaises` blocks
- fix `assertInt` typos
- fix `str(e)` vs `str(e.exception)` issues
- skip permission-based checks when root (in a docker container)
- catch `OSError` problems when instantiating `INotify` and
  skip inotify-based tests when it's unavailable.
This commit is contained in:
Ed Bardsley 2025-11-14 05:51:09 +00:00
parent dd6f7fad32
commit 7b220f737f
11 changed files with 103 additions and 39 deletions

View file

@ -5,6 +5,7 @@ from threading import Thread
from time import sleep
from unittest import mock
import pytest
from django.conf import settings
from django.core.management import CommandError
from django.core.management import call_command
@ -18,6 +19,14 @@ from documents.models import Tag
from documents.tests.utils import DirectoriesMixin
from documents.tests.utils import DocumentConsumeDelayMixin
try:
from inotifyrecursive import INotify
INotify()
SKIP_INOTIFY_TESTS = False
except (ImportError, OSError):
SKIP_INOTIFY_TESTS = True
class ConsumerThread(Thread):
def __init__(self):
@ -108,10 +117,10 @@ class ConsumerThreadMixin(DocumentConsumeDelayMixin):
print("file completed.") # noqa: T201
@override_settings(
CONSUMER_INOTIFY_DELAY=0.01,
)
class TestConsumer(DirectoriesMixin, ConsumerThreadMixin, TransactionTestCase):
class _TestConsumerBase(DirectoriesMixin, ConsumerThreadMixin):
# Note: adding TransactionTestCase as a base makes pytest discover this
# class. Only add it to the actual test classes.
def test_consume_file(self):
self.t_start()
@ -365,6 +374,14 @@ class TestConsumer(DirectoriesMixin, ConsumerThreadMixin, TransactionTestCase):
self.consume_file_mock.assert_not_called()
@override_settings(
CONSUMER_INOTIFY_DELAY=0.01,
)
@pytest.mark.skipif(SKIP_INOTIFY_TESTS, reason="no inotify")
class TestConsumer(_TestConsumerBase, TransactionTestCase):
pass
@override_settings(
CONSUMER_POLLING=1,
# please leave the delay here and down below
@ -372,13 +389,14 @@ class TestConsumer(DirectoriesMixin, ConsumerThreadMixin, TransactionTestCase):
CONSUMER_POLLING_DELAY=3,
CONSUMER_POLLING_RETRY_COUNT=20,
)
class TestConsumerPolling(TestConsumer):
class TestConsumerPolling(_TestConsumerBase, TransactionTestCase):
# just do all the tests with polling
pass
@override_settings(CONSUMER_INOTIFY_DELAY=0.01, CONSUMER_RECURSIVE=True)
class TestConsumerRecursive(TestConsumer):
@pytest.mark.skipif(SKIP_INOTIFY_TESTS, reason="no inotify")
class TestConsumerRecursive(_TestConsumerBase, TransactionTestCase):
# just do all the tests with recursive
pass
@ -389,14 +407,14 @@ class TestConsumerRecursive(TestConsumer):
CONSUMER_POLLING_DELAY=3,
CONSUMER_POLLING_RETRY_COUNT=20,
)
class TestConsumerRecursivePolling(TestConsumer):
class TestConsumerRecursivePolling(_TestConsumerBase, TransactionTestCase):
# just do all the tests with polling and recursive
pass
@override_settings(CONSUMER_RECURSIVE=True, CONSUMER_SUBDIRS_AS_TAGS=True)
class TestConsumerTags(DirectoriesMixin, ConsumerThreadMixin, TransactionTestCase):
@override_settings(CONSUMER_RECURSIVE=True, CONSUMER_SUBDIRS_AS_TAGS=True)
def test_consume_file_with_path_tags(self):
def _test_consume_file_with_path_tags(self):
tag_names = ("existingTag", "Space Tag")
# Create a Tag prior to consuming a file using it in path
tag_ids = [
@ -429,10 +447,14 @@ class TestConsumerTags(DirectoriesMixin, ConsumerThreadMixin, TransactionTestCas
# their order.
self.assertCountEqual(overrides.tag_ids, tag_ids)
@pytest.mark.skipif(SKIP_INOTIFY_TESTS, reason="no inotify")
def test_consume_file_with_path_tags(self):
self._test_consume_file_with_path_tags()
@override_settings(
CONSUMER_POLLING=1,
CONSUMER_POLLING_DELAY=3,
CONSUMER_POLLING_RETRY_COUNT=20,
)
def test_consume_file_with_path_tags_polling(self):
self.test_consume_file_with_path_tags()
self._test_consume_file_with_path_tags()