X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/522d7fd117285e4e4ce3ea5ec9b5a1722521b681..9301f77a5709fe7daea3a71f8dd072c6cd7df4fe:/daemon_test.go?ds=inline diff --git a/daemon_test.go b/daemon_test.go index bfb4efb..a329778 100644 --- a/daemon_test.go +++ b/daemon_test.go @@ -1,16 +1,111 @@ package main import ( + "encoding/json" "io" + "net" "net/http" "os" "path/filepath" "strings" "testing" + "time" "github.com/stretchr/testify/require" ) +func TestNotificationReceiptIsPrivateToItsSubmittingSocket(t *testing.T) { + server := newModelFake(t) + socket := daemonStartTest(t, server) + observer, err := net.Dial("unix", socket) + require.NoError(t, err) + require.NoError(t, observer.SetDeadline(time.Now().Add(10*time.Second))) + + decoder := json.NewDecoder(observer) + + var event Event + + require.NoError(t, decoder.Decode(&event)) + require.Equal(t, "ready", event.Kind) + + submitter, err := net.Dial("unix", socket) + require.NoError(t, err) + require.NoError(t, submitter.SetDeadline(time.Now().Add(10*time.Second))) + require.NoError(t, json.NewEncoder(submitter).Encode(SocketRequest{ + Type: "notify", + Notify: &NotifyInput{ + Source: "check", + ID: "1", + Text: "A new result.", + }, + })) + + accepted := false + answer := json.NewDecoder(submitter) + for !accepted { + require.NoError(t, answer.Decode(&event)) + + accepted = event.Kind == "notify" + } + + require.Equal(t, "accepted", event.Status) + + for { + require.NoError(t, decoder.Decode(&event)) + require.NotEqual(t, "notify", event.Kind) + + if event.Kind == "idle" { + break + } + } + + require.NoError(t, submitter.Close()) + require.NoError(t, observer.Close()) +} + +func TestNotificationSocketRejectsMissingOrInvalidData(t *testing.T) { + server := newModelFake(t) + socket := daemonStartTest(t, server) + conn, err := net.Dial("unix", socket) + require.NoError(t, err) + require.NoError(t, conn.SetDeadline(time.Now().Add(10*time.Second))) + + decoder := json.NewDecoder(conn) + encoder := json.NewEncoder(conn) + + var event Event + + require.NoError(t, decoder.Decode(&event)) + require.Equal(t, "ready", event.Kind) + + testCases := []*NotifyInput{ + nil, + { + Source: "invalid source", + ID: "1", + Text: "data", + }, + } + + for _, tc := range testCases { + require.NoError(t, encoder.Encode(SocketRequest{ + Type: "notify", + Notify: tc, + })) + require.NoError(t, decoder.Decode(&event)) + require.Equal(t, "error", event.Kind) + require.NotContains(t, event.Text, "invalid source") + } + + _, err = io.WriteString(conn, `{"type":"notify","agent":"Garden","notify":{"source":"check","id":"1","text":"data"}}`+"\n") + require.NoError(t, err) + require.NoError(t, decoder.Decode(&event)) + require.Equal(t, "error", event.Kind) + + require.Zero(t, server.Calls()) + require.NoError(t, conn.Close()) +} + func TestClientsSeeTheTurnAsItHappens(t *testing.T) { server := newModelFake(t) server.reply = func(w http.ResponseWriter, call ModelFakeCall) { @@ -39,7 +134,7 @@ func TestClientsSeeTheTurnAsItHappens(t *testing.T) { first.Type(stopCommand) first.WaitFor(t, "[error] no turn runs") first.Type(stopCommand + " BlueFox") - first.WaitFor(t, "[error] no subagent BlueFox runs") + first.WaitFor(t, "[error] stop subagent: no subagent BlueFox runs") require.NotContains(t, second.Output(), "no turn runs") require.NoError(t, first.Close()) } @@ -109,12 +204,12 @@ func TestDaemonLogHasATimeStampOnlyOutsideTheJournal(t *testing.T) { { name: "the journal adds the time itself", journal: "8:12345", - line: `^onechat: the agent is ready\n$`, + line: `^<6>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$`, + line: `^\d{4}/\d\d/\d\d \d\d:\d\d:\d\d INFO onechat: the agent is ready\n$`, }, } @@ -124,7 +219,7 @@ func TestDaemonLogHasATimeStampOnlyOutsideTheJournal(t *testing.T) { var out strings.Builder - daemonLogger(&out, "onechat: ").Print("the agent is ready") + daemonLogger(&out, "onechat: ").Info("the agent is ready") require.Regexp(t, tc.line, out.String()) }) }