5
5
"errors"
6
6
"io"
7
7
"net"
8
- "os/signal"
9
8
"syscall"
10
9
"testing"
11
10
"time"
@@ -38,15 +37,85 @@ func TestRunLabel(t *testing.T) {
38
37
assert .NilError (t , cmd .Execute ())
39
38
}
40
39
41
- func TestRunAttachTermination (t * testing.T ) {
40
+ func TestRunAttach (t * testing.T ) {
42
41
p , tty , err := pty .Open ()
43
42
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
+ }
44
109
110
+ func TestRunAttachTermination (t * testing.T ) {
111
+ p , tty , err := pty .Open ()
112
+ assert .NilError (t , err )
45
113
defer func () {
46
114
_ = tty .Close ()
47
115
_ = p .Close ()
48
116
}()
49
117
118
+ var conn net.Conn
50
119
killCh := make (chan struct {})
51
120
attachCh := make (chan struct {})
52
121
fakeCLI := test .NewFakeCli (& fakeClient {
@@ -61,42 +130,62 @@ func TestRunAttachTermination(t *testing.T) {
61
130
},
62
131
containerAttachFunc : func (ctx context.Context , containerID string , options container.AttachOptions ) (types.HijackedResponse , error ) {
63
132
server , client := net .Pipe ()
133
+ conn = server
64
134
t .Cleanup (func () {
65
135
_ = server .Close ()
66
136
})
67
137
attachCh <- struct {}{}
68
138
return types .NewHijackedResponse (client , types .MediaTypeRawStream ), nil
69
139
},
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" ,
71
152
}, func (fc * test.FakeCli ) {
72
153
fc .SetOut (streams .NewOut (tty ))
73
154
fc .SetIn (streams .NewIn (tty ))
74
155
})
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 )
80
156
81
157
cmd := NewRunCommand (fakeCLI )
82
158
cmd .SetArgs ([]string {"-it" , "busybox" })
83
159
cmd .SilenceUsage = true
160
+ cmdErrC := make (chan error , 1 )
84
161
go func () {
85
- assert . ErrorIs ( t , cmd .ExecuteContext ( ctx ), context . Canceled )
162
+ cmdErrC <- cmd .Execute ( )
86
163
}()
87
164
165
+ // run command should attempt to attach to the container
88
166
select {
89
167
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" )
91
169
case <- attachCh :
92
170
}
93
171
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
+
95
176
select {
96
- case <- time .After (5 * time .Second ):
97
- cancel ()
98
- t .Fatal ("containerKillFunc was not called before the 5 second timeout" )
99
177
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" )
100
189
}
101
190
}
102
191
0 commit comments