Basis: feature/fdn-09-verschluesselung-at-rest-schluesselverwaltung (enthaelt FDN-04, wovon FDN-11 laut Ticket abhaengt; fdn-10 wurde NICHT als Basis genommen, da FDN-04 kein Vorfahre von fdn-10 ist). Ergaenzt harte, konfigurierbare Obergrenzen je Verarbeitungsjob (Zeit, Speicher, Eingabegroesse/Seitenzahl) um internal/jobqueue: Ueberschreitung fuehrt zum kontrollierten Abbruch in die Dead-Letter-Queue statt zur Blockade des Workers, inkl. Nutzerbenachrichtigung ueber ein neues Notifier-Interface. - limits.go: Limits-Struct, DefaultLimits, Vorab-Pruefung von size_bytes/pages aus den Job-Metadaten vor Handler-Start - notifier.go: Notifier-Interface + LogNotifier als Standard - queue.go: Queue.FailPermanently fuer sofortigen DLQ-Transfer (kein Backoff/Retry bei Ressourcenlimit-Verstoss) - worker.go: Worker.runWithLimits fuehrt Handler mit Zeit-Timeout und Speicher-Sampling (runtime.MemStats, prozessweite Annaeherung) aus und kehrt bei Ueberschreitung sofort zurueck statt zu blockieren Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPsyieCYwvbUBsnN598SbP
55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
package jobqueue
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
// TestCheckInputLimits ist Akzeptanzkriterium 1 (Groesse/Seitenzahl
|
|
// konfigurierbar pruefbar) fuer die reine Prueffunktion, unabhaengig vom Worker.
|
|
func TestCheckInputLimits(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
payload string
|
|
limits Limits
|
|
wantExceed bool
|
|
}{
|
|
{
|
|
name: "innerhalb der obergrenzen",
|
|
payload: `{"size_bytes": 100, "pages": 5}`,
|
|
limits: Limits{MaxInputBytes: 1000, MaxPages: 10},
|
|
wantExceed: false,
|
|
},
|
|
{
|
|
name: "eingabegroesse ueberschritten",
|
|
payload: `{"size_bytes": 5000, "pages": 5}`,
|
|
limits: Limits{MaxInputBytes: 1000, MaxPages: 10},
|
|
wantExceed: true,
|
|
},
|
|
{
|
|
name: "seitenzahl ueberschritten",
|
|
payload: `{"size_bytes": 100, "pages": 999}`,
|
|
limits: Limits{MaxInputBytes: 1000, MaxPages: 10},
|
|
wantExceed: true,
|
|
},
|
|
{
|
|
name: "limit 0 bedeutet keine pruefung",
|
|
payload: `{"size_bytes": 999999, "pages": 999999}`,
|
|
limits: Limits{},
|
|
wantExceed: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := checkInputLimits(json.RawMessage(tc.payload), tc.limits)
|
|
var limitErr *LimitExceededError
|
|
gotExceed := errors.As(err, &limitErr)
|
|
if gotExceed != tc.wantExceed {
|
|
t.Fatalf("checkInputLimits(%s) exceed = %v, want %v (err=%v)", tc.payload, gotExceed, tc.wantExceed, err)
|
|
}
|
|
})
|
|
}
|
|
}
|