78 lines
2.9 KiB
Go
78 lines
2.9 KiB
Go
package test
|
|||
|
|
|
||
|
|
// Prozessgrenzen-Tests für die Längen- und Alters-Gesetze: queue.max_text
|
||
|
|
// kürzt überlange Texte beim Eintritt (Antwort truncated, CLI-Hinweis, der
|
||
|
|
// Provider sieht die gekürzte Fassung); queue.max_age verwirft Ansagen, die
|
||
|
|
// zu lange geparkt haben (expired, nie gesprochen).
|
||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
// TestMaxTextKuerzt: Ein 60-Wörter-Text gegen max_text=40 — /speak meldet
|
||
|
|
// truncated, die CLI warnt auf stderr, der Fake-Provider bekommt höchstens
|
||
|
|
// 40 Zeichen, und /status zeigt das Limit.
|
||
|
|
func TestMaxTextKuerzt(t *testing.T) {
|
||
|
|
root := t.TempDir()
|
||
|
|
fake := newFakeProvider(t, 0)
|
||
|
|
d := startDaemon(t, root, fake.srv.URL, map[string]string{"TALK_MAX_TEXT": "40"})
|
||
|
|
lang := strings.Repeat("viel zu lange Antwort ", 12)
|
||
|
|
|
||
|
|
code, m := speak(t, d, `{"text":"`+lang+`"}`)
|
||
|
|
if code != 202 || m["id"] == "" || m["truncated"] != true {
|
||
|
|
t.Fatalf("speak: %d %v, want 202 mit id und truncated=true", code, m)
|
||
|
|
}
|
||
|
|
hits := fake.waitCompleted(t, 1)
|
||
|
|
if n := len([]rune(hits[0].Text)); n > 40 || !strings.HasPrefix(hits[0].Text, "viel zu lange Antwort") {
|
||
|
|
t.Errorf("Provider bekam %q (%d Zeichen), want ≤ 40 Zeichen vom Anfang", hits[0].Text, n)
|
||
|
|
}
|
||
|
|
|
||
|
|
env := daemonEnv(root, d.port, fake.srv.URL, nil)
|
||
|
|
res := runTalk(t, env, "say", lang)
|
||
|
|
if res.code != 0 || !strings.Contains(res.stderr, "gekürzt") {
|
||
|
|
t.Errorf("talk say (lang): Exit %d, stderr %q — will Kürzungs-Hinweis", res.code, res.stderr)
|
||
|
|
}
|
||
|
|
fake.waitCompleted(t, 2)
|
||
|
|
|
||
|
|
res = runTalk(t, env, "say", "kurz genug")
|
||
|
|
if strings.Contains(res.stderr, "gekürzt") {
|
||
|
|
t.Errorf("kurzer Text mit Kürzungs-Hinweis: %q", res.stderr)
|
||
|
|
}
|
||
|
|
fake.waitCompleted(t, 3)
|
||
|
|
|
||
|
|
res = runTalk(t, env, "status")
|
||
|
|
if !strings.Contains(res.stdout, "limits: max. 40 Zeichen") {
|
||
|
|
t.Errorf("talk status ohne Limits-Zeile: %q", res.stdout)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestMaxAgeVerwirftGeparkte: Rate-Limit 1 s, max_age 1,5 s, drei normal-
|
||
|
|
// Ansagen direkt hintereinander: die erste spielt sofort, die zweite parkt
|
||
|
|
// 1 s (frisch genug), die dritte wäre erst nach 2 s fällig — veraltet,
|
||
|
|
// verworfen, nie beim Provider.
|
||
|
|
func TestMaxAgeVerwirftGeparkte(t *testing.T) {
|
||
|
|
root := t.TempDir()
|
||
|
|
fake := newFakeProvider(t, 0)
|
||
|
|
d := startDaemon(t, root, fake.srv.URL, map[string]string{
|
||
|
|
"TALK_RATE_LIMIT": "1s",
|
||
|
|
"TALK_MAX_AGE": "1500ms",
|
||
|
|
})
|
||
|
|
|
||
|
|
for _, text := range []string{"eins", "zwei", "drei"} {
|
||
|
|
code, m := speak(t, d, `{"text":"`+text+`"}`)
|
||
|
|
if code != 202 || m["id"] == "" {
|
||
|
|
t.Fatalf("speak %s: %d %v — beim Eintritt darf nichts verfallen", text, code, m)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
hits := fake.waitCompleted(t, 2)
|
||
|
|
if hits[0].Text != "eins" || hits[1].Text != "zwei" {
|
||
|
|
t.Errorf("gesprochen = %q, %q; want eins, zwei", hits[0].Text, hits[1].Text)
|
||
|
|
}
|
||
|
|
fake.assertNoFurtherArrivals(t, 1500*time.Millisecond)
|
||
|
|
waitStatusIdle(t, d, 3*time.Second)
|
||
|
|
if !strings.Contains(d.stderr.String(), "max_age") {
|
||
|
|
t.Errorf("Daemon-Protokoll nennt den Verfall nicht:\n%s", d.stderr.String())
|
||
|
|
}
|
||
|
|
}
|