93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func askWorld(t *testing.T, enrol bool) string {
|
|
t.Helper()
|
|
uiTestConfigDir(t)
|
|
stubStopWorld(t, []agentObs{
|
|
{PID: 101, Kind: kindAgent, Signature: "aider", User: "u"},
|
|
{PID: 102, Kind: kindAgent, Signature: "aider", User: "u"},
|
|
{PID: 103, Kind: kindAgent, Signature: "aider", User: "u"},
|
|
{PID: 104, Kind: kindAgent, Signature: "aider", User: "u"},
|
|
{PID: 105, Kind: kindAgent, Signature: "aider", User: "u"},
|
|
{PID: 106, Kind: kindAgent, Signature: "aider", User: "u"},
|
|
{PID: 300, Kind: kindAgent, Signature: "claude-code", User: "u"},
|
|
{PID: 4532, Kind: kindApp, Signature: "claude-desktop", User: "u"},
|
|
}, map[int]int{310: 300, 311: 310}) // 311: a shell the claude-code session started
|
|
prev := homeForUserFn
|
|
t.Cleanup(func() { homeForUserFn = prev })
|
|
homeForUserFn = func(string) string { return "" }
|
|
d, err := machineFactorDir()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if enrol {
|
|
enrolFactorAt(t, d, machineTestSecret)
|
|
}
|
|
return d
|
|
}
|
|
|
|
// An ask from another account becomes a pending request naming the agent
|
|
// that asked, from the kernel's pid, and approves nothing.
|
|
func TestAnAskBecomesARequestNamingTheAgentThatAsked(t *testing.T) {
|
|
d := askWorld(t, true)
|
|
r := fileAsk(agentAskRequest{Op: "stop", PID: 101}, "u", 311)
|
|
if !r.OK {
|
|
t.Fatalf("refused: %s", r.Why)
|
|
}
|
|
if !strings.Contains(r.Text, "Asked from Claude Code (pid 300), running as u.") {
|
|
t.Errorf("the request reads %q", r.Text)
|
|
}
|
|
pending := sortedPending(requestsLoad(d))
|
|
if len(pending) != 1 {
|
|
t.Fatalf("pending %v", pending)
|
|
}
|
|
for _, a := range approvalsLoad(d) {
|
|
t.Fatalf("an ask produced an approval: %+v", a)
|
|
}
|
|
}
|
|
|
|
func TestAnAskIsRefusedWithoutTheOwnersCodeOrForAnApp(t *testing.T) {
|
|
askWorld(t, false)
|
|
if r := fileAsk(agentAskRequest{Op: "stop", PID: 101}, "u", 0); r.OK || !strings.Contains(r.Why, "not set up their code") {
|
|
t.Errorf("no owner code: %+v", r)
|
|
}
|
|
askWorld(t, true)
|
|
if r := fileAsk(agentAskRequest{Op: "stop", PID: 4532}, "u", 0); r.OK || !strings.Contains(r.Why, "an app you are running") {
|
|
t.Errorf("an app: %+v", r)
|
|
}
|
|
if r := fileAsk(agentAskRequest{Op: "approve", PID: 101}, "u", 0); r.OK {
|
|
t.Errorf("an op other than stop was filed: %+v", r)
|
|
}
|
|
}
|
|
|
|
// One account cannot bury the owner in requests.
|
|
func TestOneAccountHasAtMostFiveAsksWaiting(t *testing.T) {
|
|
d := askWorld(t, true)
|
|
for i := 0; i < askMaxPendingPer; i++ {
|
|
if r := fileAsk(agentAskRequest{Op: "stop", PID: 101 + i}, "u", 0); !r.OK {
|
|
t.Fatalf("ask %d refused: %s", i+1, r.Why)
|
|
}
|
|
}
|
|
if r := fileAsk(agentAskRequest{Op: "stop", PID: 106}, "u", 0); r.OK || !strings.Contains(r.Why, "already have 5") {
|
|
t.Errorf("the sixth: %+v", r)
|
|
}
|
|
if r := fileAsk(agentAskRequest{Op: "stop", PID: 106}, "other", 0); !r.OK {
|
|
t.Errorf("another account was held to the first one's count: %s", r.Why)
|
|
}
|
|
// Asking again for the same agent is the same request, not another one:
|
|
// it is handed back (so the asker can follow it), and nothing new is filed.
|
|
before := len(sortedPending(requestsLoad(d)))
|
|
if r := fileAsk(agentAskRequest{Op: "stop", PID: 101}, "u", 0); !r.OK ||
|
|
requestsLoad(d)[fullRequestID(t, d, r.Request)].Details["pid"] != "101" {
|
|
t.Errorf("a repeat ask past the cap: %+v", r)
|
|
}
|
|
if after := len(sortedPending(requestsLoad(d))); after != before {
|
|
t.Errorf("a repeat ask past the cap filed a new request: %d -> %d pending", before, after)
|
|
}
|
|
}
|