package proc import ( "fmt" "os/exec" "runtime" "testing" "time" ) // sleeperCmd 返回一个会阻塞约 d 秒的跨平台命令。 func sleeperCmd(d int) *exec.Cmd { if runtime.GOOS == "windows" { return exec.Command("cmd", "/c", fmt.Sprintf("timeout /t %d /nobreak >nul", d)) } return exec.Command("sh", "-c", fmt.Sprintf("sleep %d", d)) } // TestGroup_TerminateKillsStartedProcess 验证完整生命周期:Prepare → Start → // Adopt → TerminateGroup 能在 grace 内终止一个本应长跑的进程。 func TestGroup_TerminateKillsStartedProcess(t *testing.T) { g := NewGroup() cmd := sleeperCmd(30) g.Prepare(cmd) if err := cmd.Start(); err != nil { t.Fatalf("start: %v", err) } if err := g.Adopt(cmd); err != nil { t.Fatalf("adopt: %v", err) } defer g.Close() done := make(chan struct{}) go func() { _ = cmd.Wait() close(done) }() g.TerminateGroup(done, 2*time.Second) select { case <-done: // 进程已终止,符合预期。 case <-time.After(10 * time.Second): t.Fatal("process not terminated within 10s after TerminateGroup") } } // TestNewGroup_NotNil 守护 build tag 选择逻辑:任意平台都应返回非 nil Group。 func TestNewGroup_NotNil(t *testing.T) { if NewGroup() == nil { t.Fatal("NewGroup returned nil") } }