Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdc71bd8

Browse files
committed
Get test passing on Linux, w/ new cross-plat pty abstraction
1 parentdf13fef commitdc71bd8

15 files changed

+2034
-3
lines changed

‎cli/login_test.go‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/coder/coder/coderd/coderdtest"
1010
"github.com/stretchr/testify/require"
1111

12-
"github.com/Netflix/go-expect"
12+
"github.com/coder/coder/expect"
1313
)
1414

1515
funcTestLogin(t*testing.T) {
@@ -28,8 +28,8 @@ func TestLogin(t *testing.T) {
2828
require.NoError(t,err)
2929
client:=coderdtest.New(t)
3030
root,_:=clitest.New(t,"login",client.URL.String())
31-
root.SetIn(console.Tty())
32-
root.SetOut(console.Tty())
31+
root.SetIn(console.InTty())
32+
root.SetOut(console.OutTty())
3333
gofunc() {
3434
err:=root.Execute()
3535
require.NoError(t,err)

‎expect/console.go‎

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// Copyright 2018 Netflix, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package expect
16+
17+
import (
18+
"bufio"
19+
"fmt"
20+
"io"
21+
"io/ioutil"
22+
"log"
23+
"os"
24+
"time"
25+
"unicode/utf8"
26+
27+
"github.com/coder/coder/expect/pty"
28+
)
29+
30+
// Console is an interface to automate input and output for interactive
31+
// applications. Console can block until a specified output is received and send
32+
// input back on it's tty. Console can also multiplex other sources of input
33+
// and multiplex its output to other writers.
34+
typeConsolestruct {
35+
optsConsoleOpts
36+
pty pty.Pty
37+
passthroughPipe*PassthroughPipe
38+
runeReader*bufio.Reader
39+
closers []io.Closer
40+
}
41+
42+
// ConsoleOpt allows setting Console options.
43+
typeConsoleOptfunc(*ConsoleOpts)error
44+
45+
// ConsoleOpts provides additional options on creating a Console.
46+
typeConsoleOptsstruct {
47+
Logger*log.Logger
48+
Stdouts []io.Writer
49+
Closers []io.Closer
50+
ExpectObservers []ExpectObserver
51+
SendObservers []SendObserver
52+
ReadTimeout*time.Duration
53+
}
54+
55+
// ExpectObserver provides an interface for a function callback that will
56+
// be called after each Expect operation.
57+
// matchers will be the list of active matchers when an error occurred,
58+
// or a list of matchers that matched `buf` when err is nil.
59+
// buf is the captured output that was matched against.
60+
// err is error that might have occurred. May be nil.
61+
typeExpectObserverfunc(matchers []Matcher,bufstring,errerror)
62+
63+
// SendObserver provides an interface for a function callback that will
64+
// be called after each Send operation.
65+
// msg is the string that was sent.
66+
// num is the number of bytes actually sent.
67+
// err is the error that might have occured. May be nil.
68+
typeSendObserverfunc(msgstring,numint,errerror)
69+
70+
// WithStdout adds writers that Console duplicates writes to, similar to the
71+
// Unix tee(1) command.
72+
//
73+
// Each write is written to each listed writer, one at a time. Console is the
74+
// last writer, writing to it's internal buffer for matching expects.
75+
// If a listed writer returns an error, that overall write operation stops and
76+
// returns the error; it does not continue down the list.
77+
funcWithStdout(writers...io.Writer)ConsoleOpt {
78+
returnfunc(opts*ConsoleOpts)error {
79+
opts.Stdouts=append(opts.Stdouts,writers...)
80+
returnnil
81+
}
82+
}
83+
84+
// WithCloser adds closers that are closed in order when Console is closed.
85+
funcWithCloser(closer...io.Closer)ConsoleOpt {
86+
returnfunc(opts*ConsoleOpts)error {
87+
opts.Closers=append(opts.Closers,closer...)
88+
returnnil
89+
}
90+
}
91+
92+
// WithLogger adds a logger for Console to log debugging information to. By
93+
// default Console will discard logs.
94+
funcWithLogger(logger*log.Logger)ConsoleOpt {
95+
returnfunc(opts*ConsoleOpts)error {
96+
opts.Logger=logger
97+
returnnil
98+
}
99+
}
100+
101+
// WithExpectObserver adds an ExpectObserver to allow monitoring Expect operations.
102+
funcWithExpectObserver(observers...ExpectObserver)ConsoleOpt {
103+
returnfunc(opts*ConsoleOpts)error {
104+
opts.ExpectObservers=append(opts.ExpectObservers,observers...)
105+
returnnil
106+
}
107+
}
108+
109+
// WithSendObserver adds a SendObserver to allow monitoring Send operations.
110+
funcWithSendObserver(observers...SendObserver)ConsoleOpt {
111+
returnfunc(opts*ConsoleOpts)error {
112+
opts.SendObservers=append(opts.SendObservers,observers...)
113+
returnnil
114+
}
115+
}
116+
117+
// WithDefaultTimeout sets a default read timeout during Expect statements.
118+
funcWithDefaultTimeout(timeout time.Duration)ConsoleOpt {
119+
returnfunc(opts*ConsoleOpts)error {
120+
opts.ReadTimeout=&timeout
121+
returnnil
122+
}
123+
}
124+
125+
// NewConsole returns a new Console with the given options.
126+
funcNewConsole(opts...ConsoleOpt) (*Console,error) {
127+
options:=ConsoleOpts{
128+
Logger:log.New(ioutil.Discard,"",0),
129+
}
130+
131+
for_,opt:=rangeopts {
132+
iferr:=opt(&options);err!=nil {
133+
returnnil,err
134+
}
135+
}
136+
137+
pty,err:=pty.New()
138+
iferr!=nil {
139+
returnnil,err
140+
}
141+
closers:=append(options.Closers,pty)
142+
reader:=pty.Reader()
143+
144+
passthroughPipe,err:=NewPassthroughPipe(reader)
145+
iferr!=nil {
146+
returnnil,err
147+
}
148+
closers=append(closers,passthroughPipe)
149+
150+
c:=&Console{
151+
opts:options,
152+
pty:pty,
153+
passthroughPipe:passthroughPipe,
154+
runeReader:bufio.NewReaderSize(passthroughPipe,utf8.UTFMax),
155+
closers:closers,
156+
}
157+
158+
/*for _, stdin := range options.Stdins {
159+
go func(stdin io.Reader) {
160+
_, err := io.Copy(c, stdin)
161+
if err != nil {
162+
c.Logf("failed to copy stdin: %s", err)
163+
}
164+
}(stdin)
165+
}*/
166+
167+
returnc,nil
168+
}
169+
170+
// Tty returns an input Tty for accepting input
171+
func (c*Console)InTty()*os.File {
172+
returnc.pty.InPipe()
173+
}
174+
175+
// OutTty returns an output tty for writing
176+
func (c*Console)OutTty()*os.File {
177+
returnc.pty.OutPipe()
178+
}
179+
180+
// Read reads bytes b from Console's tty.
181+
/*func (c *Console) Read(b []byte) (int, error) {
182+
return c.ptm.Read(b)
183+
}*/
184+
185+
// Write writes bytes b to Console's tty.
186+
/*func (c *Console) Write(b []byte) (int, error) {
187+
c.Logf("console write: %q", b)
188+
return c.ptm.Write(b)
189+
}*/
190+
191+
// Fd returns Console's file descripting referencing the master part of its
192+
// pty.
193+
/*func (c *Console) Fd() uintptr {
194+
return c.ptm.Fd()
195+
}*/
196+
197+
// Close closes Console's tty. Calling Close will unblock Expect and ExpectEOF.
198+
func (c*Console)Close()error {
199+
for_,fd:=rangec.closers {
200+
err:=fd.Close()
201+
iferr!=nil {
202+
c.Logf("failed to close: %s",err)
203+
}
204+
}
205+
returnnil
206+
}
207+
208+
// Send writes string s to Console's tty.
209+
func (c*Console)Send(sstring) (int,error) {
210+
c.Logf("console send: %q",s)
211+
n,err:=c.pty.WriteString(s)
212+
for_,observer:=rangec.opts.SendObservers {
213+
observer(s,n,err)
214+
}
215+
returnn,err
216+
}
217+
218+
// SendLine writes string s to Console's tty with a trailing newline.
219+
func (c*Console)SendLine(sstring) (int,error) {
220+
returnc.Send(fmt.Sprintf("%s\n",s))
221+
}
222+
223+
// Log prints to Console's logger.
224+
// Arguments are handled in the manner of fmt.Print.
225+
func (c*Console)Log(v...interface{}) {
226+
c.opts.Logger.Print(v...)
227+
}
228+
229+
// Logf prints to Console's logger.
230+
// Arguments are handled in the manner of fmt.Printf.
231+
func (c*Console)Logf(formatstring,v...interface{}) {
232+
c.opts.Logger.Printf(format,v...)
233+
}

‎expect/doc.go‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2018 Netflix, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package expect provides an expect-like interface to automate control of
16+
// applications. It is unlike expect in that it does not spawn or manage
17+
// process lifecycle. This package only focuses on expecting output and sending
18+
// input through it's psuedoterminal.
19+
package expect

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp