package infra import ( "strings" "testing" ) func TestProcessSpawn(t *testing.T) { t.Run("spawn and wait echo", func(t *testing.T) { h, err := ProcessSpawn("echo hello", "", nil, "") if err != nil { t.Fatalf("spawn: %v", err) } res, err := ProcessWait(h, 10) if err != nil { t.Fatalf("wait: %v", err) } if res.ExitCode != 0 { t.Errorf("exit code: got %d, want 0", res.ExitCode) } if !strings.Contains(res.Stdout, "hello") { t.Errorf("stdout: got %q, want it to contain 'hello'", res.Stdout) } }) t.Run("spawn with timeout kills", func(t *testing.T) { h, err := ProcessSpawn("sleep 60", "", nil, "") if err != nil { t.Fatalf("spawn: %v", err) } res, err := ProcessWait(h, 2) if err != nil { t.Fatalf("wait: %v", err) } if !res.Killed { t.Errorf("killed: got false, want true") } if res.ExitCode == 0 { t.Errorf("exit code: got 0, want != 0 after kill") } }) t.Run("spawn with env", func(t *testing.T) { h, err := ProcessSpawn("echo $TEST_VAR", "", []string{"PATH=/usr/bin:/bin", "TEST_VAR=hello123"}, "") if err != nil { t.Fatalf("spawn: %v", err) } res, err := ProcessWait(h, 10) if err != nil { t.Fatalf("wait: %v", err) } if !strings.Contains(res.Stdout, "hello123") { t.Errorf("stdout: got %q, want it to contain 'hello123'", res.Stdout) } }) t.Run("spawn script", func(t *testing.T) { script := "#!/bin/sh\necho line1\necho line2" h, err := ProcessSpawn(script, "", nil, "") if err != nil { t.Fatalf("spawn: %v", err) } res, err := ProcessWait(h, 10) if err != nil { t.Fatalf("wait: %v", err) } if !strings.Contains(res.Stdout, "line1") { t.Errorf("stdout: got %q, want it to contain 'line1'", res.Stdout) } if !strings.Contains(res.Stdout, "line2") { t.Errorf("stdout: got %q, want it to contain 'line2'", res.Stdout) } }) t.Run("spawn with working dir", func(t *testing.T) { h, err := ProcessSpawn("pwd", "/tmp", nil, "") if err != nil { t.Fatalf("spawn: %v", err) } res, err := ProcessWait(h, 10) if err != nil { t.Fatalf("wait: %v", err) } if !strings.Contains(res.Stdout, "/tmp") { t.Errorf("stdout: got %q, want it to contain '/tmp'", res.Stdout) } }) t.Run("kill process", func(t *testing.T) { h, err := ProcessSpawn("sleep 60", "", nil, "") if err != nil { t.Fatalf("spawn: %v", err) } if err := ProcessKill(h, 1); err != nil { t.Fatalf("kill: %v", err) } // After kill, Wait should unblock quickly. _ = h.Cmd.Wait() state := h.Cmd.ProcessState if state == nil { t.Fatal("process state is nil after kill+wait") } if state.ExitCode() == 0 { t.Errorf("exit code: got 0 after kill, want non-zero") } }) }