Files
patrickandClaude Sonnet 5 7cce1664ff
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
FDN-23: jobtyp-limits (laufzeit/speicher), workerruntime-tests
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 00:50:51 +02:00

64 lines
2.5 KiB
Go

package workerruntime
import (
"context"
"errors"
"strings"
"testing"
"time"
"gitea.perlbach24.de/scripte/nexarch/dms/internal/integrity"
"gitea.perlbach24.de/scripte/nexarch/dms/internal/jobqueue"
"gitea.perlbach24.de/scripte/nexarch/dms/internal/testenv"
)
func TestIntegrityJobIsRegisteredOnlyWhenConfigured(t *testing.T) {
e := testenv.New(t)
queue := jobqueue.NewQueue(e.Pool, 5*time.Minute)
noTools := func(string) (string, error) { return "", errors.New("nicht gefunden") }
base := Deps{Pool: e.Pool, Storage: e.Storage, Crypto: e.Crypto, TenantSlug: testenv.TenantSlug, Queue: queue, LookPath: noTools}
rt := New(base)
if _, ok := rt.Handlers[integrity.JobType]; ok {
t.Fatal("integrity.verify ohne konfiguration registriert")
}
if !strings.Contains(strings.Join(rt.Notices, "\n"), integrity.JobType) {
t.Errorf("hinweis auf %s fehlt: %v", integrity.JobType, rt.Notices)
}
base.Integrity = &integrity.Config{Mode: integrity.ModeFull, MaxDuration: 2 * time.Hour}
rt = New(base)
if _, ok := rt.Handlers[integrity.JobType]; !ok {
t.Fatal("integrity.verify trotz konfiguration nicht registriert")
}
if l := rt.Limits[integrity.JobType]; l.MaxDuration != 2*time.Hour+time.Minute {
t.Fatalf("job-limits: %+v", l)
}
}
func TestIntegrityJobRunsThroughDispatcherToFinalState(t *testing.T) {
e := testenv.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
queue := jobqueue.NewQueue(e.Pool, 5*time.Minute)
noTools := func(string) (string, error) { return "", errors.New("nicht gefunden") }
rt := New(Deps{Pool: e.Pool, Storage: e.Storage, Crypto: e.Crypto, TenantSlug: testenv.TenantSlug, Queue: queue, LookPath: noTools,
Integrity: &integrity.Config{Mode: integrity.ModeFull, MaxDuration: time.Minute}})
_, rev := e.UploadDoc(t, "a.txt", "text/plain", []byte("inhalt"))
if _, err := e.Pool.Exec(ctx, `UPDATE file_revisions SET created_at = now() - interval '1 hour'`); err != nil {
t.Fatal(err)
}
if ok, err := integrity.EnqueueIfDue(ctx, e.Pool, queue, integrity.Schedule{Interval: time.Hour}, time.Now()); err != nil || !ok {
t.Fatalf("einreihen: %v %v", ok, err)
}
go rt.Run(ctx, 1, "test", 20*time.Millisecond)
waitFor(t, e, "integrity.verify abgeschlossen", 20*time.Second, func() bool {
return count(t, e, `SELECT count(*) FROM processing_jobs WHERE job_type = $1 AND status = 'succeeded'`, integrity.JobType) == 1
})
if n := count(t, e, `SELECT count(*) FROM integrity_results WHERE revision_id = $1 AND status = 'ok'`, rev); n != 1 {
t.Fatalf("ergebnis der revision: %d, erwartet ok", n)
}
}