| package orchestrator |
|
|
| import ( |
| "context" |
| "io" |
| "testing" |
|
|
| "github.com/pinchtab/pinchtab/internal/bridge" |
| "github.com/pinchtab/pinchtab/internal/idutil" |
| ) |
|
|
| type mockRunner struct { |
| runCalled bool |
| portAvail bool |
| args []string |
| } |
|
|
| type mockCmd struct { |
| pid int |
| isAlive bool |
| } |
|
|
| func (m *mockCmd) Wait() error { return nil } |
| func (m *mockCmd) PID() int { return m.pid } |
| func (m *mockCmd) Cancel() {} |
|
|
| func (m *mockRunner) Run(ctx context.Context, binary string, args []string, env []string, stdout, stderr io.Writer) (Cmd, error) { |
| m.runCalled = true |
| m.args = append([]string(nil), args...) |
| return &mockCmd{pid: 1234, isAlive: true}, nil |
| } |
|
|
| func (m *mockRunner) IsPortAvailable(port string) bool { |
| return m.portAvail |
| } |
|
|
| func TestLaunch_Mocked(t *testing.T) { |
| runner := &mockRunner{portAvail: true} |
| o := NewOrchestratorWithRunner(t.TempDir(), runner) |
|
|
| inst, err := o.Launch("test-prof", "9999", true, nil) |
| if err != nil { |
| t.Fatalf("Launch failed: %v", err) |
| } |
|
|
| if !runner.runCalled { |
| t.Error("expected runner.Run to be called") |
| } |
| if len(runner.args) != 1 || runner.args[0] != "bridge" { |
| t.Fatalf("expected child process args [bridge], got %v", runner.args) |
| } |
| if !idutil.IsValidID(inst.ID, "inst") { |
| t.Errorf("expected ID format inst_XXXXXXXX, got %s", inst.ID) |
| } |
| } |
|
|
| func TestLaunch_PortConflict(t *testing.T) { |
| runner := &mockRunner{portAvail: false} |
| o := NewOrchestratorWithRunner(t.TempDir(), runner) |
|
|
| _, err := o.Launch("test-prof", "9999", true, nil) |
| if err == nil { |
| t.Fatal("expected error for unavailable port") |
| } |
| } |
|
|
| func TestInstanceIsActive(t *testing.T) { |
| tests := []struct { |
| name string |
| inst *InstanceInternal |
| active bool |
| }{ |
| { |
| name: "starting", |
| inst: &InstanceInternal{ |
| Instance: bridge.Instance{Status: "starting"}, |
| }, |
| active: true, |
| }, |
| { |
| name: "running", |
| inst: &InstanceInternal{ |
| Instance: bridge.Instance{Status: "running"}, |
| }, |
| active: true, |
| }, |
| } |
|
|
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| if got := instanceIsActive(tt.inst); got != tt.active { |
| t.Errorf("instanceIsActive() = %v, want %v", got, tt.active) |
| } |
| }) |
| } |
| } |
|
|