okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

Aly Raffauffix(tui): close clipboard stdout on cancellation85b721f

main
1.3 KiB49 linesraw
1package tui
2
3// These tests catch cancellation blocked by a descendant's inherited stdout.
4// The daemon E2E suite cannot drive the TUI's local clipboard subprocesses.
5
6import (
7	"context"
8	"errors"
9	"os"
10	"os/exec"
11	"strconv"
12	"strings"
13	"testing"
14	"time"
15)
16
17func TestClipboardCancellationClosesDescendantStdout(t *testing.T) {
18	shell, err := exec.LookPath("sh")
19	if err != nil {
20		t.Skip("requires sh")
21	}
22	for _, parent := range []string{"wait", "exit 0"} {
23		t.Run(parent, func(t *testing.T) {
24			ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
25			defer cancel()
26
27			start := time.Now()
28			out, err := execClipboardCommand(ctx, shell, "-c", `sleep 2 & printf '%s\n' "$!"; `+parent)
29			elapsed := time.Since(start)
30			// Kill the fixture's descendant promptly even when an assertion fails.
31			pid, parseErr := strconv.Atoi(strings.TrimSpace(string(out)))
32			if parseErr != nil {
33				t.Fatalf("descendant did not report its PID: %q: %v", out, parseErr)
34			}
35			process, findErr := os.FindProcess(pid)
36			if findErr != nil {
37				t.Fatal(findErr)
38			}
39			_ = process.Kill()
40
41			if !errors.Is(err, context.DeadlineExceeded) {
42				t.Fatalf("expected deadline error, got %v", err)
43			}
44			if elapsed >= time.Second {
45				t.Fatalf("cancellation took %s with a 50 ms deadline", elapsed)
46			}
47		})
48	}
49}