1
2
3 package main
4
5 import (
6 "context"
7 "testing"
8 "time"
9
10 containerd_v1_types "github.com/containerd/containerd/api/types/task"
11 "github.com/containerd/containerd/errdefs"
12 "github.com/containerd/containerd/runtime/v2/task"
13 "github.com/pkg/errors"
14 )
15
16 func verifyWcowPodSandboxExecStatus(t *testing.T, wasStarted bool, es containerd_v1_types.Status, status *task.StateResponse) {
17 t.Helper()
18 if status.ID != t.Name() {
19 t.Fatalf("expected id: '%s' got: '%s'", t.Name(), status.ID)
20 }
21 if status.ExecID != t.Name() {
22 t.Fatalf("expected execid: '%s' got: '%s'", t.Name(), status.ExecID)
23 }
24 if status.Bundle != t.Name() {
25 t.Fatalf("expected bundle: '%s' got: '%s'", t.Name(), status.Bundle)
26 }
27 var expectedPid uint32
28 if wasStarted && es != containerd_v1_types.StatusCreated {
29 expectedPid = 1
30 }
31 if status.Pid != expectedPid {
32 t.Fatalf("expected pid: '%d' got: '%d'", expectedPid, status.Pid)
33 }
34 if status.Status != es {
35 t.Fatalf("expected status: '%s' got: '%s'", es, status.Status)
36 }
37 if status.Stdin != "" {
38 t.Fatalf("expected stdin: '' got: '%s'", status.Stdin)
39 }
40 if status.Stdout != "" {
41 t.Fatalf("expected stdout: '' got: '%s'", status.Stdout)
42 }
43 if status.Stderr != "" {
44 t.Fatalf("expected stderr: '' got: '%s'", status.Stderr)
45 }
46 if status.Terminal {
47 t.Fatalf("expected terminal: 'false' got: '%v'", status.Terminal)
48 }
49 var expectedExitStatus uint32
50 switch es {
51 case containerd_v1_types.StatusCreated, containerd_v1_types.StatusRunning:
52 expectedExitStatus = 255
53 case containerd_v1_types.StatusStopped:
54 if !wasStarted {
55 expectedExitStatus = 1
56 } else {
57 expectedExitStatus = 0
58 }
59 }
60 if status.ExitStatus != expectedExitStatus {
61 t.Fatalf("expected exitstatus: '%d' got: '%d'", expectedExitStatus, status.ExitStatus)
62 }
63 if es != containerd_v1_types.StatusStopped {
64 if !status.ExitedAt.IsZero() {
65 t.Fatalf("expected exitedat: '%v' got: '%v'", time.Time{}, status.ExitedAt)
66 }
67 } else {
68 if status.ExitedAt.IsZero() {
69 t.Fatalf("expected exitedat: > '%v' got: '%v'", time.Time{}, status.ExitedAt)
70 }
71 }
72 }
73
74 func Test_newWcowPodSandboxExec(t *testing.T) {
75 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
76
77 verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusCreated, wpse.Status())
78 }
79
80 func Test_newWcowPodSandboxExec_ID(t *testing.T) {
81 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
82
83 if wpse.ID() != t.Name() {
84 t.Fatalf("expected ID: '%s' got: '%s", t.Name(), wpse.ID())
85 }
86 }
87
88 func Test_newWcowPodSandboxExec_Pid(t *testing.T) {
89 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
90
91 if wpse.Pid() != 0 {
92 t.Fatalf("expected created pid: '0' got: '%d", wpse.Pid())
93 }
94
95
96 err := wpse.Start(context.TODO())
97 if err != nil {
98 t.Fatalf("should not have failed to start got: %v", err)
99 }
100
101 if wpse.Pid() != 1 {
102 t.Fatalf("expected running pid: '1' got: '%d", wpse.Pid())
103 }
104
105
106 err = wpse.Kill(context.TODO(), 0x0)
107 if err != nil {
108 t.Fatalf("should not have failed to stop got: %v", err)
109 }
110
111 if wpse.Pid() != 1 {
112 t.Fatalf("expected stopped pid: '1' got: '%d", wpse.Pid())
113 }
114 }
115
116 func Test_newWcowPodSandboxExec_State(t *testing.T) {
117 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
118
119 if wpse.State() != shimExecStateCreated {
120 t.Fatalf("expected state: '%s' got: '%s", shimExecStateCreated, wpse.State())
121 }
122
123
124 err := wpse.Start(context.TODO())
125 if err != nil {
126 t.Fatalf("should not have failed to start got: %v", err)
127 }
128
129 if wpse.State() != shimExecStateRunning {
130 t.Fatalf("expected state: '%s' got: '%s", shimExecStateRunning, wpse.State())
131 }
132
133
134 err = wpse.Kill(context.TODO(), 0x0)
135 if err != nil {
136 t.Fatalf("should not have failed to stop got: %v", err)
137 }
138
139 if wpse.State() != shimExecStateExited {
140 t.Fatalf("expected state: '%s' got: '%s", shimExecStateExited, wpse.State())
141 }
142 }
143
144 func Test_newWcowPodSandboxExec_Status(t *testing.T) {
145 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
146
147 verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusCreated, wpse.Status())
148
149
150 err := wpse.Start(context.TODO())
151 if err != nil {
152 t.Fatalf("should not have failed to start got: %v", err)
153 }
154
155 verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusRunning, wpse.Status())
156
157
158 err = wpse.Kill(context.TODO(), 0x0)
159 if err != nil {
160 t.Fatalf("should not have failed to stop got: %v", err)
161 }
162
163 verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusStopped, wpse.Status())
164 }
165
166 func Test_newWcowPodSandboxExec_Start(t *testing.T) {
167 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
168
169
170 err := wpse.Start(context.TODO())
171 if err != nil {
172 t.Fatalf("should not have failed to start got: %v", err)
173 }
174 if wpse.State() != shimExecStateRunning {
175 t.Fatalf("should of transitioned to running state")
176 }
177
178
179 err = wpse.Start(context.TODO())
180 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
181 }
182
183 func Test_newWcowPodSandboxExec_Kill_Created(t *testing.T) {
184 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
185
186
187 err := wpse.Kill(context.TODO(), 0x0)
188 if err != nil {
189 t.Fatalf("should not have failed to kill got: %v", err)
190 }
191 if wpse.State() != shimExecStateExited {
192 t.Fatalf("should of transitioned to exited state")
193 }
194
195
196 err = wpse.Kill(context.TODO(), 0x0)
197 if errors.Cause(err) != errdefs.ErrNotFound {
198 t.Fatalf("Kill should fail with `ErrNotFound` in the exited state got: %v", err)
199 }
200 }
201
202 func Test_newWcowPodSandboxExec_Kill_Started(t *testing.T) {
203 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
204
205
206 err := wpse.Start(context.TODO())
207 if err != nil {
208 t.Fatalf("should not have failed to start got: %v", err)
209 }
210
211
212 err = wpse.Kill(context.TODO(), 0x0)
213 if err != nil {
214 t.Fatalf("should not have failed to kill got: %v", err)
215 }
216 if wpse.State() != shimExecStateExited {
217 t.Fatalf("should of transitioned to exited state")
218 }
219
220
221 err = wpse.Kill(context.TODO(), 0x0)
222 if errors.Cause(err) != errdefs.ErrNotFound {
223 t.Fatalf("Kill should fail with `ErrNotFound` in the exited state got: %v", err)
224 }
225 }
226
227 func Test_newWcowPodSandboxExec_ResizePty(t *testing.T) {
228 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
229
230
231 err := wpse.ResizePty(context.TODO(), 10, 10)
232 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
233
234
235 err = wpse.Start(context.TODO())
236 if err != nil {
237 t.Fatalf("should not have failed to start got: %v", err)
238 }
239
240 err = wpse.ResizePty(context.TODO(), 10, 10)
241 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
242
243
244 err = wpse.Kill(context.TODO(), 0x0)
245 if err != nil {
246 t.Fatalf("should not have failed to stop got: %v", err)
247 }
248
249 err = wpse.ResizePty(context.TODO(), 10, 10)
250 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
251 }
252
253 func Test_newWcowPodSandboxExec_CloseIO(t *testing.T) {
254 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
255
256
257 err := wpse.CloseIO(context.TODO(), true)
258 if err != nil {
259 t.Fatalf("should not have failed CloseIO in created state got: %v", err)
260 }
261
262
263 err = wpse.Start(context.TODO())
264 if err != nil {
265 t.Fatalf("should not have failed to start got: %v", err)
266 }
267
268 err = wpse.CloseIO(context.TODO(), true)
269 if err != nil {
270 t.Fatalf("should not have failed CloseIO in running state got: %v", err)
271 }
272
273
274 err = wpse.Kill(context.TODO(), 0x0)
275 if err != nil {
276 t.Fatalf("should not have failed to stop got: %v", err)
277 }
278
279 err = wpse.CloseIO(context.TODO(), true)
280 if err != nil {
281 t.Fatalf("should not have failed CloseIO in exited state got: %v", err)
282 }
283 }
284
285 func Test_newWcowPodSandboxExec_Wait_Created(t *testing.T) {
286 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
287
288 waitExit := make(chan *task.StateResponse, 1)
289 defer close(waitExit)
290
291
292 go func() {
293 waitExit <- wpse.Wait()
294 }()
295
296 now := time.Now()
297 err := wpse.Kill(context.TODO(), 0x0)
298 if err != nil {
299 t.Fatalf("should not have failed to kill got: %v", err)
300 }
301
302 status := <-waitExit
303 verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusStopped, status)
304 if status.ExitedAt.Before(now) {
305 t.Fatal("exit should not have unblocked previous to kill")
306 }
307
308
309 verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusStopped, wpse.Wait())
310 }
311
312 func Test_newWcowPodSandboxExec_Wait_Started(t *testing.T) {
313 wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
314
315 waitExit := make(chan *task.StateResponse, 1)
316 defer close(waitExit)
317
318
319 go func() {
320 waitExit <- wpse.Wait()
321 }()
322
323 err := wpse.Start(context.TODO())
324 if err != nil {
325 t.Fatalf("should not have failed to start got: %v", err)
326 }
327
328 now := time.Now()
329 err = wpse.Kill(context.TODO(), 0x0)
330 if err != nil {
331 t.Fatalf("should not have failed to kill got: %v", err)
332 }
333
334 status := <-waitExit
335 verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusStopped, status)
336 if status.ExitedAt.Before(now) {
337 t.Fatal("exit should not have unblocked previous to kill")
338 }
339
340
341 verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusStopped, wpse.Wait())
342 }
343
View as plain text