@@ -12,6 +12,7 @@ import (
1212 "time"
1313
1414 "github.com/docker/cli/cli/command"
15+ "github.com/docker/cli/cli/streams"
1516 "github.com/docker/cli/internal/test"
1617 "github.com/pkg/errors"
1718 "gotest.tools/v3/assert"
@@ -81,46 +82,98 @@ func TestPromptForConfirmation(t *testing.T) {
8182 ctx , cancel := context .WithCancel (context .Background ())
8283 t .Cleanup (cancel )
8384
85+ t .Run ("case=prompt should wait for user input" , func (t * testing.T ) {
86+ buf := new (bytes.Buffer )
87+ wroteHook := make (chan struct {}, 1 )
88+ bufioWriter := bufio .NewWriter (buf )
89+ w := test .NewWriterWithHook (bufioWriter , func (p []byte ) {
90+ wroteHook <- struct {}{}
91+ })
92+
93+ r , _ , err := os .Pipe ()
94+ assert .NilError (t , err )
95+ in := streams .NewIn (r )
96+
97+ result := make (chan bool , 1 )
98+ go func () {
99+ result <- command .PromptForConfirmation (ctx , in , w , "" )
100+ }()
101+
102+ // wait for the prompt to write to the buffer
103+ pollForPromptOutput (ctx , t , wroteHook )
104+
105+ assert .NilError (t , bufioWriter .Flush ())
106+ assert .Check (t , strings .Contains (buf .String (), "Are you sure you want to proceed? [y/N]" ))
107+
108+ writeCtx , writeCancel := context .WithTimeout (ctx , 100 * time .Millisecond )
109+ defer writeCancel ()
110+
111+ writeInputChan := make (chan struct {})
112+
113+ go func () {
114+ _ , err := w .Write ([]byte ("n" ))
115+ assert .NilError (t , err )
116+ writeInputChan <- struct {}{}
117+ }()
118+
119+ select {
120+ case <- writeCtx .Done ():
121+ t .Fatal ("PromptForConfirmation did not receive user input" )
122+ case <- result :
123+ t .Fatal ("PromptForConfirmation returned before user input" )
124+ case <- writeInputChan :
125+ }
126+ })
127+
84128 t .Run ("case=terminate the prompt with SIGINT" , func (t * testing.T ) {
85129 wroteHook := make (chan struct {}, 1 )
86130 buf := new (bytes.Buffer )
87131 bufioWriter := bufio .NewWriter (buf )
88- w := test .NewWriterWithHook (bufioWriter , func () {
132+ w := test .NewWriterWithHook (bufioWriter , func (p [] byte ) {
89133 wroteHook <- struct {}{}
90134 })
91135
92- in := test . NewFakeStreamIn ( ctx , time . Second * 2 )
93- t . Cleanup ( func () {
94- assert . NilError ( t , in . Close () )
95- })
136+ r , _ , err := os . Pipe ( )
137+ assert . NilError ( t , err )
138+ in := streams . NewIn ( r )
139+
96140 result := make (chan bool , 1 )
141+ defer close (result )
142+
97143 go func () {
98- defer close (result )
99144 result <- command .PromptForConfirmation (ctx , in , w , "" )
100145 }()
101146
102147 // wait for the Prompt to write to the buffer
103148 pollForPromptOutput (ctx , t , wroteHook )
149+
104150 assert .NilError (t , bufioWriter .Flush ())
105151 assert .Equal (t , strings .TrimSpace (buf .String ()), "Are you sure you want to proceed? [y/N]" )
106152
153+ resultCtx , resultCancel := context .WithTimeout (ctx , 100 * time .Millisecond )
154+ defer resultCancel ()
155+
107156 syscall .Kill (syscall .Getpid (), syscall .SIGINT )
157+
108158 select {
159+ case <- resultCtx .Done ():
160+ t .Fatal ("PromptForConfirmation did not return after SIGINT" )
109161 case r := <- result :
110162 assert .Check (t , ! r )
111- case <- time .After (100 * time .Millisecond ):
112- t .Fatal ("PromptForConfirmation did not return after SIGINT" )
113163 }
114164 })
115165
116166 t .Run ("case=prompt should return on io.EOF" , func (t * testing.T ) {
117167 buf := new (bytes.Buffer )
118168 wroteHook := make (chan struct {}, 1 )
119169 bufioWriter := bufio .NewWriter (buf )
120- w := test .NewWriterWithHook (bufioWriter , func () {
170+ w := test .NewWriterWithHook (bufioWriter , func (p [] byte ) {
121171 wroteHook <- struct {}{}
122172 })
123- in := test .NewFakeStreamIn (ctx , 0 )
173+
174+ r , _ , err := os .Pipe ()
175+ assert .NilError (t , err )
176+ in := streams .NewIn (r )
124177
125178 result := make (chan bool , 1 )
126179 go func () {
@@ -132,13 +185,17 @@ func TestPromptForConfirmation(t *testing.T) {
132185
133186 assert .NilError (t , bufioWriter .Flush ())
134187 assert .Check (t , strings .Contains (buf .String (), "Are you sure you want to proceed? [y/N]" ))
188+
135189 assert .NilError (t , in .Close ())
136190
191+ resultCtx , resultCancel := context .WithTimeout (ctx , 100 * time .Millisecond )
192+ defer resultCancel ()
193+
137194 select {
195+ case <- resultCtx .Done ():
196+ t .Fatal ("PromptForConfirmation did not return after io.EOF" )
138197 case r := <- result :
139198 assert .Check (t , ! r )
140- case <- time .After (100 * time .Millisecond ):
141- t .Fatal ("PromptForConfirmation did not return after io.EOF" )
142199 }
143200 })
144201}
0 commit comments