TestProcAdapterLifecycleE2E drives the full loop the model will use — start → list → logs → stop → remove — against a REAL process, through the same adapter formatting the model reads.
(t *testing.T)
| 19 | // start → list → logs → stop → remove — against a REAL process, through the |
| 20 | // same adapter formatting the model reads. |
| 21 | func TestProcAdapterLifecycleE2E(t *testing.T) { |
| 22 | cli := &ChatCLI{logger: zap.NewNop()} |
| 23 | t.Cleanup(cli.shutdownProcSupervisor) |
| 24 | a := &procToolAdapter{cli: cli} |
| 25 | |
| 26 | out, err := a.Start(`sh -c 'echo ready; sleep 30'`, "") |
| 27 | if err != nil { |
| 28 | t.Fatalf("Start: %v", err) |
| 29 | } |
| 30 | if !strings.Contains(out, "started p1 (pid ") { |
| 31 | t.Fatalf("start output missing id/pid: %q", out) |
| 32 | } |
| 33 | |
| 34 | list, err := a.List() |
| 35 | if err != nil { |
| 36 | t.Fatal(err) |
| 37 | } |
| 38 | if !strings.Contains(list, "p1 running (pid ") { |
| 39 | t.Fatalf("list missing running process: %q", list) |
| 40 | } |
| 41 | |
| 42 | // Poll logs until the readiness line lands (the workflow the tool |
| 43 | // documents: poll readiness before testing against the process). |
| 44 | deadline := time.Now().Add(5 * time.Second) |
| 45 | var logs string |
| 46 | for time.Now().Before(deadline) { |
| 47 | logs, err = a.Logs("p1", 10) |
| 48 | if err != nil { |
| 49 | t.Fatal(err) |
| 50 | } |
| 51 | if strings.Contains(logs, "ready") { |
| 52 | break |
| 53 | } |
| 54 | time.Sleep(50 * time.Millisecond) |
| 55 | } |
| 56 | if !strings.Contains(logs, "ready") { |
| 57 | t.Fatalf("readiness line never appeared: %q", logs) |
| 58 | } |
| 59 | |
| 60 | stopOut, err := a.Stop("p1") |
| 61 | if err != nil { |
| 62 | t.Fatal(err) |
| 63 | } |
| 64 | if !strings.Contains(stopOut, "stopped p1") { |
| 65 | t.Fatalf("stop output wrong: %q", stopOut) |
| 66 | } |
| 67 | |
| 68 | if _, err := a.Remove("p1"); err != nil { |
| 69 | t.Fatalf("Remove: %v", err) |
| 70 | } |
| 71 | empty, err := a.List() |
| 72 | if err != nil { |
| 73 | t.Fatal(err) |
| 74 | } |
| 75 | if !strings.Contains(empty, "No background processes") { |
| 76 | t.Fatalf("list after remove: %q", empty) |
| 77 | } |
| 78 | } |