1
2
3 package main
4
5 import (
6 "context"
7 "fmt"
8 "math/rand"
9 "strconv"
10 "sync"
11 "testing"
12
13 "github.com/containerd/containerd/errdefs"
14 "github.com/containerd/containerd/runtime/v2/task"
15 specs "github.com/opencontainers/runtime-spec/specs-go"
16 )
17
18 var _ = (shimPod)(&testShimPod{})
19
20 type testShimPod struct {
21 id string
22
23 tasks sync.Map
24 }
25
26 func (tsp *testShimPod) ID() string {
27 return tsp.id
28 }
29
30 func (tsp *testShimPod) CreateTask(ctx context.Context, req *task.CreateTaskRequest, s *specs.Spec) (shimTask, error) {
31 return nil, errdefs.ErrNotImplemented
32 }
33
34 func (tsp *testShimPod) GetTask(tid string) (shimTask, error) {
35 v, loaded := tsp.tasks.Load(tid)
36 if loaded {
37 return v.(shimTask), nil
38 }
39 return nil, errdefs.ErrNotFound
40 }
41
42 func (tsp *testShimPod) ListTasks() (_ []shimTask, err error) {
43 var tasks []shimTask
44 tsp.tasks.Range(func(key, value interface{}) bool {
45 wt, ok := value.(shimTask)
46 if !ok {
47 err = fmt.Errorf("failed to load tasks %s", key)
48 return false
49 }
50 tasks = append(tasks, wt)
51 return true
52 })
53 if err != nil {
54 return nil, err
55 }
56 return tasks, nil
57 }
58
59 func (tsp *testShimPod) KillTask(ctx context.Context, tid, eid string, signal uint32, all bool) error {
60 s, err := tsp.GetTask(tid)
61 if err != nil {
62 return err
63 }
64 return s.KillExec(ctx, eid, signal, all)
65 }
66
67 func (tsp *testShimPod) DeleteTask(ctx context.Context, tid string) error {
68 t, err := tsp.GetTask(tid)
69 if err != nil {
70 return err
71 }
72
73 e, err := t.GetExec("")
74 if err != nil {
75 return err
76 }
77 switch e.State() {
78 case shimExecStateRunning:
79 return errdefs.ErrFailedPrecondition
80 default:
81 }
82
83 if tid != tsp.ID() {
84 tsp.tasks.Delete(tid)
85 }
86 return nil
87 }
88
89
90
91 func setupTestPodWithFakes(t *testing.T) (*pod, *testShimTask) {
92 t.Helper()
93 st := &testShimTask{
94 id: t.Name(),
95 exec: newTestShimExec(t.Name(), t.Name(), 10),
96 execs: make(map[string]*testShimExec),
97 }
98
99 seid := strconv.Itoa(rand.Int())
100 st.execs[seid] = newTestShimExec(t.Name(), seid, int(rand.Int31()))
101 p := &pod{
102 id: t.Name(),
103 sandboxTask: st,
104 }
105 return p, st
106 }
107
108 func setupTestTaskInPod(t *testing.T, p *pod) *testShimTask {
109 t.Helper()
110 tid := strconv.Itoa(rand.Int())
111 wt := &testShimTask{
112 id: tid,
113 exec: newTestShimExec(tid, tid, int(rand.Int31())),
114 }
115 p.workloadTasks.Store(wt.id, wt)
116 return wt
117 }
118
119 func Test_pod_ID(t *testing.T) {
120 p := pod{id: t.Name()}
121 id := p.ID()
122 if id != t.Name() {
123 t.Fatalf("pod should of returned ID: %s, got: %s", t.Name(), id)
124 }
125 }
126
127 func Test_pod_GetTask_SandboxID(t *testing.T) {
128 p, st := setupTestPodWithFakes(t)
129 t1, err := p.GetTask(t.Name())
130 if err != nil {
131 t.Fatalf("should not have failed, got: %v", err)
132 }
133 if t1 != st {
134 t.Fatal("should have returned sandbox task")
135 }
136 }
137
138 func Test_pod_GetTask_WorkloadID_NotCreated_Error(t *testing.T) {
139 p, _ := setupTestPodWithFakes(t)
140 t1, err := p.GetTask("thisshouldnotmatch")
141
142 verifyExpectedError(t, t1, err, errdefs.ErrNotFound)
143 }
144
145 func Test_pod_GetTask_WorkloadID_Created_Success(t *testing.T) {
146 p, _ := setupTestPodWithFakes(t)
147 t2 := setupTestTaskInPod(t, p)
148
149 resp, err := p.GetTask(t2.ID())
150 if err != nil {
151 t.Fatalf("should not have failed, got: %v", err)
152 }
153 if resp != t2 {
154 t.Fatal("should have returned workload task")
155 }
156 }
157
158
159
160 func Test_pod_KillTask_UnknownTaskID_Error(t *testing.T) {
161 p, _ := setupTestPodWithFakes(t)
162 err := p.KillTask(context.TODO(), "thisshouldnotmatch", "", 0xf, false)
163
164 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
165 }
166
167 func Test_pod_KillTask_SandboxID_UnknownExecID_Error(t *testing.T) {
168 p, _ := setupTestPodWithFakes(t)
169 err := p.KillTask(context.TODO(), t.Name(), "thisshouldnotmatch", 0xf, false)
170
171 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
172 }
173
174 func Test_pod_KillTask_SandboxID_InitExecID_Success(t *testing.T) {
175 p, _ := setupTestPodWithFakes(t)
176 err := p.KillTask(context.TODO(), t.Name(), "", 0xf, false)
177 if err != nil {
178 t.Fatalf("should not have failed, got: %v", err)
179 }
180 }
181
182 func Test_pod_KillTask_SandboxID_InitExecID_All_Success(t *testing.T) {
183 p, _ := setupTestPodWithFakes(t)
184
185 setupTestTaskInPod(t, p)
186 setupTestTaskInPod(t, p)
187 err := p.KillTask(context.TODO(), t.Name(), "", 0xf, true)
188 if err != nil {
189 t.Fatalf("should not have failed, got: %v", err)
190 }
191 }
192
193 func Test_pod_KillTask_SandboxID_2ndExecID_Success(t *testing.T) {
194 p, t1 := setupTestPodWithFakes(t)
195 for k := range t1.execs {
196 err := p.KillTask(context.TODO(), t.Name(), k, 0xf, false)
197 if err != nil {
198 t.Fatalf("should not have failed, got: %v", err)
199 }
200 }
201 }
202
203 func Test_pod_KillTask_SandboxID_2ndExecID_All_Error(t *testing.T) {
204 p, t1 := setupTestPodWithFakes(t)
205 for k := range t1.execs {
206 err := p.KillTask(context.TODO(), t.Name(), k, 0xf, true)
207
208 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
209 }
210 }
211
212 func Test_pod_KillTask_WorkloadID_InitExecID_Success(t *testing.T) {
213 p, _ := setupTestPodWithFakes(t)
214 t1 := setupTestTaskInPod(t, p)
215
216 err := p.KillTask(context.TODO(), t1.ID(), "", 0xf, false)
217 if err != nil {
218 t.Fatalf("should not have failed, got: %v", err)
219 }
220 }
221
222 func Test_pod_KillTask_WorkloadID_InitExecID_All_Success(t *testing.T) {
223 p, _ := setupTestPodWithFakes(t)
224 t1 := setupTestTaskInPod(t, p)
225
226 err := p.KillTask(context.TODO(), t1.ID(), "", 0xf, true)
227 if err != nil {
228 t.Fatalf("should not have failed, got: %v", err)
229 }
230 }
231
232 func Test_pod_KillTask_WorkloadID_2ndExecID_Success(t *testing.T) {
233 p, _ := setupTestPodWithFakes(t)
234 t1 := setupTestTaskInPod(t, p)
235
236 for k := range t1.execs {
237 err := p.KillTask(context.TODO(), t1.ID(), k, 0xf, false)
238 if err != nil {
239 t.Fatalf("should not have failed, got: %v", err)
240 }
241 }
242 }
243
244 func Test_pod_KillTask_WorkloadID_2ndExecID_All_Error(t *testing.T) {
245 p, _ := setupTestPodWithFakes(t)
246 t1 := setupTestTaskInPod(t, p)
247
248 for k := range t1.execs {
249 err := p.KillTask(context.TODO(), t1.ID(), k, 0xf, true)
250
251 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
252 }
253 }
254
255
256
257 func Test_pod_DeleteTask_SandboxID(t *testing.T) {
258 p, st := setupTestPodWithFakes(t)
259
260 err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
261 if err != nil {
262 t.Fatalf("should not have failed, got: %v", err)
263 }
264
265 err = p.DeleteTask(context.Background(), st.ID())
266 if err != nil {
267 t.Fatalf("should not have failed, got: %v", err)
268 }
269
270
271 _, err = p.GetTask(t.Name())
272 if err != nil {
273 t.Fatalf("should not have failed, got: %v", err)
274 }
275 }
276
277 func Test_pod_DeleteTask_SandboxID_Running(t *testing.T) {
278 p, st := setupTestPodWithFakes(t)
279
280
281 e, err := st.GetExec("")
282 if err != nil {
283 t.Fatalf("should not have failed, got: %v", err)
284 }
285 err = e.Start(context.Background())
286 if err != nil {
287 t.Fatalf("should not have failed, got: %v", err)
288 }
289
290 err = p.DeleteTask(context.Background(), st.ID())
291 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
292 }
293
294 func Test_pod_DeleteTask_SandboxID_Repeated(t *testing.T) {
295 p, st := setupTestPodWithFakes(t)
296
297 err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
298 if err != nil {
299 t.Fatalf("should not have failed, got: %v", err)
300 }
301
302 err = p.DeleteTask(context.Background(), st.ID())
303 if err != nil {
304 t.Fatalf("should not have failed, got: %v", err)
305 }
306
307 err = p.DeleteTask(context.Background(), st.ID())
308 if err != nil {
309 t.Fatalf("should not have failed, got: %v", err)
310 }
311 }
312
313 func Test_pod_DeleteTask_TaskID(t *testing.T) {
314 p, _ := setupTestPodWithFakes(t)
315 st := setupTestTaskInPod(t, p)
316
317 err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
318 if err != nil {
319 t.Fatalf("should not have failed, got: %v", err)
320 }
321
322 err = p.DeleteTask(context.Background(), st.ID())
323 if err != nil {
324 t.Fatalf("should not have failed, got: %v", err)
325 }
326
327 _, err = p.GetTask(st.ID())
328 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
329 }
330
331 func Test_pod_DeleteTask_TaskID_Running(t *testing.T) {
332 p, _ := setupTestPodWithFakes(t)
333 st := setupTestTaskInPod(t, p)
334
335
336 e, err := st.GetExec("")
337 if err != nil {
338 t.Fatalf("should not have failed, got: %v", err)
339 }
340 err = e.Start(context.Background())
341 if err != nil {
342 t.Fatalf("should not have failed, got: %v", err)
343 }
344
345 err = p.DeleteTask(context.Background(), st.ID())
346 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
347
348
349 _, err = p.GetTask(t.Name())
350 if err != nil {
351 t.Fatalf("should not have failed, got: %v", err)
352 }
353
354 stp, err := p.GetTask(st.ID())
355 if err != nil {
356 t.Fatalf("should not have failed, got: %v", err)
357 }
358
359 if stp != st {
360 t.Fatalf("task should not have changed: %v != %v", st, stp)
361 }
362 }
363
364 func Test_pod_DeleteTask_TaskID_Repeated(t *testing.T) {
365 p, _ := setupTestPodWithFakes(t)
366 st := setupTestTaskInPod(t, p)
367
368 err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
369 if err != nil {
370 t.Fatalf("should not have failed, got: %v", err)
371 }
372
373 err = p.DeleteTask(context.Background(), st.ID())
374 if err != nil {
375 t.Fatalf("should not have failed, got: %v", err)
376 }
377
378 err = p.DeleteTask(context.Background(), st.ID())
379 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
380 }
381
382 func Test_pod_DeleteTask_TaskID_Not_Created(t *testing.T) {
383 p, _ := setupTestPodWithFakes(t)
384
385 setupTestTaskInPod(t, p)
386 setupTestTaskInPod(t, p)
387
388 err := p.KillTask(context.Background(), strconv.Itoa(rand.Int()), "", 0xf, true)
389 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
390 }
391
View as plain text