iop/apps/node/internal/adapters/cli/oneshot/cli_test.go
toki 0988942b07 refactor: reorganize CLI adapter into subpackages
- Move cli_test.go to internal/, lifecycle/, onshot/, persistent/
- Restructure CLI adapter modules into organized subdirectories
2026-05-03 18:19:00 +09:00

94 lines
2.3 KiB
Go

package oneshot_test
import (
"context"
"strings"
"testing"
"time"
"go.uber.org/zap"
clipkg "iop/apps/node/internal/adapters/cli"
"iop/apps/node/internal/adapters/cli/internal/testutil"
noderuntime "iop/apps/node/internal/runtime"
"iop/packages/config"
)
func TestCLIExecuteOneShotPassesPromptAsArg(t *testing.T) {
testutil.RequireUnixShell(t)
cfg := config.CLIConf{
Enabled: true,
Profiles: map[string]config.CLIProfileConf{
"echo": {
Command: "sh",
Args: []string{"-c", `printf "reply:%s\n" "$1"`, "sh"},
},
},
}
c := clipkg.New(cfg, zap.NewNop())
sink := &testutil.FakeSink{}
err := c.Execute(context.Background(), noderuntime.ExecutionSpec{
RunID: "run-1",
Model: "echo",
Input: map[string]any{"prompt": "hello"},
}, sink)
if err != nil {
t.Fatalf("execute: %v", err)
}
events := sink.Events()
var types []string
for _, e := range events {
types = append(types, string(e.Type))
}
if len(events) < 3 {
t.Fatalf("expected at least 3 events (start/delta/complete), got %v", types)
}
if events[0].Type != noderuntime.EventTypeStart {
t.Fatalf("first event should be start, got %q", events[0].Type)
}
if events[len(events)-1].Type != noderuntime.EventTypeComplete {
t.Fatalf("last event should be complete, got %q", events[len(events)-1].Type)
}
if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:hello") {
t.Fatalf("expected reply:hello in deltas, got %q", combined)
}
}
func TestCLIExecuteOneShotDrainsStderrConcurrently(t *testing.T) {
testutil.RequireUnixShell(t)
cfg := config.CLIConf{
Enabled: true,
Profiles: map[string]config.CLIProfileConf{
"noisy": {
Command: "sh",
Args: []string{
"-c",
`i=0; while [ "$i" -lt 20000 ]; do echo "warning line $i" >&2; i=$((i+1)); done; printf "reply:%s\n" "$1"`,
"sh",
},
},
},
}
c := clipkg.New(cfg, zap.NewNop())
sink := &testutil.FakeSink{}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
err := c.Execute(ctx, noderuntime.ExecutionSpec{
RunID: "run-noisy",
Model: "noisy",
Input: map[string]any{"prompt": "hello"},
}, sink)
if err != nil {
t.Fatalf("execute: %v", err)
}
if combined := testutil.CollectDeltas(sink.Events()); !strings.Contains(combined, "reply:hello") {
t.Fatalf("expected reply:hello in deltas, got %q", combined)
}
}