Source file
src/cmd/go/terminal_test.go
1
2
3
4
5 package main_test
6
7 import (
8 "errors"
9 "internal/testenv"
10 "internal/testpty"
11 "io"
12 "os"
13 "testing"
14
15 "golang.org/x/term"
16 )
17
18 func TestTerminalPassthrough(t *testing.T) {
19 t.Parallel()
20
21
22
23
24
25
26 testenv.MustHaveGoBuild(t)
27
28
29
30
31 t.Run("pipe", func(t *testing.T) {
32 t.Parallel()
33 r, w, err := os.Pipe()
34 if err != nil {
35 t.Fatalf("pipe failed: %s", err)
36 }
37 defer r.Close()
38 defer w.Close()
39 stdout, stderr := runTerminalPassthrough(t, r, w)
40 if stdout {
41 t.Errorf("stdout is unexpectedly a terminal")
42 }
43 if stderr {
44 t.Errorf("stderr is unexpectedly a terminal")
45 }
46 })
47
48
49 t.Run("pty", func(t *testing.T) {
50 t.Parallel()
51 r, processTTY, err := testpty.Open()
52 if errors.Is(err, testpty.ErrNotSupported) {
53 t.Skipf("%s", err)
54 } else if err != nil {
55 t.Fatalf("failed to open test PTY: %s", err)
56 }
57 defer r.Close()
58 w, err := os.OpenFile(processTTY, os.O_RDWR, 0)
59 if err != nil {
60 t.Fatal(err)
61 }
62 defer w.Close()
63 stdout, stderr := runTerminalPassthrough(t, r, w)
64 if !stdout {
65 t.Errorf("stdout is not a terminal")
66 }
67 if !stderr {
68 t.Errorf("stderr is not a terminal")
69 }
70 })
71 }
72
73 func runTerminalPassthrough(t *testing.T, r, w *os.File) (stdout, stderr bool) {
74 cmd := testenv.Command(t, testGo, "test", "-run=^$")
75 cmd.Env = append(cmd.Environ(), "GO_TEST_TERMINAL_PASSTHROUGH=1")
76 cmd.Stdout = w
77 cmd.Stderr = w
78
79
80
81
82
83
84
85
86 stdin, err := cmd.StdinPipe()
87 if err != nil {
88 t.Fatal(err)
89 }
90
91 t.Logf("running %s", cmd)
92 err = cmd.Start()
93 if err != nil {
94 t.Fatalf("starting subprocess: %s", err)
95 }
96 w.Close()
97 t.Cleanup(func() {
98 stdin.Close()
99 if err := cmd.Wait(); err != nil {
100 t.Errorf("suprocess failed with: %s", err)
101 }
102 })
103
104 buf := make([]byte, 2)
105 n, err := io.ReadFull(r, buf)
106 if err != nil || !(buf[0] == '1' || buf[0] == 'X') || !(buf[1] == '2' || buf[1] == 'X') {
107 t.Logf("read error: %v", err)
108 t.Fatalf("expected 2 bytes matching `[1X][2X]`; got %q", buf[:n])
109 }
110 return buf[0] == '1', buf[1] == '2'
111 }
112
113 func init() {
114 if os.Getenv("GO_TEST_TERMINAL_PASSTHROUGH") == "" {
115 return
116 }
117
118 if term.IsTerminal(1) {
119 os.Stdout.WriteString("1")
120 } else {
121 os.Stdout.WriteString("X")
122 }
123 if term.IsTerminal(2) {
124 os.Stdout.WriteString("2")
125 } else {
126 os.Stdout.WriteString("X")
127 }
128
129
130
131 io.Copy(io.Discard, os.Stdin)
132
133 os.Exit(0)
134 }
135
View as plain text