package process import ( "bytes" "context" "os" "os/exec" "path/filepath" "strings" "testing" "time" "github.com/stretchr/testify/require" ) func TestProcessFixture(t *testing.T) { mode := os.Getenv("MPV_PROCESS_FIXTURE") if mode == "" { return } root := os.Getenv("MPV_PROCESS_FIXTURE_DIR") if mode == "child" { require.NoError(t, os.WriteFile(filepath.Join(root, "ready"), []byte("ready"), 0600)) time.Sleep(600 * time.Millisecond) require.NoError(t, os.WriteFile(filepath.Join(root, "late-write"), []byte("child survived"), 0600)) time.Sleep(4 * time.Second) os.Exit(0) } if mode == "noisy" { _, _ = os.Stdout.WriteString(strings.Repeat("x", 2*1024*1024)) os.Exit(0) } child := exec.Command(os.Args[0], "-test.run=^TestProcessFixture$") child.Env = append(os.Environ(), "MPV_PROCESS_FIXTURE=child") child.Stdout, child.Stderr = os.Stdout, os.Stderr require.NoError(t, child.Start()) if mode == "parent-exits" { os.Exit(0) } _ = child.Wait() os.Exit(0) } func TestCancellationStopsDescendantWithInheritedOutputPipes(t *testing.T) { for _, mode := range []string{"parent-waits", "parent-exits"} { t.Run(mode, func(t *testing.T) { root := t.TempDir() ctx, cancel := context.WithCancel(context.Background()) defer cancel() cmd := exec.Command(os.Args[0], "-test.run=^TestProcessFixture$") cmd.Env = append(os.Environ(), "MPV_PROCESS_FIXTURE="+mode, "MPV_PROCESS_FIXTURE_DIR="+root) var captured bytes.Buffer cmd.Stdout, cmd.Stderr = &captured, &captured done := make(chan error, 1) go func() { done <- Run(ctx, cmd) }() require.Eventually(t, func() bool { _, err := os.Stat(filepath.Join(root, "ready")); return err == nil }, 10*time.Second, 5*time.Millisecond) cancel() select { case err := <-done: require.Error(t, err) case <-time.After(3 * time.Second): t.Fatal("command did not join after cancellation") } time.Sleep(750 * time.Millisecond) require.NoFileExists(t, filepath.Join(root, "late-write"), "descendant must stop before worker releases ownership") }) } } func TestOutputIsBoundedAndReportsOverflow(t *testing.T) { cmd := exec.Command(os.Args[0], "-test.run=^TestProcessFixture$") cmd.Env = append(os.Environ(), "MPV_PROCESS_FIXTURE=noisy") data, err := Output(context.Background(), cmd) require.ErrorContains(t, err, "exceeded 1 MiB") require.Len(t, data, 1024*1024) }