cd803a3dfe
Vor dem Rollout durchgesehen und die verbliebenen Stellen geschlossen, an denen etwas schiefgehen konnte, ohne dass es irgendwo sichtbar wurde. Datenverlust: - veraPDF: das in [verapdf].binary konfigurierte Programm wird im Preflight geprueft. Bisher galt bei falschem Pfad JEDE Datei als "nicht konform" — Ergebnis nach error/, Original geloescht (Default delete). run_verapdf() trennt jetzt ausserdem ein echtes FAIL-Urteil von einer Stoerung (VeraPdfUnavailable: nicht startbar, abgestuerzt, kein PASS/FAIL in der Ausgabe). Bei Stoerung wandern Original UND Ergebnis nach error/, das Original wird nicht entsorgt. - Gleichnamige Dateien wurden in outgoing/, error/ und beim Ordner-Upload mit abweichendem target kommentarlos ueberschrieben. Jetzt Zeitstempel daneben, mit Warnung; ProcessResult.output traegt den echten Pfad. Robustheit: - Kaputtes oder nicht lesbares TOML beim Start: Exit 2 statt Traceback. - RestartPreventExitStatus=2 in der Unit — Exit 2 (Config/Preflight) laeuft nicht mehr endlos neu, die Instanz bleibt sichtbar failed stehen. - Toter watchdog-Observer wird erkannt: Exit 3, systemd setzt den Watch neu auf. Vorher blieb die Unit "active" und verarbeitete nichts mehr. - Relative Pfade in [paths]/archive_dir/target sind ein Config-Fehler statt still unter /opt zu landen. - Fehler beim Archivieren entwertet den Durchlauf nicht mehr: Upload und Mail laufen, Sichtbarkeit ueber log.error + "OK mit Warnung"-Mail. - Nicht-PDFs in incoming/ werden beim Start-Scan gesammelt gemeldet. - Logging explizit nach stdout (die Doku versprach das schon). Struktur: - Neue lib/common.sh, von install.sh und update.sh gesourct. Die doppelte venv_is_healthy() gibt es nur noch einmal, in der gruendlichen Fassung — die schlanke in install.sh haette eine nach einem Distro-Sprung kaputte venv als gesund durchgewunken (nachgewiesen). - install.sh warnt in Containern, wenn systemd-journald nicht laeuft. Doku: Dateisystem-Festlegung (ext4/xfs/zfs, kein CIFS/NFS wegen inotify), Debian 13 in LXC auf Proxmox scheitert an journald (243/CREDENTIALS, AppArmor blockiert sd-mkdcreds) inkl. Abhilfe, echte Speicher-Messwerte, Exit-Code-Tabelle. 254 Tests gruen (vorher 152). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""Punkt 6: Fremddateien in incoming/ verschwinden nicht mehr lautlos.
|
|
|
|
Alles ohne .pdf-Endung wurde kommentarlos ignoriert und sammelte sich an.
|
|
Jetzt gibt es beim Start-Scan genau EINE Sammelmeldung — kein Spam im
|
|
laufenden Betrieb, keine Zeile pro Datei.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from unittest.mock import patch
|
|
|
|
from pdf_ocr_hotfolder.service import HotfolderService
|
|
|
|
LOGGER = "pdf_ocr_hotfolder.service"
|
|
|
|
|
|
def _scan(tmp_config, caplog) -> str:
|
|
service = HotfolderService(tmp_config)
|
|
try:
|
|
with caplog.at_level(logging.WARNING, logger=LOGGER), \
|
|
patch.object(HotfolderService, "enqueue"):
|
|
service._scan_existing()
|
|
finally:
|
|
service._executor.shutdown(wait=False)
|
|
return caplog.text
|
|
|
|
|
|
def test_non_pdf_files_are_reported(tmp_config, caplog) -> None:
|
|
(tmp_config.paths.incoming / "notizen.txt").write_text("x")
|
|
(tmp_config.paths.incoming / "bild.jpg").write_bytes(b"x")
|
|
(tmp_config.paths.incoming / "scan.pdf").write_bytes(b"%PDF-1.4\n")
|
|
|
|
text = _scan(tmp_config, caplog)
|
|
|
|
assert "2 Datei(en) ohne .pdf-Endung" in text
|
|
assert "notizen.txt" in text
|
|
assert "bild.jpg" in text
|
|
assert "scan.pdf" not in text
|
|
|
|
|
|
def test_single_aggregate_line(tmp_config, caplog) -> None:
|
|
"""Eine Sammelmeldung, nicht eine pro Datei."""
|
|
for i in range(7):
|
|
(tmp_config.paths.incoming / f"datei{i}.txt").write_text("x")
|
|
|
|
text = _scan(tmp_config, caplog)
|
|
|
|
assert text.count("ohne .pdf-Endung") == 1
|
|
assert "7 Datei(en)" in text
|
|
# Nur die ersten drei werden namentlich genannt
|
|
assert "+4 weitere" in text
|
|
|
|
|
|
def test_no_message_without_foreign_files(tmp_config, caplog) -> None:
|
|
(tmp_config.paths.incoming / "scan.pdf").write_bytes(b"%PDF-1.4\n")
|
|
assert "ohne .pdf-Endung" not in _scan(tmp_config, caplog)
|
|
|
|
|
|
def test_empty_incoming_is_quiet(tmp_config, caplog) -> None:
|
|
assert "ohne .pdf-Endung" not in _scan(tmp_config, caplog)
|
|
|
|
|
|
def test_directories_are_not_counted(tmp_config, caplog) -> None:
|
|
"""Ein Unterverzeichnis ist keine liegengebliebene Fremddatei."""
|
|
(tmp_config.paths.incoming / "unterordner").mkdir()
|
|
assert "ohne .pdf-Endung" not in _scan(tmp_config, caplog)
|
|
|
|
|
|
def test_uppercase_pdf_is_not_foreign(tmp_config, caplog) -> None:
|
|
"""`_is_pdf()` ist case-insensitiv — SCAN.PDF ist eine PDF."""
|
|
(tmp_config.paths.incoming / "SCAN.PDF").write_bytes(b"%PDF-1.4\n")
|
|
assert "ohne .pdf-Endung" not in _scan(tmp_config, caplog)
|
|
|
|
|
|
def test_no_spam_during_runtime(tmp_config, caplog) -> None:
|
|
"""Im laufenden Betrieb bleibt enqueue() für Fremddateien stumm."""
|
|
fremd = tmp_config.paths.incoming / "notizen.txt"
|
|
fremd.write_text("x")
|
|
|
|
service = HotfolderService(tmp_config)
|
|
try:
|
|
with caplog.at_level(logging.DEBUG, logger=LOGGER):
|
|
for _ in range(5):
|
|
service.enqueue(fremd)
|
|
finally:
|
|
service._executor.shutdown(wait=False)
|
|
|
|
assert caplog.text == ""
|