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