iop/apps/agent/internal/command/task_loop_test.go

88 lines
3.1 KiB
Go

package command
import (
"strings"
"testing"
)
func TestTaskLoopCommandMapsDryRunFilterRetryAndTerminalExit(t *testing.T) {
cases := []struct {
name string
args []string
response TaskLoopResponse
wantErr bool
assert func(t *testing.T, request TaskLoopRequest)
}{
{
name: "dry run filter", args: []string{"task-loop", "--dry-run", "--task-group", "m-m1", "--repo-config", "/r", "--local-config", "/l"},
response: TaskLoopResponse{DryRun: true},
assert: func(t *testing.T, request TaskLoopRequest) {
if !request.DryRun || request.TaskGroup != "m-m1" || request.RetryBlocked {
t.Fatalf("request = %#v", request)
}
},
},
{
name: "retry blocked", args: []string{"task-loop", "--retry-blocked", "--task-group", "m-m1", "--repo-config", "/r", "--local-config", "/l", "--provider-catalog", "/c"},
response: TaskLoopResponse{},
assert: func(t *testing.T, request TaskLoopRequest) {
if request.DryRun || !request.RetryBlocked || request.Config.ProviderCatalog != "/c" {
t.Fatalf("request = %#v", request)
}
},
},
{
name: "drained blocker terminal", args: []string{"task-loop", "--repo-config", "/r", "--local-config", "/l"},
response: TaskLoopResponse{ExitCode: 2}, wantErr: true,
assert: func(t *testing.T, request TaskLoopRequest) {},
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
svc := newTestService()
svc.taskLoopResp = tt.response
root := NewRoot(svc, newTextBuf(), newTextBuf())
stdout, _, err := cmdRunner(t, root, tt.args)
if (err != nil) != tt.wantErr {
t.Fatalf("error = %v, want error=%t", err, tt.wantErr)
}
if !strings.Contains(stdout, "task-loop") {
t.Fatalf("stdout = %q", stdout)
}
tt.assert(t, svc.lastTaskLoopReq)
})
}
}
func TestTaskLoopParityRequiresDisposalManifest(t *testing.T) {
svc := newTestService()
root := NewRoot(svc, newTextBuf(), newTextBuf())
if _, _, err := cmdRunner(t, root, []string{"task-loop", "parity"}); err == nil {
t.Fatal("expected missing disposal manifest error")
}
stdout, _, err := cmdRunner(t, root, []string{"task-loop", "parity", "--disposal-manifest"})
if err != nil || stdout != "parity: ok\n" {
t.Fatalf("stdout=%q err=%v", stdout, err)
}
}
func TestTaskLoopValidatePlanMapsRequestAndPropagatesError(t *testing.T) {
svc := newTestService()
root := NewRoot(svc, newTextBuf(), newTextBuf())
stdout, _, err := cmdRunner(t, root, []string{"task-loop", "validate-plan", "--workspace", "/workspace", "/tmp/plan.md"})
if err != nil || stdout != "" {
t.Fatalf("stdout=%q err=%v", stdout, err)
}
if svc.lastPlanValidationReq != (PlanValidationRequest{Workspace: "/workspace", PlanPath: "/tmp/plan.md"}) {
t.Fatalf("request = %#v", svc.lastPlanValidationReq)
}
svc.planValidationErr = assertError{}
_, _, err = cmdRunner(t, root, []string{"task-loop", "validate-plan", "--workspace", "/workspace", "/tmp/plan.md"})
if err == nil || !strings.Contains(err.Error(), "validate-plan") {
t.Fatalf("error = %v", err)
}
}
type assertError struct{}
func (assertError) Error() string { return "rejected" }