package cli import ( "testing" "git.cloudinit.dev/coreci/orca/internal/jobspec" ) func TestSplitCommand(t *testing.T) { tests := []struct { name string input string wantBin string wantArgs []string }{ { name: "single binary", input: "/bin/true", wantBin: "/bin/true", wantArgs: nil, }, { name: "binary with one arg", input: "/bin/echo hello", wantBin: "/bin/echo", wantArgs: []string{"hello"}, }, { name: "binary with multiple args", input: "/usr/bin/httpd -f /etc/orca/web-app/httpd.conf", wantBin: "/usr/bin/httpd", wantArgs: []string{"-f", "/etc/orca/web-app/httpd.conf"}, }, { name: "binary with sh -c and quoted string", input: "/bin/sh -c 'echo hello world'", wantBin: "/bin/sh", wantArgs: []string{"-c", "'echo", "hello", "world'"}, }, { name: "empty command falls back to /bin/true", input: "", wantBin: "/bin/true", wantArgs: nil, }, { name: "all-whitespace command falls back to /bin/true", input: " \t ", wantBin: "/bin/true", wantArgs: nil, }, { name: "multiple spaces between args", input: "/bin/echo hello world", wantBin: "/bin/echo", wantArgs: []string{"hello", "world"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotBin, gotArgs := splitCommand(tt.input) if gotBin != tt.wantBin { t.Errorf("splitCommand(%q) bin = %q, want %q", tt.input, gotBin, tt.wantBin) } if len(gotArgs) != len(tt.wantArgs) { t.Errorf("splitCommand(%q) args len = %d, want %d (got %v, want %v)", tt.input, len(gotArgs), len(tt.wantArgs), gotArgs, tt.wantArgs) return } for i, a := range gotArgs { if a != tt.wantArgs[i] { t.Errorf("splitCommand(%q) args[%d] = %q, want %q", tt.input, i, a, tt.wantArgs[i]) } } }) } } func TestWorkloadToTaskSpecs_SplitsCommand(t *testing.T) { spec := &jobspec.WorkloadSpec{ Name: "web-app", Runtime: &jobspec.RuntimeBlock{ OneOf: "process", Command: "/usr/bin/httpd -f /etc/orca/web-app/httpd.conf", }, } tasks := workloadToTaskSpecs(spec) if len(tasks) != 1 { t.Fatalf("expected 1 task, got %d", len(tasks)) } if tasks[0].Command != "/usr/bin/httpd" { t.Errorf("expected Command=/usr/bin/httpd, got %q", tasks[0].Command) } if len(tasks[0].Args) != 2 { t.Fatalf("expected 2 args, got %d (%v)", len(tasks[0].Args), tasks[0].Args) } if tasks[0].Args[0] != "-f" || tasks[0].Args[1] != "/etc/orca/web-app/httpd.conf" { t.Errorf("expected args [-f /etc/orca/web-app/httpd.conf], got %v", tasks[0].Args) } } func TestWorkloadToTaskSpecs_NilRuntimeUsesBinTrue(t *testing.T) { spec := &jobspec.WorkloadSpec{ Name: "noop", } tasks := workloadToTaskSpecs(spec) if len(tasks) != 1 { t.Fatalf("expected 1 task, got %d", len(tasks)) } if tasks[0].Command != "/bin/true" { t.Errorf("expected Command=/bin/true, got %q", tasks[0].Command) } if len(tasks[0].Args) != 0 { t.Errorf("expected 0 args, got %d (%v)", len(tasks[0].Args), tasks[0].Args) } } func TestWorkloadToTaskSpecs_EmptyCommandUsesBinTrue(t *testing.T) { spec := &jobspec.WorkloadSpec{ Name: "empty", Runtime: &jobspec.RuntimeBlock{ OneOf: "process", Command: "", }, } tasks := workloadToTaskSpecs(spec) if len(tasks) != 1 { t.Fatalf("expected 1 task, got %d", len(tasks)) } if tasks[0].Command != "/bin/true" { t.Errorf("expected Command=/bin/true, got %q", tasks[0].Command) } } func TestWorkloadToTaskSpecs_NilSpecReturnsNil(t *testing.T) { tasks := workloadToTaskSpecs(nil) if tasks != nil { t.Errorf("expected nil, got %v", tasks) } }