Zielwert vs. real erreichtes Ergebnis fuer alle drei Pflichtpruefungen festgehalten. Layouttreue und Absturzsicherheit gegen echten soffice-Prozess bleiben offen, da LibreOffice auf 192.168.1.131 nicht installiert ist (grosser, unueblicher Fussabdruck laut apt-get --dry-run, daher vor Installation zurueckgemeldet statt blind installiert). Zeitlimit real verifiziert, inklusive eines dabei gefundenen echten exec.Cmd-Pipe-Hangs und dessen Fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.3 KiB
DOC-06 – Prüfprotokoll: Office-zu-PDF-Konverter
Stand: 2026-09-18. Testhost 192.168.1.131.
Umsetzung
internal/pdfconvert folgt exakt dem Muster von internal/thumbnail (DOC-04) für Revisions-Derivate:
explizite State-Machine (pending/processing/ready/failed) in einer neuen Tabelle
revision_pdf_derivatives (Migration 0016), ein Zustand je Datei-Revision, angebunden über
FDN-04 (internal/jobqueue) für Wiederholung/Backoff/DLQ. Konvertierung läuft über headless
LibreOffice (soffice --headless --convert-to pdf), pro Aufruf mit eigenem, frischem
UserInstallation-Profilverzeichnis (Isolation zwischen gleichzeitigen Jobs) und context.WithTimeout
exec.CommandContext(Zeitlimit). Format-/Endungs-Zuordnung MIME → Dateiendung liegt in EINER Stelle (format.go,lookupFormat), mit Property-Test — genau das im Ticket unter "Bekannte Fehler vermeiden" geforderte Muster.
Formatabdeckung (bewusst dokumentiert, da "gängige Office-Formate" im Ticket nicht enumeriert
ist): docx, xlsx, pptx (OOXML), odt, ods, odp (ODF) sowie doc, xls, ppt (Legacy-Binärformate) — alle
Formate, die LibreOffice/soffice nativ importieren kann. Erweiterung um weitere Formate ist eine
Einzeilerergänzung in supportedFormats (format.go).
Prüfungen
Prüfung 1: Layouttreue an Referenzdokumenten
Ziel: Konvertierte PDFs entsprechen optisch den Referenzdokumenten.
Ergebnis: nicht durchführbar in dieser Sitzung — zählt als offen. LibreOffice (soffice) ist auf
192.168.1.131 nicht installiert. Die Prüfung des Pakets (apt-get install --dry-run libreoffice-writer libreoffice-calc libreoffice-impress) zeigt einen großen, für einen Server unüblichen Fußabdruck:
volle Desktop-Suite plus GStreamer-Multimedia-Plugins, GPU-/VA-API-Treiber (mesa, intel-media-va-driver),
Java-Bridges (libatk-wrapper-java, librhino-java), Spracherkennung (pocketsphinx-en-us) — deutlich mehr
als ein reiner Headless-Konverter braucht. Laut Auftrag ist das eine "meaningful action", bei der vor
der Installation zurückgemeldet werden soll statt blind zu installieren. Diese Rückmeldung ist erfolgt
(siehe Bericht an den Auftraggeber); die Installation selbst wurde NICHT durchgeführt. Sobald soffice
verfügbar ist, deckt TestHandler_ConvertsDocxToPDF die technische Konvertierung ab (Test läuft aktuell
mit SKIP: soffice nicht installiert — echtes docx via reinem OOXML-ZIP-Aufbau, Konvertierung, PDF-
Signaturprüfung, Speicherung als Revisions-Derivat); ein manueller visueller Abgleich mit echten
Referenzdokumenten wäre zusätzlich zu diesem automatisierten Test nachzuholen, sobald soffice installiert
ist — Zielwert und Testcode liegen bereit, das reale Ergebnis fehlt.
Prüfung 2: Zeitlimit bei Endlosdokument greift
Ziel: Eine Konvertierung, die nicht terminiert, wird nach Ablauf des Zeitlimits abgebrochen, statt Job/Worker unbegrenzt zu blockieren.
Ergebnis: bestanden, real geprüft. TestConvertToPDF_TimeoutOnPathologicalDocument ersetzt den
Konverter durch ein echtes, hängendes Shell-Skript (exec sleep 3600) und setzt Generator.Timeout auf
300 ms. Realer Lauf auf 192.168.1.131: Fehler nach Zeitlimit-Überschreitung, Gesamtdauer 0,30 s (weit
unter der 5-s-Toleranzgrenze im Test) — context.WithTimeout + exec.CommandContext killen den
Prozess zuverlässig.
Realer Fund während der Prüfung (nicht vorab bekannt): Der erste Testlauf hing sich real auf und
musste per SSH abgebrochen werden. Ursache: das ursprüngliche Testskript startete sleep 3600 als
Kindprozess des Shell-Skripts (ohne exec) — nach SIGKILL des direkten Kindprozesses (sh) blieb der
Enkelprozess (sleep) am Leben und hielt die von CombinedOutput() gelesene Ausgabe-Pipe offen; cmd.Wait()
wartete dadurch trotz abgelaufenem Kontext unbegrenzt weiter — eine bekannte exec.Cmd-Falle. Behoben in
zwei Schritten: (1) Testskript nutzt jetzt exec sleep 3600, sodass der Prozess direkt durch das Signal
stirbt; (2) zusätzlich, als echte Produktionshärtung (nicht nur Testfix), trägt Generator.convertToPDF
jetzt cmd.WaitDelay = 5 * time.Second, was denselben Hang bei einem realen soffice-Prozess begrenzen
würde, sollte dieser (z. B. über Hilfsprozesse) die Pipe offenhalten. Der reale Prozess auf dem Testhost
(PID 182657, sleep 3600) wurde nach dem Abbruch verifiziert per kill -9 entfernt.
Prüfung 3: Konverter-Absturz beeinträchtigt andere Jobs nicht
Ziel: Ein abstürzender Konverter-Prozess für ein Dokument blockiert/beeinträchtigt die Verarbeitung eines anderen Dokuments nicht.
Ergebnis: Testcode vorhanden und mechanisch korrekt (Fake-Wrapper-Skript, das bei einem
Marker-Dokument kill -SEGV $$ auslöst, sonst an echtes soffice delegiert, TestHandler_ CrashingConverterDoesNotAffectOtherJobs), aber real NICHT ausgeführt — derselbe Grund wie Prüfung 1:
kein soffice auf dem Testhost, Test läuft mit SKIP. Die strukturelle Absturzsicherheit ist
indirekt bereits belegt: TestHandler_UnsupportedFormatResultsInFailedStatus (real bestanden) zeigt,
dass ein fehlschlagender Konvertierungsversuch sauber in StatusFailed mit Fehlermeldung mündet statt
den Worker zu blockieren, und die zugrundeliegende jobqueue.Dequeue-SKIP-LOCKED-Semantik (FDN-04,
bereits in DOC-04 real mit gleichzeitigen Jobs verifiziert) ist unverändert wiederverwendet — kein
neuer Code an dieser Stelle. Der eigentliche Prozessabsturz-Fall (SIGSEGV eines echten
soffice-Subprozesses) ist damit aber NICHT real reproduziert worden — zählt nach Ticket-Vorgabe
("nicht durchgeführt = offen") als offen, bis soffice verfügbar ist.
Zusätzlich real durchgeführt
TestHandler_UnsupportedFormatResultsInFailedStatus— PASS. Ein Revisions-MIME-Typ außerhalb der unterstützten Formatliste (text/plain) führt zuStatusFailed, kein Absturz, keine hängende Verarbeitung.TestLookupFormat_*(3 Tests inkl. Property-Test übertesting/quick) — PASS. Format-/Endungs- Zuordnung ist konsistent für alle 9 unterstützten MIME-Typen, robust gegen Groß-/Kleinschreibung und Whitespace, lehnt nicht unterstützte Typen (application/pdf,text/plain) korrekt ab.
Regressionsnachweis
go build ./..., go vet ./... sauber auf 192.168.1.131 (Go 1.24.4). gofmt -l . zeigt ausschließlich
eine vorbestehende, nicht mit DOC-06 zusammenhängende Datei (internal/versioningapi/handler_test.go) —
keine neue Formatierungsabweichung durch dieses Ticket.
Offene Punkte für die Abnahme
- LibreOffice/soffice-Installation auf dem Zielsystem entscheiden (Umfang siehe Prüfung 1) und
danach
TestHandler_ConvertsDocxToPDFsowieTestHandler_CrashingConverterDoesNotAffectOtherJobsreal (nicht nur SKIP) laufen lassen. - Nach (1): manueller visueller Layoutabgleich mit echten Referenzdokumenten (Prüfung 1 im engeren Sinn — automatisierter Test prüft nur "PDF entsteht und ist strukturell gültig", nicht Formatierungstreue).
Nicht Bestandteil dieser Kachel
VER-07 (digitale Signatur) und QA-03 (Prüfgate Dokumentenkern) wurden bewusst NICHT implementiert. Es wurde keine gesonderte Schnittstelle dafür vorbereitet, da DOC-06 lediglich ein weiteres Revisions-Derivat ablegt (analog zum Thumbnail aus DOC-04) — es gibt keine Freigabe-/Signatur- Anknüpfungsstelle, die dieses Derivat betrifft und die nicht bereits durch die generische Revisions-/Derivat-Modellierung abgedeckt wäre.