package main
import (
- "context"
"io"
"net/http"
"os"
modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("It said hi.")}, 100, 0, 5))
}
- socket := startTestDaemon(t, server)
+ socket := daemonStartTest(t, server)
first := terminalStartTestClient(t, socket)
second := terminalStartTestClient(t, socket)
first.WaitFor(t, "[connected to OneChat]")
first.Type(stopCommand)
first.WaitFor(t, "[error] no turn runs")
+ first.Type(stopCommand + " BlueFox")
+ first.WaitFor(t, "[error] no subagent BlueFox runs")
require.NotContains(t, second.Output(), "no turn runs")
require.NoError(t, first.Close())
}
<-release
}
- socket := startTestDaemon(t, server)
+ socket := daemonStartTest(t, server)
client := terminalStartTestClient(t, socket)
client.Type("a long task")
<-arrived
path := filepath.Join(t.TempDir(), socketFileName)
require.NoError(t, os.WriteFile(path, nil, 0o600))
- listener, err := listenSocket(path)
+ listener, err := daemonListenSocket(path)
require.NoError(t, err)
info, err := os.Stat(path)
}
func TestListenSocketRefusesALongPath(t *testing.T) {
- _, err := listenSocket(filepath.Join(t.TempDir(), strings.Repeat("d", 100), socketFileName))
+ _, err := daemonListenSocket(filepath.Join(t.TempDir(), strings.Repeat("d", 100), socketFileName))
require.ErrorContains(t, err, "set ONECHAT_DIR to a shorter path")
}
require.Empty(t, entries)
}
-func TestOneProcessHoldsTheTokens(t *testing.T) {
- dir := t.TempDir()
- lock, err := lockTokens(dir)
- require.NoError(t, err)
+func TestDaemonLogHasATimeStampOnlyOutsideTheJournal(t *testing.T) {
+ testCases := []struct {
+ name string
+ journal string
+ line string
+ }{
+ {
+ name: "the journal adds the time itself",
+ journal: "8:12345",
+ line: `^onechat: the agent is ready\n$`,
+ },
+ {
+ name: "a terminal gets the time in the line",
+ journal: "",
+ line: `^onechat: \d{4}/\d\d/\d\d \d\d:\d\d:\d\d the agent is ready\n$`,
+ },
+ }
- _, err = lockTokens(dir)
- require.ErrorIs(t, err, errTokensInUse)
- require.NoError(t, lock.Close())
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Setenv("JOURNAL_STREAM", tc.journal)
- lock, err = lockTokens(dir)
- require.NoError(t, err)
- require.NoError(t, lock.Close())
+ var out strings.Builder
+ daemonLogger(&out, "onechat: ").Print("the agent is ready")
+ require.Regexp(t, tc.line, out.String())
+ })
+ }
}
-// startTestDaemon serves a new agent on a socket in a temporary directory and
+// daemonStartTest serves a new agent on a socket in a temporary directory and
// returns the socket path. The commands of the agent run in a temporary
// directory.
-func startTestDaemon(t *testing.T, server *ModelFake) string {
+func daemonStartTest(t *testing.T, server *ModelFake) string {
t.Helper()
- return startTestDaemonWithBot(t, server, nil)
-}
-
-// startTestDaemonWithBot is startTestDaemon with bot, which can be nil.
-func startTestDaemonWithBot(t *testing.T, server *ModelFake, bot *TelegramBot) string {
- t.Helper()
-
- dir := t.TempDir()
- agent, err := openAgent(filepath.Join(dir, agentDirName))
- require.NoError(t, err)
-
- agent.config.Workdir = t.TempDir()
- clock := newTestClock()
- memory, err := openMemory(t.Context(), agent.dir, clock.Now, newFakeSummarizer())
- require.NoError(t, err)
-
- socket := filepath.Join(dir, socketFileName)
- listener, err := listenSocket(socket)
- require.NoError(t, err)
-
- client := newModelClient(server.URL, ModelAPIKey(modelTestKey), agent.CacheKey(), filepath.Join(agent.dir, "usage.jsonl"))
- ctx, cancel := context.WithCancel(t.Context())
- done := make(chan error)
- go func() {
- done <- serveAgent(ctx, listener, bot, func(notify func(Event)) (*loop, error) {
- return newLoop(agent, memory, client, clock.Now, notify)
- })
- }()
-
- t.Cleanup(func() {
- cancel()
- require.NoError(t, <-done)
- require.NoError(t, memory.Close())
- })
-
- return socket
+ return daemonStartTestWithBot(t, server, nil)
}