Skip to content

Commit 5456e65

Browse files
committed
brain/*: record trace of message ids used to speak
For #44.
1 parent 9e31d26 commit 5456e65

File tree

13 files changed

+432
-196
lines changed

13 files changed

+432
-196
lines changed

brain/braintest/bench.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func BenchSpeak(ctx context.Context, b *testing.B, new func(ctx context.Context,
125125
b.ResetTimer()
126126
b.RunParallel(func(pb *testing.PB) {
127127
for pb.Next() {
128-
if _, err := brain.Speak(ctx, br, "bocchi", ""); err != nil {
128+
if _, _, err := brain.Speak(ctx, br, "bocchi", ""); err != nil {
129129
b.Errorf("error while speaking: %v", err)
130130
}
131131
}
@@ -170,7 +170,7 @@ func BenchSpeak(ctx context.Context, b *testing.B, new func(ctx context.Context,
170170
b.ResetTimer()
171171
b.RunParallel(func(pb *testing.PB) {
172172
for pb.Next() {
173-
if _, err := brain.Speak(ctx, br, "bocchi", ""); err != nil {
173+
if _, _, err := brain.Speak(ctx, br, "bocchi", ""); err != nil {
174174
b.Errorf("error while speaking: %v", err)
175175
}
176176
}
@@ -215,7 +215,7 @@ func BenchSpeak(ctx context.Context, b *testing.B, new func(ctx context.Context,
215215
b.ResetTimer()
216216
b.RunParallel(func(pb *testing.PB) {
217217
for pb.Next() {
218-
if _, err := brain.Speak(ctx, br, "bocchi", toks[rand.IntN(len(toks)-1)]); err != nil {
218+
if _, _, err := brain.Speak(ctx, br, "bocchi", toks[rand.IntN(len(toks)-1)]); err != nil {
219219
b.Errorf("error while speaking: %v", err)
220220
}
221221
}

brain/braintest/braintest.go

Lines changed: 122 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ package braintest
33

44
import (
55
"context"
6-
"maps"
76
"slices"
87
"strings"
98
"testing"
109
"time"
1110

11+
"github.com/google/go-cmp/cmp"
1212
"github.com/zephyrtronium/robot/brain"
1313
"github.com/zephyrtronium/robot/userhash"
1414
)
@@ -111,15 +111,15 @@ func learn(ctx context.Context, t *testing.T, br brain.Learner) {
111111
}
112112
}
113113

114-
func speak(ctx context.Context, t *testing.T, br brain.Speaker, tag, prompt string, iters int) map[string]bool {
114+
func speak(ctx context.Context, t *testing.T, br brain.Speaker, tag, prompt string, iters int) map[string]struct{} {
115115
t.Helper()
116-
got := make(map[string]bool, 5)
116+
got := make(map[string]struct{}, 20)
117117
for range iters {
118-
s, err := brain.Speak(ctx, br, tag, prompt)
118+
s, trace, err := brain.Speak(ctx, br, tag, prompt)
119119
if err != nil {
120120
t.Errorf("couldn't speak: %v", err)
121121
}
122-
got[s] = true
122+
got[strings.Join(trace, " ")+"#"+s] = struct{}{}
123123
}
124124
return got
125125
}
@@ -128,33 +128,57 @@ func speak(ctx context.Context, t *testing.T, br brain.Speaker, tag, prompt stri
128128
func testSpeak(ctx context.Context, br brain.Brain) func(t *testing.T) {
129129
return func(t *testing.T) {
130130
learn(ctx, t, br)
131-
got := speak(ctx, t, br, "kessoku", "", 256)
132-
want := map[string]bool{
133-
"member bocchi": true,
134-
"member ryou": true,
135-
"member nijika": true,
136-
"member kita": true,
131+
got := speak(ctx, t, br, "kessoku", "", 2048)
132+
want := map[string]struct{}{
133+
"1#member bocchi": {},
134+
"1 2#member bocchi": {},
135+
"1 3#member bocchi": {},
136+
"1 4#member bocchi": {},
137+
"1 2#member ryou": {},
138+
"2#member ryou": {},
139+
"2 3#member ryou": {},
140+
"2 4#member ryou": {},
141+
"1 3#member nijika": {},
142+
"2 3#member nijika": {},
143+
"3#member nijika": {},
144+
"3 4#member nijika": {},
145+
"1 4#member kita": {},
146+
"2 4#member kita": {},
147+
"3 4#member kita": {},
148+
"4#member kita": {},
137149
}
138-
if !maps.Equal(got, want) {
139-
t.Errorf("wrong spoken messages for kessoku: want %v, got %v", want, got)
150+
if diff := cmp.Diff(want, got); diff != "" {
151+
t.Errorf("wrong spoken messages for kessoku (+got/-want):\n%s", diff)
140152
}
141-
got = speak(ctx, t, br, "sickhack", "", 256)
142-
want = map[string]bool{
143-
"member bocchi": true,
144-
"member ryou": true,
145-
"member nijika": true,
146-
"member kita": true,
147-
"manager seika": true,
153+
got = speak(ctx, t, br, "sickhack", "", 2048)
154+
want = map[string]struct{}{
155+
"5#member bocchi": {},
156+
"5 6#member bocchi": {},
157+
"5 7#member bocchi": {},
158+
"5 8#member bocchi": {},
159+
"5 6#member ryou": {},
160+
"6#member ryou": {},
161+
"6 7#member ryou": {},
162+
"6 8#member ryou": {},
163+
"5 7#member nijika": {},
164+
"6 7#member nijika": {},
165+
"7#member nijika": {},
166+
"7 8#member nijika": {},
167+
"5 8#member kita": {},
168+
"6 8#member kita": {},
169+
"7 8#member kita": {},
170+
"8#member kita": {},
171+
"9#manager seika": {},
148172
}
149-
if !maps.Equal(got, want) {
150-
t.Errorf("wrong spoken messages for sickhack: want %v, got %v", want, got)
173+
if diff := cmp.Diff(want, got); diff != "" {
174+
t.Errorf("wrong spoken messages for sickhack (+got/-want):\n%s", diff)
151175
}
152176
got = speak(ctx, t, br, "sickhack", "manager", 32)
153-
want = map[string]bool{
154-
"manager seika": true,
177+
want = map[string]struct{}{
178+
"9#manager seika": {},
155179
}
156-
if !maps.Equal(got, want) {
157-
t.Errorf("wrong prompted messages for sickhack: want %v, got %v", want, got)
180+
if diff := cmp.Diff(want, got); diff != "" {
181+
t.Errorf("wrong prompted messages for sickhack (+got/-want):\n%s", diff)
158182
}
159183
}
160184
}
@@ -167,16 +191,19 @@ func testForget(ctx context.Context, br brain.Brain) func(t *testing.T) {
167191
t.Errorf("couldn't forget: %v", err)
168192
}
169193
for range 100 {
170-
s, err := brain.Speak(ctx, br, "kessoku", "")
194+
s, trace, err := brain.Speak(ctx, br, "kessoku", "")
171195
if err != nil {
172196
t.Errorf("couldn't speak: %v", err)
173197
}
174198
if strings.Contains(s, "bocchi") {
175199
t.Errorf("remembered that which must be forgotten: %q", s)
176200
}
201+
if trace[len(trace)-1] == messages[0].ID {
202+
t.Errorf("id %q should have been forgotten but was used in %q", messages[0].ID, trace)
203+
}
177204
}
178205
for range 10000 {
179-
s, err := brain.Speak(ctx, br, "sickhack", "")
206+
s, _, err := brain.Speak(ctx, br, "sickhack", "")
180207
if err != nil {
181208
t.Errorf("couldn't speak: %v", err)
182209
}
@@ -195,25 +222,46 @@ func testForgetMessage(ctx context.Context, br brain.Brain) func(t *testing.T) {
195222
if err := br.ForgetMessage(ctx, "kessoku", messages[0].ID); err != nil {
196223
t.Errorf("failed to forget first message: %v", err)
197224
}
198-
got := speak(ctx, t, br, "kessoku", "", 256)
199-
want := map[string]bool{
200-
"member ryou": true,
201-
"member nijika": true,
202-
"member kita": true,
225+
got := speak(ctx, t, br, "kessoku", "", 2048)
226+
want := map[string]struct{}{
227+
// The current brains should delete the "member" with ID 1, but we
228+
// don't strictly require it.
229+
// This should change anyway once we stop deleting by tuples.
230+
"2#member ryou": {},
231+
"2 3#member ryou": {},
232+
"2 4#member ryou": {},
233+
"2 3#member nijika": {},
234+
"3#member nijika": {},
235+
"3 4#member nijika": {},
236+
"2 4#member kita": {},
237+
"3 4#member kita": {},
238+
"4#member kita": {},
203239
}
204-
if !maps.Equal(got, want) {
205-
t.Errorf("wrong messages after forgetting: want %v, got %v", want, got)
240+
if diff := cmp.Diff(want, got); diff != "" {
241+
t.Errorf("wrong messages after forgetting (+got/-want):\n%s", diff)
206242
}
207-
got = speak(ctx, t, br, "sickhack", "", 256)
208-
want = map[string]bool{
209-
"member bocchi": true,
210-
"member ryou": true,
211-
"member nijika": true,
212-
"member kita": true,
213-
"manager seika": true,
243+
got = speak(ctx, t, br, "sickhack", "", 2048)
244+
want = map[string]struct{}{
245+
"5#member bocchi": {},
246+
"5 6#member bocchi": {},
247+
"5 7#member bocchi": {},
248+
"5 8#member bocchi": {},
249+
"5 6#member ryou": {},
250+
"6#member ryou": {},
251+
"6 7#member ryou": {},
252+
"6 8#member ryou": {},
253+
"5 7#member nijika": {},
254+
"6 7#member nijika": {},
255+
"7#member nijika": {},
256+
"7 8#member nijika": {},
257+
"5 8#member kita": {},
258+
"6 8#member kita": {},
259+
"7 8#member kita": {},
260+
"8#member kita": {},
261+
"9#manager seika": {},
214262
}
215-
if !maps.Equal(got, want) {
216-
t.Errorf("wrong messages in other tag after forgetting: want %v, got %v", want, got)
263+
if diff := cmp.Diff(want, got); diff != "" {
264+
t.Errorf("wrong messages in other tag after forgetting (+got/-want):\n%s", diff)
217265
}
218266
}
219267
}
@@ -225,24 +273,38 @@ func testForgetDuring(ctx context.Context, br brain.Brain) func(t *testing.T) {
225273
if err := br.ForgetDuring(ctx, "kessoku", time.Unix(1, 0).Add(-time.Millisecond), time.Unix(2, 0).Add(time.Millisecond)); err != nil {
226274
t.Errorf("failed to forget: %v", err)
227275
}
228-
got := speak(ctx, t, br, "kessoku", "", 256)
229-
want := map[string]bool{
230-
"member bocchi": true,
231-
"member kita": true,
276+
got := speak(ctx, t, br, "kessoku", "", 2048)
277+
want := map[string]struct{}{
278+
"1#member bocchi": {},
279+
"1 4#member bocchi": {},
280+
"1 4#member kita": {},
281+
"4#member kita": {},
232282
}
233-
if !maps.Equal(got, want) {
234-
t.Errorf("wrong messages after forgetting: want %v, got %v", want, got)
283+
if diff := cmp.Diff(want, got); diff != "" {
284+
t.Errorf("wrong messages after forgetting (+got/-want):\n%s", diff)
235285
}
236-
got = speak(ctx, t, br, "sickhack", "", 256)
237-
want = map[string]bool{
238-
"member bocchi": true,
239-
"member ryou": true,
240-
"member nijika": true,
241-
"member kita": true,
242-
"manager seika": true,
286+
got = speak(ctx, t, br, "sickhack", "", 2048)
287+
want = map[string]struct{}{
288+
"5#member bocchi": {},
289+
"5 6#member bocchi": {},
290+
"5 7#member bocchi": {},
291+
"5 8#member bocchi": {},
292+
"5 6#member ryou": {},
293+
"6#member ryou": {},
294+
"6 7#member ryou": {},
295+
"6 8#member ryou": {},
296+
"5 7#member nijika": {},
297+
"6 7#member nijika": {},
298+
"7#member nijika": {},
299+
"7 8#member nijika": {},
300+
"5 8#member kita": {},
301+
"6 8#member kita": {},
302+
"7 8#member kita": {},
303+
"8#member kita": {},
304+
"9#manager seika": {},
243305
}
244-
if !maps.Equal(got, want) {
245-
t.Errorf("wrong spoken messages for sickhack: want %v, got %v", want, got)
306+
if diff := cmp.Diff(want, got); diff != "" {
307+
t.Errorf("wrong spoken messages for sickhack (+got/-want):\n%s", diff)
246308
}
247309
}
248310
}
@@ -278,7 +340,7 @@ func testCombinatoric(ctx context.Context, br brain.Brain) func(t *testing.T) {
278340
}
279341
}
280342
allocs := testing.AllocsPerRun(10, func() {
281-
_, err := brain.Speak(ctx, br, "bocchi", "")
343+
_, _, err := brain.Speak(ctx, br, "bocchi", "")
282344
if err != nil {
283345
t.Errorf("couldn't speak: %v", err)
284346
}

0 commit comments

Comments
 (0)