1
2
3 package main
4
5 import (
6 "context"
7 "fmt"
8 "math/rand"
9 "strconv"
10 "testing"
11 "time"
12
13 "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
14 "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
15 "github.com/containerd/containerd/errdefs"
16 "github.com/containerd/containerd/runtime/v2/task"
17 "github.com/containerd/typeurl"
18 specs "github.com/opencontainers/runtime-spec/specs-go"
19 )
20
21 func setupPodServiceWithFakes(t *testing.T) (*service, *testShimTask, *testShimTask, *testShimExec) {
22 t.Helper()
23 tid := strconv.Itoa(rand.Int())
24
25 s, err := NewService(WithTID(tid), WithIsSandbox(true))
26 if err != nil {
27 t.Fatalf("could not create service: %v", err)
28 }
29
30
31 t.Cleanup(func() {
32 if _, err := s.shutdownInternal(context.Background(), &task.ShutdownRequest{
33 ID: s.tid,
34 Now: true,
35 }); err != nil {
36 t.Fatalf("could not shutdown service: %v", err)
37 }
38 })
39
40 pod := &testShimPod{id: tid}
41
42
43 task := &testShimTask{
44 id: tid,
45 exec: newTestShimExec(tid, tid, 10),
46 execs: make(map[string]*testShimExec),
47 }
48
49
50 secondTaskID := strconv.Itoa(rand.Int())
51 secondTaskSecondExecID := strconv.Itoa(rand.Int())
52 task2 := &testShimTask{
53 id: secondTaskID,
54 exec: newTestShimExec(secondTaskID, secondTaskID, 101),
55 execs: make(map[string]*testShimExec),
56 }
57 task2exec2 := newTestShimExec(secondTaskID, secondTaskSecondExecID, 201)
58 task2.execs[secondTaskSecondExecID] = task2exec2
59
60
61 pod.tasks.Store(task.id, task)
62 pod.tasks.Store(task2.id, task2)
63 s.taskOrPod.Store(pod)
64 return s, task, task2, task2exec2
65 }
66
67 func Test_PodShim_getPod_NotCreated_Error(t *testing.T) {
68 s := service{
69 tid: t.Name(),
70 isSandbox: true,
71 }
72
73 p, err := s.getPod()
74
75 verifyExpectedError(t, p, err, errdefs.ErrFailedPrecondition)
76 }
77
78 func Test_PodShim_getPod_Created_Success(t *testing.T) {
79 s, _, _, _ := setupPodServiceWithFakes(t)
80
81 p, err := s.getPod()
82 if err != nil {
83 t.Fatalf("should have not failed with error, got: %v", err)
84 }
85 if p == nil {
86 t.Fatal("should have returned a valid pod")
87 }
88 }
89
90 func Test_PodShim_getTask_NotCreated_Error(t *testing.T) {
91 s := service{
92 tid: t.Name(),
93 isSandbox: true,
94 }
95
96 st, err := s.getTask(t.Name())
97
98 verifyExpectedError(t, st, err, errdefs.ErrNotFound)
99 }
100
101 func Test_PodShim_getTask_Created_DifferentID_Error(t *testing.T) {
102 s, _, _, _ := setupPodServiceWithFakes(t)
103
104 st, err := s.getTask("thisidwontmatch")
105
106 verifyExpectedError(t, st, err, errdefs.ErrNotFound)
107 }
108
109 func Test_PodShim_getTask_Created_InitID_Success(t *testing.T) {
110 s, t1, _, _ := setupPodServiceWithFakes(t)
111
112 st, err := s.getTask(t1.ID())
113 if err != nil {
114 t.Fatalf("should have not failed with error, got: %v", err)
115 }
116 if st != t1 {
117 t.Fatal("should have returned a valid task")
118 }
119 }
120
121 func Test_PodShim_getTask_Created_2ndID_Success(t *testing.T) {
122 s, _, t2, _ := setupPodServiceWithFakes(t)
123
124 st, err := s.getTask(t2.ID())
125 if err != nil {
126 t.Fatalf("should have not failed with error, got: %v", err)
127 }
128 if st != t2 {
129 t.Fatal("should have returned a valid task")
130 }
131 }
132
133 func Test_PodShim_stateInternal_NoTask_Error(t *testing.T) {
134 s := service{
135 tid: t.Name(),
136 isSandbox: true,
137 }
138
139 resp, err := s.stateInternal(context.TODO(), &task.StateRequest{ID: t.Name()})
140
141 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
142 }
143
144 func Test_PodShim_stateInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
145 s, t1, _, _ := setupPodServiceWithFakes(t)
146
147 resp, err := s.stateInternal(context.TODO(), &task.StateRequest{
148 ID: t1.ID(),
149 ExecID: "thisshouldnotmatch",
150 })
151
152 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
153 }
154
155 func Test_PodShim_stateInternal_InitTaskID_InitExecID_Success(t *testing.T) {
156 s, t1, _, _ := setupPodServiceWithFakes(t)
157
158 resp, err := s.stateInternal(context.TODO(), &task.StateRequest{
159 ID: t1.ID(),
160 ExecID: "",
161 })
162 if err != nil {
163 t.Fatalf("should not have failed with error got: %v", err)
164 }
165 if resp == nil {
166 t.Fatal("should have returned StateResponse")
167 }
168 if resp.ID != t1.ID() {
169 t.Fatalf("StateResponse.ID expected '%s' got '%s'", t1.ID(), resp.ID)
170 }
171 if resp.ExecID != t1.ID() {
172 t.Fatalf("StateResponse.ExecID expected '%s' got '%s'", t1.ID(), resp.ExecID)
173 }
174 if resp.Pid != uint32(t1.exec.pid) {
175 t.Fatalf("should have returned init pid, got: %v", resp.Pid)
176 }
177 }
178
179 func Test_PodShim_stateInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
180 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
181
182 resp, err := s.stateInternal(context.TODO(), &task.StateRequest{
183 ID: t2.ID(),
184 ExecID: t2e2.ID(),
185 })
186 if err != nil {
187 t.Fatalf("should not have failed with error got: %v", err)
188 }
189 if resp == nil {
190 t.Fatal("should have returned StateResponse")
191 }
192 if resp.ID != t2.ID() {
193 t.Fatalf("StateResponse.ID expected '%s' got '%s'", t2.ID(), resp.ID)
194 }
195 if resp.ExecID != t2e2.ID() {
196 t.Fatalf("StateResponse.ExecID expected '%s' got '%s'", t2e2.ID(), resp.ExecID)
197 }
198 if resp.Pid != uint32(t2.execs[t2e2.ID()].pid) {
199 t.Fatalf("should have returned 2nd exec pid, got: %v", resp.Pid)
200 }
201 }
202
203
204
205 func Test_PodShim_startInternal_NoTask_Error(t *testing.T) {
206 s := service{
207 tid: t.Name(),
208 isSandbox: true,
209 }
210
211 resp, err := s.startInternal(context.TODO(), &task.StartRequest{ID: t.Name()})
212
213 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
214 }
215
216 func Test_PodShim_startInternal_ValidTask_DifferentExecID_Error(t *testing.T) {
217 s, t1, _, _ := setupPodServiceWithFakes(t)
218
219 resp, err := s.startInternal(context.TODO(), &task.StartRequest{
220 ID: t1.ID(),
221 ExecID: "thisshouldnotmatch",
222 })
223
224 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
225 }
226
227 func Test_PodShim_startInternal_InitTaskID_InitExecID_Success(t *testing.T) {
228 s, t1, _, _ := setupPodServiceWithFakes(t)
229
230 resp, err := s.startInternal(context.TODO(), &task.StartRequest{
231 ID: t1.ID(),
232 ExecID: "",
233 })
234 if err != nil {
235 t.Fatalf("should not have failed with error got: %v", err)
236 }
237 if resp == nil {
238 t.Fatal("should have returned StartResponse")
239 }
240 if resp.Pid != uint32(t1.exec.pid) {
241 t.Fatal("should have returned init pid")
242 }
243 }
244
245 func Test_PodShim_startInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
246 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
247
248 resp, err := s.startInternal(context.TODO(), &task.StartRequest{
249 ID: t2.ID(),
250 ExecID: t2e2.ID(),
251 })
252 if err != nil {
253 t.Fatalf("should not have failed with error got: %v", err)
254 }
255 if resp == nil {
256 t.Fatal("should have returned StartResponse")
257 }
258 if resp.Pid != uint32(t2.execs[t2e2.ID()].pid) {
259 t.Fatal("should have returned 2nd pid")
260 }
261 }
262
263 func Test_PodShim_deleteInternal_NoTask_Error(t *testing.T) {
264 s := service{
265 tid: t.Name(),
266 isSandbox: true,
267 }
268
269 resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{ID: t.Name()})
270
271 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
272 }
273
274 func Test_PodShim_deleteInternal_ValidTask_DifferentExecID_Error(t *testing.T) {
275 s, t1, _, _ := setupPodServiceWithFakes(t)
276
277 resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{
278 ID: t1.ID(),
279 ExecID: "thisshouldnotmatch",
280 })
281
282 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
283 }
284
285 func Test_PodShim_deleteInternal_InitTaskID_InitExecID_Success(t *testing.T) {
286 s, t1, _, _ := setupPodServiceWithFakes(t)
287
288 resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{
289 ID: t1.ID(),
290 ExecID: "",
291 })
292 if err != nil {
293 t.Fatalf("should not have failed with error got: %v", err)
294 }
295 if resp == nil {
296 t.Fatal("should have returned DeleteResponse")
297 }
298 if resp.Pid != uint32(t1.exec.pid) {
299 t.Fatal("should have returned init pid")
300 }
301 }
302
303 func Test_PodShim_deleteInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
304 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
305
306
307 t2t := t2.execs[t2e2.ID()]
308
309 resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{
310 ID: t2.ID(),
311 ExecID: t2e2.ID(),
312 })
313 if err != nil {
314 t.Fatalf("should not have failed with error got: %v", err)
315 }
316 if resp == nil {
317 t.Fatal("should have returned DeleteResponse")
318 }
319 if resp.Pid != uint32(t2t.pid) {
320 t.Fatal("should have returned 2nd pid")
321 }
322 if _, ok := t2.execs[t2e2.ID()]; ok {
323 t.Fatal("should have deleted the 2nd exec")
324 }
325 }
326
327 func Test_PodShim_pidsInternal_NoTask_Error(t *testing.T) {
328 s := service{
329 tid: t.Name(),
330 isSandbox: true,
331 }
332
333 resp, err := s.pidsInternal(context.TODO(), &task.PidsRequest{ID: t.Name()})
334
335 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
336 }
337
338 func Test_PodShim_pidsInternal_InitTaskID_Success(t *testing.T) {
339 s, t1, _, _ := setupPodServiceWithFakes(t)
340
341 resp, err := s.pidsInternal(context.TODO(), &task.PidsRequest{ID: t1.ID()})
342 if err != nil {
343 t.Fatalf("should not have failed with error got: %v", err)
344 }
345 if resp == nil {
346 t.Fatal("should have returned PidsResponse")
347 }
348 if len(resp.Processes) != 1 {
349 t.Fatalf("should have returned len(processes) == 1, got: %v", len(resp.Processes))
350 }
351 if resp.Processes[0].Pid != uint32(t1.exec.pid) {
352 t.Fatal("should have returned init pid")
353 }
354 if resp.Processes[0].Info == nil {
355 t.Fatal("should have returned init pid info")
356 }
357 u, err := typeurl.UnmarshalAny(resp.Processes[0].Info)
358 if err != nil {
359 t.Fatalf("failed to unmarshal init pid info, err: %v", err)
360 }
361 pi := u.(*options.ProcessDetails)
362 if pi.ExecID != t1.ID() {
363 t.Fatalf("should have returned 2nd pid ExecID, got: %v", pi.ExecID)
364 }
365 }
366
367 func Test_PodShim_pidsInternal_2ndTaskID_Success(t *testing.T) {
368 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
369
370 resp, err := s.pidsInternal(context.TODO(), &task.PidsRequest{ID: t2.ID()})
371 if err != nil {
372 t.Fatalf("should not have failed with error got: %v", err)
373 }
374 if resp == nil {
375 t.Fatal("should have returned PidsResponse")
376 }
377 if len(resp.Processes) != 2 {
378 t.Fatalf("should have returned len(processes) == 2, got: %v", len(resp.Processes))
379 }
380 if resp.Processes[0].Pid != uint32(t2.exec.pid) {
381 t.Fatal("should have returned init pid")
382 }
383 if resp.Processes[0].Info == nil {
384 t.Fatal("should have returned init pid info")
385 }
386 if resp.Processes[1].Pid != uint32(t2.execs[t2e2.ID()].pid) {
387 t.Fatal("should have returned 2nd pid")
388 }
389 if resp.Processes[1].Info == nil {
390 t.Fatal("should have returned 2nd pid info")
391 }
392 u, err := typeurl.UnmarshalAny(resp.Processes[1].Info)
393 if err != nil {
394 t.Fatalf("failed to unmarshal 2nd pid info, err: %v", err)
395 }
396 pi := u.(*options.ProcessDetails)
397 if pi.ExecID != t2e2.ID() {
398 t.Fatalf("should have returned 2nd pid ExecID, got: %v", pi.ExecID)
399 }
400 }
401
402 func Test_PodShim_pauseInternal_Error(t *testing.T) {
403 s := service{
404 tid: t.Name(),
405 isSandbox: true,
406 }
407
408 resp, err := s.pauseInternal(context.TODO(), &task.PauseRequest{ID: t.Name()})
409
410 verifyExpectedError(t, resp, err, errdefs.ErrNotImplemented)
411 }
412
413 func Test_PodShim_resumeInternal_Error(t *testing.T) {
414 s := service{
415 tid: t.Name(),
416 isSandbox: true,
417 }
418
419 resp, err := s.resumeInternal(context.TODO(), &task.ResumeRequest{ID: t.Name()})
420
421 verifyExpectedError(t, resp, err, errdefs.ErrNotImplemented)
422 }
423
424 func Test_PodShim_checkpointInternal_Error(t *testing.T) {
425 s := service{
426 tid: t.Name(),
427 isSandbox: true,
428 }
429
430 resp, err := s.checkpointInternal(context.TODO(), &task.CheckpointTaskRequest{ID: t.Name()})
431
432 verifyExpectedError(t, resp, err, errdefs.ErrNotImplemented)
433 }
434
435 func Test_PodShim_killInternal_NoTask_Error(t *testing.T) {
436 s := service{
437 tid: t.Name(),
438 isSandbox: true,
439 }
440
441 resp, err := s.killInternal(context.TODO(), &task.KillRequest{ID: t.Name()})
442
443 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
444 }
445
446 func Test_PodShim_killInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
447 s, t1, _, _ := setupPodServiceWithFakes(t)
448
449 resp, err := s.killInternal(context.TODO(), &task.KillRequest{
450 ID: t1.ID(),
451 ExecID: "thisshouldnotmatch",
452 })
453
454 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
455 }
456
457 func Test_PodShim_killInternal_InitTaskID_InitExecID_Success(t *testing.T) {
458 s, t1, _, _ := setupPodServiceWithFakes(t)
459
460 resp, err := s.killInternal(context.TODO(), &task.KillRequest{
461 ID: t1.ID(),
462 ExecID: "",
463 })
464 if err != nil {
465 t.Fatalf("should not have failed with error got: %v", err)
466 }
467 if resp == nil {
468 t.Fatal("should have returned KillResponse")
469 }
470 }
471
472 func Test_PodShim_killInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
473 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
474
475 resp, err := s.killInternal(context.TODO(), &task.KillRequest{
476 ID: t2.ID(),
477 ExecID: t2e2.ID(),
478 })
479 if err != nil {
480 t.Fatalf("should not have failed with error got: %v", err)
481 }
482 if resp == nil {
483 t.Fatal("should have returned KillResponse")
484 }
485 }
486
487
488
489 func Test_PodShim_resizePtyInternal_NoTask_Error(t *testing.T) {
490 s := service{
491 tid: t.Name(),
492 isSandbox: true,
493 }
494
495 resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{ID: t.Name()})
496
497 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
498 }
499
500 func Test_PodShim_resizePtyInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
501 s, t1, _, _ := setupPodServiceWithFakes(t)
502
503 resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{
504 ID: t1.ID(),
505 ExecID: "thisshouldnotmatch",
506 })
507
508 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
509 }
510
511 func Test_PodShim_resizePtyInternal_InitTaskID_InitExecID_Success(t *testing.T) {
512 s, t1, _, _ := setupPodServiceWithFakes(t)
513
514 resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{
515 ID: t1.ID(),
516 ExecID: "",
517 })
518 if err != nil {
519 t.Fatalf("should not have failed with error got: %v", err)
520 }
521 if resp == nil {
522 t.Fatal("should have returned ResizePtyResponse")
523 }
524 }
525
526 func Test_PodShim_resizePtyInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
527 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
528
529 resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{
530 ID: t2.ID(),
531 ExecID: t2e2.ID(),
532 })
533 if err != nil {
534 t.Fatalf("should not have failed with error got: %v", err)
535 }
536 if resp == nil {
537 t.Fatal("should have returned ResizePtyResponse")
538 }
539 }
540
541 func Test_PodShim_closeIOInternal_NoTask_Error(t *testing.T) {
542 s := service{
543 tid: t.Name(),
544 isSandbox: true,
545 }
546
547 resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{ID: t.Name()})
548
549 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
550 }
551
552 func Test_PodShim_closeIOInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
553 s, t1, _, _ := setupPodServiceWithFakes(t)
554
555 resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{
556 ID: t1.ID(),
557 ExecID: "thisshouldnotmatch",
558 })
559
560 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
561 }
562
563 func Test_PodShim_closeIOInternal_InitTaskID_InitExecID_Success(t *testing.T) {
564 s, t1, _, _ := setupPodServiceWithFakes(t)
565
566 resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{
567 ID: t1.ID(),
568 ExecID: "",
569 })
570 if err != nil {
571 t.Fatalf("should not have failed with error got: %v", err)
572 }
573 if resp == nil {
574 t.Fatal("should have returned CloseIOResponse")
575 }
576 }
577
578 func Test_PodShim_closeIOInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
579 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
580
581 resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{
582 ID: t2.ID(),
583 ExecID: t2e2.ID(),
584 })
585 if err != nil {
586 t.Fatalf("should not have failed with error got: %v", err)
587 }
588 if resp == nil {
589 t.Fatal("should have returned CloseIOResponse")
590 }
591 }
592
593 func Test_PodShim_updateInternal_Success(t *testing.T) {
594 s, t1, _, _ := setupPodServiceWithFakes(t)
595
596 var limit uint64 = 100
597 resources := &specs.WindowsResources{
598 Memory: &specs.WindowsMemoryResources{
599 Limit: &limit,
600 },
601 }
602
603 any, err := typeurl.MarshalAny(resources)
604 if err != nil {
605 t.Fatal(err)
606 }
607
608 resp, err := s.updateInternal(context.TODO(), &task.UpdateTaskRequest{ID: t1.ID(), Resources: any})
609 if err != nil {
610 t.Fatalf("should not have failed with error, got: %v", err)
611 }
612 if resp == nil {
613 t.Fatalf("should have returned an empty resp")
614 }
615 }
616
617 func Test_PodShim_updateInternal_Error(t *testing.T) {
618 s, t1, _, _ := setupPodServiceWithFakes(t)
619
620
621 resources := &specs.Process{}
622 any, err := typeurl.MarshalAny(resources)
623 if err != nil {
624 t.Fatal(err)
625 }
626 _, err = s.updateInternal(context.TODO(), &task.UpdateTaskRequest{ID: t1.ID(), Resources: any})
627 if err == nil {
628 t.Fatal("expected to get an error for incorrect resource's type")
629 }
630 if err != errNotSupportedResourcesRequest {
631 t.Fatalf("expected to get errNotSupportedResourcesRequest, instead got %v", err)
632 }
633 }
634
635 func Test_PodShim_waitInternal_NoTask_Error(t *testing.T) {
636 s := service{
637 tid: t.Name(),
638 isSandbox: true,
639 }
640
641 resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{ID: t.Name()})
642
643 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
644 }
645
646 func Test_PodShim_waitInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
647 s, t1, _, _ := setupPodServiceWithFakes(t)
648
649 resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{
650 ID: t1.ID(),
651 ExecID: "thisshouldnotmatch",
652 })
653
654 verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
655 }
656
657 func Test_PodShim_waitInternal_InitTaskID_InitExecID_Success(t *testing.T) {
658 s, t1, _, _ := setupPodServiceWithFakes(t)
659
660 resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{
661 ID: t1.ID(),
662 ExecID: "",
663 })
664 if err != nil {
665 t.Fatalf("should not have failed with error got: %v", err)
666 }
667 if resp == nil {
668 t.Fatal("should have returned WaitResponse")
669 }
670 if resp.ExitStatus != t1.exec.Status().ExitStatus {
671 t.Fatal("should have returned exit status for init")
672 }
673 }
674
675 func Test_PodShim_waitInternal_2ndTaskID_2ndExecID_Success(t *testing.T) {
676 s, _, t2, t2e2 := setupPodServiceWithFakes(t)
677
678 resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{
679 ID: t2.ID(),
680 ExecID: t2e2.ID(),
681 })
682 if err != nil {
683 t.Fatalf("should not have failed with error got: %v", err)
684 }
685 if resp == nil {
686 t.Fatal("should have returned WaitResponse")
687 }
688 if resp.ExitStatus != t2.execs[t2e2.ID()].Status().ExitStatus {
689 t.Fatal("should have returned exit status for init")
690 }
691 }
692
693 func Test_PodShim_statsInternal_InitTaskID_Success(t *testing.T) {
694 testNames := []string{"WCOW", "LCOW"}
695 for i, isWCOW := range []bool{true, false} {
696 t.Run(testNames[i], func(t *testing.T) {
697 s, t1, _, _ := setupPodServiceWithFakes(t)
698 t1.isWCOW = isWCOW
699
700 resp, err := s.statsInternal(context.TODO(), &task.StatsRequest{ID: t1.ID()})
701
702 if err != nil {
703 t.Fatalf("should not have failed with error got: %v", err)
704 }
705 if resp == nil || resp.Stats == nil {
706 t.Fatal("should have returned valid stats response")
707 }
708 statsI, err := typeurl.UnmarshalAny(resp.Stats)
709 if err != nil {
710 t.Fatalf("should not have failed to unmarshal StatsResponse got: %v", err)
711 }
712 stats := statsI.(*stats.Statistics)
713 verifyExpectedStats(t, t1.isWCOW, true, stats)
714 })
715 }
716 }
717
718 func Test_PodShim_statsInternal_2ndTaskID_Success(t *testing.T) {
719 testNames := []string{"WCOW", "LCOW"}
720 for i, isWCOW := range []bool{true, false} {
721 t.Run(testNames[i], func(t *testing.T) {
722 s, _, t2, _ := setupPodServiceWithFakes(t)
723 t2.isWCOW = isWCOW
724
725 resp, err := s.statsInternal(context.TODO(), &task.StatsRequest{ID: t2.ID()})
726
727 if err != nil {
728 t.Fatalf("should not have failed with error got: %v", err)
729 }
730 if resp == nil || resp.Stats == nil {
731 t.Fatal("should have returned valid stats response")
732 }
733 statsI, err := typeurl.UnmarshalAny(resp.Stats)
734 if err != nil {
735 t.Fatalf("should not have failed to unmarshal StatsResponse got: %v", err)
736 }
737 stats := statsI.(*stats.Statistics)
738 verifyExpectedStats(t, t2.isWCOW, false, stats)
739 })
740 }
741 }
742
743 func Test_PodShim_shutdownInternal(t *testing.T) {
744 for _, now := range []bool{true, false} {
745 t.Run(fmt.Sprintf("%s_Now_%t", t.Name(), now), func(t *testing.T) {
746 s, _, _, _ := setupPodServiceWithFakes(t)
747
748 if s.IsShutdown() {
749 t.Fatal("service prematurely shutdown")
750 }
751
752 _, err := s.shutdownInternal(context.Background(), &task.ShutdownRequest{
753 ID: s.tid,
754 Now: now,
755 })
756 if err != nil {
757 t.Fatalf("could not shut down service: %v", err)
758 }
759
760 tm := time.NewTimer(5 * time.Millisecond)
761 select {
762 case <-tm.C:
763 t.Fatalf("shutdown channel did not close")
764 case <-s.Done():
765 tm.Stop()
766 }
767
768 if !s.IsShutdown() {
769 t.Fatal("service did not shutdown")
770 }
771 })
772 }
773 }
774
View as plain text