package main import ( "context" "encoding/json" "errors" "os" "path/filepath" "testing" "github.com/stretchr/testify/require" ) // 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{}, } 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.messages, err = openDaemonMessages(test.loops) require.NoError(t, err) return test }