1package main 2 3import ( 4 "context" 5 "math/rand" 6 "strconv" 7 "sync" 8 "testing" 9 10 "github.com/containerd/containerd/errdefs" 11 "github.com/containerd/containerd/runtime/v2/task" 12 specs "github.com/opencontainers/runtime-spec/specs-go" 13) 14 15var _ = (shimPod)(&testShimPod{}) 16 17type testShimPod struct { 18 id string 19 20 tasks sync.Map 21} 22 23func (tsp *testShimPod) ID() string { 24 return tsp.id 25} 26 27func (tsp *testShimPod) CreateTask(ctx context.Context, req *task.CreateTaskRequest, s *specs.Spec) (shimTask, error) { 28 return nil, errdefs.ErrNotImplemented 29} 30 31func (tsp *testShimPod) GetTask(tid string) (shimTask, error) { 32 v, loaded := tsp.tasks.Load(tid) 33 if loaded { 34 return v.(shimTask), nil 35 } 36 return nil, errdefs.ErrNotFound 37} 38 39func (tsp *testShimPod) KillTask(ctx context.Context, tid, eid string, signal uint32, all bool) error { 40 s, err := tsp.GetTask(tid) 41 if err != nil { 42 return err 43 } 44 return s.KillExec(ctx, eid, signal, all) 45} 46 47// Pod tests 48 49func setupTestPodWithFakes(t *testing.T) (*pod, *testShimTask) { 50 st := &testShimTask{ 51 id: t.Name(), 52 exec: newTestShimExec(t.Name(), t.Name(), 10), 53 execs: make(map[string]*testShimExec), 54 } 55 // Add a 2nd exec 56 seid := strconv.Itoa(rand.Int()) 57 st.execs[seid] = newTestShimExec(t.Name(), seid, int(rand.Int31())) 58 p := &pod{ 59 id: t.Name(), 60 sandboxTask: st, 61 } 62 return p, st 63} 64 65func setupTestTaskInPod(t *testing.T, p *pod) *testShimTask { 66 tid := strconv.Itoa(rand.Int()) 67 wt := &testShimTask{ 68 id: tid, 69 exec: newTestShimExec(tid, tid, int(rand.Int31())), 70 } 71 p.workloadTasks.Store(wt.id, wt) 72 return wt 73} 74 75func Test_pod_ID(t *testing.T) { 76 p := pod{id: t.Name()} 77 id := p.ID() 78 if id != t.Name() { 79 t.Fatalf("pod should of returned ID: %s, got: %s", t.Name(), id) 80 } 81} 82 83func Test_pod_GetTask_SandboxID(t *testing.T) { 84 p, st := setupTestPodWithFakes(t) 85 t1, err := p.GetTask(t.Name()) 86 if err != nil { 87 t.Fatalf("should not have failed, got: %v", err) 88 } 89 if t1 != st { 90 t.Fatal("should have returned sandbox task") 91 } 92} 93 94func Test_pod_GetTask_WorkloadID_NotCreated_Error(t *testing.T) { 95 p, _ := setupTestPodWithFakes(t) 96 t1, err := p.GetTask("thisshouldnotmatch") 97 98 verifyExpectedError(t, t1, err, errdefs.ErrNotFound) 99} 100 101func Test_pod_GetTask_WorkloadID_Created_Success(t *testing.T) { 102 p, _ := setupTestPodWithFakes(t) 103 t2 := setupTestTaskInPod(t, p) 104 105 resp, err := p.GetTask(t2.ID()) 106 if err != nil { 107 t.Fatalf("should not have failed, got: %v", err) 108 } 109 if resp != t2 { 110 t.Fatal("should have returned workload task") 111 } 112} 113 114func Test_pod_KillTask_UnknownTaskID_Error(t *testing.T) { 115 p, _ := setupTestPodWithFakes(t) 116 err := p.KillTask(context.TODO(), "thisshouldnotmatch", "", 0xf, false) 117 118 verifyExpectedError(t, nil, err, errdefs.ErrNotFound) 119} 120 121func Test_pod_KillTask_SandboxID_UnknownExecID_Error(t *testing.T) { 122 p, _ := setupTestPodWithFakes(t) 123 err := p.KillTask(context.TODO(), t.Name(), "thisshouldnotmatch", 0xf, false) 124 125 verifyExpectedError(t, nil, err, errdefs.ErrNotFound) 126} 127 128func Test_pod_KillTask_SandboxID_InitExecID_Success(t *testing.T) { 129 p, _ := setupTestPodWithFakes(t) 130 err := p.KillTask(context.TODO(), t.Name(), "", 0xf, false) 131 if err != nil { 132 t.Fatalf("should not have failed, got: %v", err) 133 } 134} 135 136func Test_pod_KillTask_SandboxID_InitExecID_All_Success(t *testing.T) { 137 p, _ := setupTestPodWithFakes(t) 138 // Add two workload tasks 139 setupTestTaskInPod(t, p) 140 setupTestTaskInPod(t, p) 141 err := p.KillTask(context.TODO(), t.Name(), "", 0xf, true) 142 if err != nil { 143 t.Fatalf("should not have failed, got: %v", err) 144 } 145} 146 147func Test_pod_KillTask_SandboxID_2ndExecID_Success(t *testing.T) { 148 p, t1 := setupTestPodWithFakes(t) 149 for k := range t1.execs { 150 err := p.KillTask(context.TODO(), t.Name(), k, 0xf, false) 151 if err != nil { 152 t.Fatalf("should not have failed, got: %v", err) 153 } 154 } 155} 156 157func Test_pod_KillTask_SandboxID_2ndExecID_All_Error(t *testing.T) { 158 p, t1 := setupTestPodWithFakes(t) 159 for k := range t1.execs { 160 err := p.KillTask(context.TODO(), t.Name(), k, 0xf, true) 161 162 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition) 163 } 164} 165 166func Test_pod_KillTask_WorkloadID_InitExecID_Success(t *testing.T) { 167 p, _ := setupTestPodWithFakes(t) 168 t1 := setupTestTaskInPod(t, p) 169 170 err := p.KillTask(context.TODO(), t1.ID(), "", 0xf, false) 171 if err != nil { 172 t.Fatalf("should not have failed, got: %v", err) 173 } 174} 175 176func Test_pod_KillTask_WorkloadID_InitExecID_All_Success(t *testing.T) { 177 p, _ := setupTestPodWithFakes(t) 178 t1 := setupTestTaskInPod(t, p) 179 180 err := p.KillTask(context.TODO(), t1.ID(), "", 0xf, true) 181 if err != nil { 182 t.Fatalf("should not have failed, got: %v", err) 183 } 184} 185 186func Test_pod_KillTask_WorkloadID_2ndExecID_Success(t *testing.T) { 187 p, _ := setupTestPodWithFakes(t) 188 t1 := setupTestTaskInPod(t, p) 189 190 for k := range t1.execs { 191 err := p.KillTask(context.TODO(), t1.ID(), k, 0xf, false) 192 if err != nil { 193 t.Fatalf("should not have failed, got: %v", err) 194 } 195 } 196} 197 198func Test_pod_KillTask_WorkloadID_2ndExecID_All_Error(t *testing.T) { 199 p, _ := setupTestPodWithFakes(t) 200 t1 := setupTestTaskInPod(t, p) 201 202 for k := range t1.execs { 203 err := p.KillTask(context.TODO(), t1.ID(), k, 0xf, true) 204 205 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition) 206 } 207} 208