Files
talk/test/limits_test.go
T

78 lines
2.9 KiB
Go
Raw Permalink Normal View History

package test
// Process-boundary tests for the length and age laws: queue.max_text
// truncates overlong texts on admission (response truncated, CLI note, the
// provider sees the truncated version); queue.max_age discards
// announcements that parked too long (expired, never spoken).
import (
"strings"
"testing"
"time"
)
// TestMaxTextTruncates: a 60-word text against max_text=40 — /speak reports
// truncated, the CLI warns on stderr, the fake provider receives at most 40
// characters, and /status shows the limit.
func TestMaxTextTruncates(t *testing.T) {
root := t.TempDir()
fake := newFakeProvider(t, 0)
d := startDaemon(t, root, fake.srv.URL, map[string]string{"TALK_MAX_TEXT": "40"})
long := strings.Repeat("far too long an answer ", 12)
code, m := speak(t, d, `{"text":"`+long+`"}`)
if code != 202 || m["id"] == "" || m["truncated"] != true {
t.Fatalf("speak: %d %v, want 202 with id and truncated=true", code, m)
}
hits := fake.waitCompleted(t, 1)
if n := len([]rune(hits[0].Text)); n > 40 || !strings.HasPrefix(hits[0].Text, "far too long an answer") {
t.Errorf("provider received %q (%d characters), want ≤ 40 characters from the start", hits[0].Text, n)
}
env := daemonEnv(root, d.port, fake.srv.URL, nil)
res := runTalk(t, env, "say", long)
if res.code != 0 || !strings.Contains(res.stderr, "truncated") {
t.Errorf("talk say (long): exit %d, stderr %q — want the truncation note", res.code, res.stderr)
}
fake.waitCompleted(t, 2)
res = runTalk(t, env, "say", "short enough")
if strings.Contains(res.stderr, "truncated") {
t.Errorf("short text with truncation note: %q", res.stderr)
}
fake.waitCompleted(t, 3)
res = runTalk(t, env, "status")
if !strings.Contains(res.stdout, "limits: max 40 characters") {
t.Errorf("talk status without limits line: %q", res.stdout)
}
}
// TestMaxAgeDiscardsParked: rate limit 1 s, max_age 1.5 s, three normal
// announcements right after one another: the first plays immediately, the
// second parks 1 s (fresh enough), the third would be due only after 2 s —
// stale, discarded, never at the provider.
func TestMaxAgeDiscardsParked(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{"one", "two", "three"} {
code, m := speak(t, d, `{"text":"`+text+`"}`)
if code != 202 || m["id"] == "" {
t.Fatalf("speak %s: %d %v — nothing may expire on admission", text, code, m)
}
}
hits := fake.waitCompleted(t, 2)
if hits[0].Text != "one" || hits[1].Text != "two" {
t.Errorf("spoken = %q, %q; want one, two", 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 log does not mention the expiry:\n%s", d.stderr.String())
}
}