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