diff --git a/docs/development.md b/docs/development.md index f724b551f..71ca4d930 100644 --- a/docs/development.md +++ b/docs/development.md @@ -152,19 +152,6 @@ $ ng build --configuration production configuration. This is not ideal. But for now, make sure no settings except for DEBUG are overridden when testing. -- Testing under docker is possible (but generally unsupported) if a - bare-metal environment cannot be setup. To run tests under docker, use - this command: - - ```bash - # paperless-ngx/ - - $ docker run --rm -i -t \ - -v $PWD:/usr/src/paperless \ - --entrypoint=uv paperlessngx/paperless-ngx:latest \ - run pytest - ``` - !!! note The line length rule E501 is generally useful for getting multiple diff --git a/src/documents/management/commands/document_consumer.py b/src/documents/management/commands/document_consumer.py index a541f66c3..97027e02d 100644 --- a/src/documents/management/commands/document_consumer.py +++ b/src/documents/management/commands/document_consumer.py @@ -250,22 +250,10 @@ class Command(BaseCommand): if options["oneshot"]: return - inotify = None if settings.CONSUMER_POLLING == 0 and INotify: - try: - inotify = INotify() - except OSError: - logger.exception("inotify failed to instantiate") - - if inotify: - self.handle_inotify( - inotify, - directory, - recursive, - is_testing=options["testing"], - ) + self.handle_inotify(directory, recursive, is_testing=options["testing"]) else: - if inotify is None and settings.CONSUMER_POLLING == 0: # pragma: no cover + if INotify is None and settings.CONSUMER_POLLING == 0: # pragma: no cover logger.warning("Using polling as INotify import failed") self.handle_polling(directory, recursive, is_testing=options["testing"]) @@ -298,7 +286,7 @@ class Command(BaseCommand): observer.stop() observer.join() - def handle_inotify(self, inotify, directory, recursive, *, is_testing: bool): + def handle_inotify(self, directory, recursive, *, is_testing: bool): logger.info(f"Using inotify to watch directory for changes: {directory}") timeout_ms = None @@ -306,6 +294,7 @@ class Command(BaseCommand): timeout_ms = self.testing_timeout_ms logger.debug(f"Configuring timeout to {timeout_ms}ms") + inotify = INotify() inotify_flags = flags.CLOSE_WRITE | flags.MOVED_TO | flags.MODIFY if recursive: inotify.add_watch_recursive(directory, inotify_flags) diff --git a/src/documents/tests/test_api_status.py b/src/documents/tests/test_api_status.py index f80512a96..9b7bf37ad 100644 --- a/src/documents/tests/test_api_status.py +++ b/src/documents/tests/test_api_status.py @@ -34,7 +34,7 @@ class TestSystemStatus(APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["pngx_version"], version.__full_version_str__) self.assertIsNotNone(response.data["server_os"]) - self.assertIn(response.data["install_type"], ["bare-metal", "docker"]) + self.assertEqual(response.data["install_type"], "bare-metal") self.assertIsNotNone(response.data["storage"]["total"]) self.assertIsNotNone(response.data["storage"]["available"]) self.assertEqual(response.data["database"]["type"], "sqlite") diff --git a/src/documents/tests/test_file_handling.py b/src/documents/tests/test_file_handling.py index 00df33a5b..c0070aa81 100644 --- a/src/documents/tests/test_file_handling.py +++ b/src/documents/tests/test_file_handling.py @@ -26,7 +26,6 @@ from documents.tasks import empty_trash from documents.tests.factories import DocumentFactory from documents.tests.utils import DirectoriesMixin from documents.tests.utils import FileSystemAssertsMixin -from documents.tests.utils import skip_if_root class TestFileHandling(DirectoriesMixin, FileSystemAssertsMixin, TestCase): @@ -90,7 +89,6 @@ class TestFileHandling(DirectoriesMixin, FileSystemAssertsMixin, TestCase): settings.ORIGINALS_DIR / "test" / "test.pdf.gpg", ) - @skip_if_root @override_settings(FILENAME_FORMAT="{correspondent}/{correspondent}") def test_file_renaming_missing_permissions(self): document = Document() diff --git a/src/documents/tests/test_management_consumer.py b/src/documents/tests/test_management_consumer.py index 447de4926..38b9eadda 100644 --- a/src/documents/tests/test_management_consumer.py +++ b/src/documents/tests/test_management_consumer.py @@ -5,7 +5,6 @@ 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 @@ -19,14 +18,6 @@ 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): @@ -117,10 +108,10 @@ class ConsumerThreadMixin(DocumentConsumeDelayMixin): print("file completed.") # noqa: T201 -class _TestConsumerBase(DirectoriesMixin, ConsumerThreadMixin): - # Note: adding TransactionTestCase as a base makes pytest discover this - # class. Only add it to the actual test classes. - +@override_settings( + CONSUMER_INOTIFY_DELAY=0.01, +) +class TestConsumer(DirectoriesMixin, ConsumerThreadMixin, TransactionTestCase): def test_consume_file(self): self.t_start() @@ -374,14 +365,6 @@ class _TestConsumerBase(DirectoriesMixin, ConsumerThreadMixin): 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 @@ -389,14 +372,13 @@ class TestConsumer(_TestConsumerBase, TransactionTestCase): CONSUMER_POLLING_DELAY=3, CONSUMER_POLLING_RETRY_COUNT=20, ) -class TestConsumerPolling(_TestConsumerBase, TransactionTestCase): +class TestConsumerPolling(TestConsumer): # just do all the tests with polling pass @override_settings(CONSUMER_INOTIFY_DELAY=0.01, CONSUMER_RECURSIVE=True) -@pytest.mark.skipif(SKIP_INOTIFY_TESTS, reason="no inotify") -class TestConsumerRecursive(_TestConsumerBase, TransactionTestCase): +class TestConsumerRecursive(TestConsumer): # just do all the tests with recursive pass @@ -407,14 +389,14 @@ class TestConsumerRecursive(_TestConsumerBase, TransactionTestCase): CONSUMER_POLLING_DELAY=3, CONSUMER_POLLING_RETRY_COUNT=20, ) -class TestConsumerRecursivePolling(_TestConsumerBase, TransactionTestCase): +class TestConsumerRecursivePolling(TestConsumer): # 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): - def _test_consume_file_with_path_tags(self): + @override_settings(CONSUMER_RECURSIVE=True, CONSUMER_SUBDIRS_AS_TAGS=True) + 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 = [ @@ -447,14 +429,10 @@ 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() diff --git a/src/documents/tests/test_management_exporter.py b/src/documents/tests/test_management_exporter.py index 6d9ffabd0..b01b8d47e 100644 --- a/src/documents/tests/test_management_exporter.py +++ b/src/documents/tests/test_management_exporter.py @@ -42,7 +42,6 @@ from documents.tests.utils import DirectoriesMixin from documents.tests.utils import FileSystemAssertsMixin from documents.tests.utils import SampleDirMixin from documents.tests.utils import paperless_environment -from documents.tests.utils import skip_if_root from paperless_mail.models import MailAccount @@ -592,7 +591,6 @@ class TestExportImport( self.assertEqual("That path isn't a directory", str(e.exception)) - @skip_if_root def test_export_target_not_writable(self): """ GIVEN: diff --git a/src/documents/tests/test_management_importer.py b/src/documents/tests/test_management_importer.py index 2ae1834a5..004f5ac5f 100644 --- a/src/documents/tests/test_management_importer.py +++ b/src/documents/tests/test_management_importer.py @@ -16,7 +16,6 @@ from documents.settings import EXPORTER_FILE_NAME from documents.tests.utils import DirectoriesMixin from documents.tests.utils import FileSystemAssertsMixin from documents.tests.utils import SampleDirMixin -from documents.tests.utils import skip_if_root class TestCommandImport( @@ -98,7 +97,6 @@ class TestCommandImport( ) self.assertIn('The manifest file refers to "noexist.pdf"', str(e.exception)) - @skip_if_root def test_import_permission_error(self): """ GIVEN: @@ -153,7 +151,6 @@ class TestCommandImport( call_command("document_importer", Path("/tmp/notapath")) self.assertIn("That path doesn't exist", str(cm.exception)) - @skip_if_root def test_import_source_not_readable(self): """ GIVEN: diff --git a/src/documents/tests/test_sanity_check.py b/src/documents/tests/test_sanity_check.py index dc9c881f8..fff5f2528 100644 --- a/src/documents/tests/test_sanity_check.py +++ b/src/documents/tests/test_sanity_check.py @@ -10,7 +10,6 @@ from django.test import override_settings from documents.models import Document from documents.sanity_checker import check_sanity from documents.tests.utils import DirectoriesMixin -from documents.tests.utils import skip_if_root class TestSanityCheck(DirectoriesMixin, TestCase): @@ -96,7 +95,6 @@ class TestSanityCheck(DirectoriesMixin, TestCase): Path(doc.thumbnail_path).unlink() self.assertSanityError(doc, "Thumbnail of document does not exist") - @skip_if_root def test_thumbnail_no_access(self): doc = self.make_test_data() Path(doc.thumbnail_path).chmod(0o000) @@ -108,7 +106,6 @@ class TestSanityCheck(DirectoriesMixin, TestCase): Path(doc.source_path).unlink() self.assertSanityError(doc, "Original of document does not exist.") - @skip_if_root def test_original_no_access(self): doc = self.make_test_data() Path(doc.source_path).chmod(0o000) @@ -126,7 +123,6 @@ class TestSanityCheck(DirectoriesMixin, TestCase): Path(doc.archive_path).unlink() self.assertSanityError(doc, "Archived version of document does not exist.") - @skip_if_root def test_archive_no_access(self): doc = self.make_test_data() Path(doc.archive_path).chmod(0o000) diff --git a/src/documents/tests/utils.py b/src/documents/tests/utils.py index 9ae06eac7..88dddc557 100644 --- a/src/documents/tests/utils.py +++ b/src/documents/tests/utils.py @@ -1,4 +1,3 @@ -import os import shutil import tempfile import time @@ -29,8 +28,6 @@ from documents.data_models import DocumentSource from documents.parsers import ParseError from documents.plugins.helpers import ProgressStatusOptions -skip_if_root = pytest.mark.skipif(os.getuid() == 0, reason="running as root") - def setup_directories(): dirs = namedtuple("Dirs", ()) diff --git a/src/paperless/tests/test_checks.py b/src/paperless/tests/test_checks.py index f6a404938..781956ff6 100644 --- a/src/paperless/tests/test_checks.py +++ b/src/paperless/tests/test_checks.py @@ -7,7 +7,6 @@ from django.test import override_settings from documents.tests.utils import DirectoriesMixin from documents.tests.utils import FileSystemAssertsMixin -from documents.tests.utils import skip_if_root from paperless.checks import audit_log_check from paperless.checks import binaries_check from paperless.checks import debug_mode_check @@ -38,7 +37,6 @@ class TestChecks(DirectoriesMixin, TestCase): for msg in msgs: self.assertTrue(msg.msg.endswith("is set but doesn't exist.")) - @skip_if_root def test_paths_check_no_access(self): Path(self.dirs.data_dir).chmod(0o000) Path(self.dirs.media_dir).chmod(0o000)