55 "errors"
66 "io"
77 "net"
8- "os/signal"
98 "syscall"
109 "testing"
1110 "time"
@@ -38,15 +37,85 @@ func TestRunLabel(t *testing.T) {
3837 assert .NilError (t , cmd .Execute ())
3938}
4039
41- func TestRunAttachTermination (t * testing.T ) {
40+ func TestRunAttach (t * testing.T ) {
4241 p , tty , err := pty .Open ()
4342 assert .NilError (t , err )
43+ defer func () {
44+ _ = tty .Close ()
45+ _ = p .Close ()
46+ }()
47+
48+ var conn net.Conn
49+ attachCh := make (chan struct {})
50+ fakeCLI := test .NewFakeCli (& fakeClient {
51+ createContainerFunc : func (_ * container.Config , _ * container.HostConfig , _ * network.NetworkingConfig , _ * specs.Platform , _ string ) (container.CreateResponse , error ) {
52+ return container.CreateResponse {
53+ ID : "id" ,
54+ }, nil
55+ },
56+ containerAttachFunc : func (ctx context.Context , containerID string , options container.AttachOptions ) (types.HijackedResponse , error ) {
57+ server , client := net .Pipe ()
58+ conn = server
59+ t .Cleanup (func () {
60+ _ = server .Close ()
61+ })
62+ attachCh <- struct {}{}
63+ return types .NewHijackedResponse (client , types .MediaTypeRawStream ), nil
64+ },
65+ waitFunc : func (_ string ) (<- chan container.WaitResponse , <- chan error ) {
66+ responseChan := make (chan container.WaitResponse , 1 )
67+ errChan := make (chan error )
68+
69+ responseChan <- container.WaitResponse {
70+ StatusCode : 33 ,
71+ }
72+ return responseChan , errChan
73+ },
74+ // use new (non-legacy) wait API
75+ // see: 38591f20d07795aaef45d400df89ca12f29c603b
76+ Version : "1.30" ,
77+ }, func (fc * test.FakeCli ) {
78+ fc .SetOut (streams .NewOut (tty ))
79+ fc .SetIn (streams .NewIn (tty ))
80+ })
81+
82+ cmd := NewRunCommand (fakeCLI )
83+ cmd .SetArgs ([]string {"-it" , "busybox" })
84+ cmd .SilenceUsage = true
85+ cmdErrC := make (chan error , 1 )
86+ go func () {
87+ cmdErrC <- cmd .Execute ()
88+ }()
89+
90+ // run command should attempt to attach to the container
91+ select {
92+ case <- time .After (5 * time .Second ):
93+ t .Fatal ("containerAttachFunc was not called before the 5 second timeout" )
94+ case <- attachCh :
95+ }
96+
97+ // end stream from "container" so that we'll detach
98+ conn .Close ()
99+
100+ select {
101+ case cmdErr := <- cmdErrC :
102+ assert .Equal (t , cmdErr , cli.StatusError {
103+ StatusCode : 33 ,
104+ })
105+ case <- time .After (2 * time .Second ):
106+ t .Fatal ("cmd did not return within timeout" )
107+ }
108+ }
44109
110+ func TestRunAttachTermination (t * testing.T ) {
111+ p , tty , err := pty .Open ()
112+ assert .NilError (t , err )
45113 defer func () {
46114 _ = tty .Close ()
47115 _ = p .Close ()
48116 }()
49117
118+ var conn net.Conn
50119 killCh := make (chan struct {})
51120 attachCh := make (chan struct {})
52121 fakeCLI := test .NewFakeCli (& fakeClient {
@@ -61,42 +130,62 @@ func TestRunAttachTermination(t *testing.T) {
61130 },
62131 containerAttachFunc : func (ctx context.Context , containerID string , options container.AttachOptions ) (types.HijackedResponse , error ) {
63132 server , client := net .Pipe ()
133+ conn = server
64134 t .Cleanup (func () {
65135 _ = server .Close ()
66136 })
67137 attachCh <- struct {}{}
68138 return types .NewHijackedResponse (client , types .MediaTypeRawStream ), nil
69139 },
70- Version : "1.36" ,
140+ waitFunc : func (_ string ) (<- chan container.WaitResponse , <- chan error ) {
141+ responseChan := make (chan container.WaitResponse , 1 )
142+ errChan := make (chan error )
143+
144+ responseChan <- container.WaitResponse {
145+ StatusCode : 130 ,
146+ }
147+ return responseChan , errChan
148+ },
149+ // use new (non-legacy) wait API
150+ // see: 38591f20d07795aaef45d400df89ca12f29c603b
151+ Version : "1.30" ,
71152 }, func (fc * test.FakeCli ) {
72153 fc .SetOut (streams .NewOut (tty ))
73154 fc .SetIn (streams .NewIn (tty ))
74155 })
75- ctx , cancel := signal .NotifyContext (context .Background (), syscall .SIGTERM )
76- defer cancel ()
77-
78- assert .Equal (t , fakeCLI .In ().IsTerminal (), true )
79- assert .Equal (t , fakeCLI .Out ().IsTerminal (), true )
80156
81157 cmd := NewRunCommand (fakeCLI )
82158 cmd .SetArgs ([]string {"-it" , "busybox" })
83159 cmd .SilenceUsage = true
160+ cmdErrC := make (chan error , 1 )
84161 go func () {
85- assert . ErrorIs ( t , cmd .ExecuteContext ( ctx ), context . Canceled )
162+ cmdErrC <- cmd .Execute ( )
86163 }()
87164
165+ // run command should attempt to attach to the container
88166 select {
89167 case <- time .After (5 * time .Second ):
90- t .Fatal ("containerAttachFunc was not called before the 5 second timeout" )
168+ t .Fatal ("containerAttachFunc was not called before the timeout" )
91169 case <- attachCh :
92170 }
93171
94- assert .NilError (t , syscall .Kill (syscall .Getpid (), syscall .SIGTERM ))
172+ assert .NilError (t , syscall .Kill (syscall .Getpid (), syscall .SIGINT ))
173+ // end stream from "container" so that we'll detach
174+ conn .Close ()
175+
95176 select {
96- case <- time .After (5 * time .Second ):
97- cancel ()
98- t .Fatal ("containerKillFunc was not called before the 5 second timeout" )
99177 case <- killCh :
178+ case <- time .After (5 * time .Second ):
179+ t .Fatal ("containerKillFunc was not called before the timeout" )
180+ }
181+
182+ select {
183+ case cmdErr := <- cmdErrC :
184+ assert .Equal (t , cmdErr , cli.StatusError {
185+ StatusCode : 130 ,
186+ })
187+ case <- time .After (2 * time .Second ):
188+ t .Fatal ("cmd did not return before the timeout" )
100189 }
101190}
102191
0 commit comments