X-Git-Url: http://git.giacomolli.uk/onechat/blobdiff_plain/2ad578a24f252706976cddb41bee6cc969f251cd..refs/heads/master:/daemon_message_test.go?ds=inline diff --git a/daemon_message_test.go b/daemon_message_test.go index f9c25f1..5574172 100644 --- a/daemon_message_test.go +++ b/daemon_message_test.go @@ -2,7 +2,6 @@ package main import ( "context" - "encoding/json" "errors" "net/http" "os" @@ -532,94 +531,29 @@ func TestInvalidAgentMessageQueueStopsStartup(t *testing.T) { } } -// DaemonMessageTest owns test agents and the loops selected by Start. -type DaemonMessageTest struct { - agents DaemonAgents - loops []*TurnLoop - events []*TurnEventRecorder - messages *DaemonMessages - logs *SyncBuffer - cancel context.CancelFunc - done []chan error -} - -func (r *DaemonMessageTest) Start(t *testing.T, indices ...int) { - t.Helper() - - ctx, cancel := context.WithCancel(t.Context()) - r.cancel = cancel - for _, index := range indices { - done := make(chan error, 1) - r.done = append(r.done, done) - go func() { - done <- r.loops[index].Run(ctx) - }() - } -} - -func (r *DaemonMessageTest) Queue(t *testing.T) DaemonMessageFile { - t.Helper() - - data, err := os.ReadFile(r.messages.path) - require.NoError(t, err) - - var file DaemonMessageFile - - require.NoError(t, json.Unmarshal(data, &file)) - - return file -} - -func (r *DaemonMessageTest) Close(t *testing.T) { - t.Helper() - - if r.cancel != nil { - r.cancel() - - for _, done := range r.done { - require.ErrorIs(t, <-done, context.Canceled) - } - - r.cancel = nil - r.done = nil - } - - require.NoError(t, r.agents.Close()) - - r.agents = nil -} - -func newDaemonMessageTest(t *testing.T, dir string, server *ModelFake) *DaemonMessageTest { - t.Helper() - - _, err := os.Stat(filepath.Join(dir, daemonAgentDirName, "children")) - if errors.Is(err, os.ErrNotExist) { - daemonChildConfig(t, dir, "Garden") - daemonChildConfig(t, dir, "Library") - } else { - require.NoError(t, err) - } - - test := &DaemonMessageTest{ - logs: &SyncBuffer{}, +func TestChildScheduleWakesOnlyItsOwner(t *testing.T) { + server := newModelFake(t) + server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { + modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } - test.agents, err = openDaemonAgents(t.Context(), dir, server.URL, ModelAPIKey(modelTestKey), defaultConfig().Compactor, newTestClock().Now, daemonTestLogger(test.logs)) - require.NoError(t, err) - t.Cleanup(func() { - test.Close(t) - }) - - for _, agent := range test.agents { - events := &TurnEventRecorder{} - loop, err := agent.Loop(nil, events.Add) - require.NoError(t, err) - - test.events = append(test.events, events) - test.loops = append(test.loops, loop) + test := newDaemonMessageTest(t, t.TempDir(), server) + child := test.agents[1] + at := child.clock().Add(time.Minute).Format(scheduleAtLayout) + output := test.loops[1].tools.run(t.Context(), "schedule_set", `{"text":"Check the plants.","at":"`+at+`","cron":null}`) + require.Contains(t, output, "Schedule 1 set.") + require.Equal(t, "Garden", child.schedules.sorted()[0].Owner) + + child.schedules.clock = func() time.Time { + return child.clock().Add(time.Minute) } - - test.messages, err = openDaemonMessages(test.loops) - require.NoError(t, err) - - return test + require.ErrorContains(t, child.schedules.deliver(t.Context(), test.loops[0]), "does not match") + require.NoError(t, child.schedules.deliver(t.Context(), test.loops[1])) + test.Start(t, 0, 1, 2) + test.events[1].WaitFor(t, "idle", 1) + require.Equal(t, 1, server.Calls()) + require.Equal(t, child.agent.CacheKey(), server.Call(0).body["prompt_cache_key"]) + require.Zero(t, test.agents[0].memory.Len()) + require.Zero(t, test.agents[2].memory.Len()) + require.Contains(t, test.events[1].LastEvent("work").Text, "Check the plants.") + require.Equal(t, scheduleSource, test.events[1].LastEvent("work").Source) }