1
2
3 package main
4
5 import (
6 "context"
7 "math/rand"
8 "strconv"
9 "testing"
10 "time"
11
12 "github.com/containerd/containerd/errdefs"
13 )
14
15 func setupTestHcsTask(t *testing.T) (*hcsTask, *testShimExec, *testShimExec) {
16 t.Helper()
17 initExec := newTestShimExec(t.Name(), t.Name(), int(rand.Int31()))
18 lt := &hcsTask{
19 events: newFakePublisher(),
20 id: t.Name(),
21 init: initExec,
22 closed: make(chan struct{}),
23 }
24 secondExecID := strconv.Itoa(rand.Int())
25 secondExec := newTestShimExec(t.Name(), secondExecID, int(rand.Int31()))
26 lt.execs.Store(secondExecID, secondExec)
27 return lt, initExec, secondExec
28 }
29
30 func Test_hcsTask_ID(t *testing.T) {
31 lt, _, _ := setupTestHcsTask(t)
32
33 if lt.ID() != t.Name() {
34 t.Fatalf("expect ID: '%s', got: '%s'", t.Name(), lt.ID())
35 }
36 }
37
38 func Test_hcsTask_GetExec_Empty_Success(t *testing.T) {
39 lt, i, _ := setupTestHcsTask(t)
40
41 e, err := lt.GetExec("")
42 if err != nil {
43 t.Fatalf("should not have failed with error: %v", err)
44 }
45 if i != e {
46 t.Fatal("should of returned the init exec on empty")
47 }
48 }
49
50 func Test_hcsTask_GetExec_UnknownExecID_Error(t *testing.T) {
51 lt, _, _ := setupTestHcsTask(t)
52
53 e, err := lt.GetExec("shouldnotmatch")
54
55 verifyExpectedError(t, e, err, errdefs.ErrNotFound)
56 }
57
58 func Test_hcsTask_GetExec_2ndID_Success(t *testing.T) {
59 lt, _, second := setupTestHcsTask(t)
60
61 e, err := lt.GetExec(second.id)
62 if err != nil {
63 t.Fatalf("should not have failed with error: %v", err)
64 }
65 if second != e {
66 t.Fatal("should of returned the second exec")
67 }
68 }
69
70 func Test_hcsTask_KillExec_UnknownExecID_Error(t *testing.T) {
71 lt, _, _ := setupTestHcsTask(t)
72
73 err := lt.KillExec(context.TODO(), "thisshouldnotmatch", 0xf, false)
74
75 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
76 }
77
78 func Test_hcsTask_KillExec_InitExecID_Unexited2ndExec_Success(t *testing.T) {
79 lt, init, second := setupTestHcsTask(t)
80
81 err := lt.KillExec(context.TODO(), "", 0xf, false)
82 if err != nil {
83 t.Fatalf("should not have failed, got: %v", err)
84 }
85 if init.state != shimExecStateExited {
86 t.Fatalf("init should be in exited state got: %v", init.state)
87 }
88
89
90 if second.state != shimExecStateCreated {
91 t.Fatalf("2nd exec should be in created state, got: %v", second.state)
92 }
93 }
94
95 func Test_hcsTask_KillExec_InitExecID_All_Success(t *testing.T) {
96 lt, init, second := setupTestHcsTask(t)
97
98 err := lt.KillExec(context.TODO(), "", 0xf, true)
99 if err != nil {
100 t.Fatalf("should not have failed, got: %v", err)
101 }
102 if init.state != shimExecStateExited {
103 t.Fatalf("init should be in exited state got: %v", init.state)
104 }
105 if second.state != shimExecStateExited {
106 t.Fatalf("2nd exec should be in exited state got: %v", second.state)
107 }
108 }
109
110 func Test_hcsTask_KillExec_2ndExecID_Success(t *testing.T) {
111 lt, _, second := setupTestHcsTask(t)
112
113 err := lt.KillExec(context.TODO(), second.id, 0xf, false)
114 if err != nil {
115 t.Fatalf("should not have failed, got: %v", err)
116 }
117 if second.state != shimExecStateExited {
118 t.Fatalf("2nd exec should be in exited state got: %v", second.state)
119 }
120 }
121
122 func Test_hcsTask_KillExec_2ndExecID_All_Error(t *testing.T) {
123 lt, _, second := setupTestHcsTask(t)
124
125 err := lt.KillExec(context.TODO(), second.id, 0xf, true)
126
127 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
128 }
129
130 func verifyDeleteFailureValues(t *testing.T, pid int, status uint32, at time.Time) {
131 t.Helper()
132 if pid != 0 {
133 t.Fatalf("pid expected '0' got: '%d'", pid)
134 }
135 if status != 0 {
136 t.Fatalf("status expected '0' got: '%d'", status)
137 }
138 if !at.IsZero() {
139 t.Fatalf("at expected 'zero' got: '%v'", at)
140 }
141 }
142
143 func verifyDeleteSuccessValues(t *testing.T, pid int, status uint32, at time.Time, e *testShimExec) {
144 t.Helper()
145 if pid != e.pid {
146 t.Fatalf("pid expected '%d' got: '%d'", e.pid, pid)
147 }
148 if status != e.status {
149 t.Fatalf("status expected '%d' got: '%d'", e.status, status)
150 }
151 if at != e.at {
152 t.Fatalf("at expected '%v' got: '%v'", e.at, at)
153 }
154 }
155
156 func Test_hcsTask_DeleteExec_UnknownExecID_Error(t *testing.T) {
157 lt, _, _ := setupTestHcsTask(t)
158
159 pid, status, at, err := lt.DeleteExec(context.TODO(), "thisshouldnotmatch")
160 verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
161 verifyDeleteFailureValues(t, pid, status, at)
162 }
163
164 func Test_hcsTask_DeleteExec_InitExecID_CreatedState_Success(t *testing.T) {
165 lt, init, second := setupTestHcsTask(t)
166
167 lt.execs.Delete(second.id)
168
169
170 close(lt.closed)
171
172 pid, status, at, err := lt.DeleteExec(context.TODO(), "")
173
174 if err != nil {
175 t.Fatalf("expected nil err got: %v", err)
176 }
177 verifyDeleteSuccessValues(t, pid, status, at, init)
178 }
179
180 func Test_hcsTask_DeleteExec_InitExecID_RunningState_Error(t *testing.T) {
181 lt, init, second := setupTestHcsTask(t)
182
183 lt.execs.Delete(second.id)
184
185
186 _ = init.Start(context.TODO())
187
188
189 close(lt.closed)
190
191 pid, status, at, err := lt.DeleteExec(context.TODO(), "")
192
193 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
194 verifyDeleteFailureValues(t, pid, status, at)
195 }
196
197 func Test_hcsTask_DeleteExec_InitExecID_ExitedState_Success(t *testing.T) {
198 lt, init, second := setupTestHcsTask(t)
199
200 lt.execs.Delete(second.id)
201
202 _ = init.Kill(context.TODO(), 0xf)
203
204
205 close(lt.closed)
206
207 pid, status, at, err := lt.DeleteExec(context.TODO(), "")
208
209 if err != nil {
210 t.Fatalf("expected nil err got: %v", err)
211 }
212 verifyDeleteSuccessValues(t, pid, status, at, init)
213 }
214
215 func Test_hcsTask_DeleteExec_InitExecID_2ndExec_CreatedState_Error(t *testing.T) {
216 lt, init, second := setupTestHcsTask(t)
217
218
219 _ = init.Start(context.TODO())
220
221
222 close(lt.closed)
223
224 pid, status, at, err := lt.DeleteExec(context.TODO(), "")
225
226 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
227 verifyDeleteFailureValues(t, pid, status, at)
228 if second.state != shimExecStateExited {
229 t.Fatalf("2nd exec should be in exited state, got: %v", second.state)
230 }
231 }
232
233 func Test_hcsTask_DeleteExec_InitExecID_2ndExec_RunningState_Error(t *testing.T) {
234 lt, init, second := setupTestHcsTask(t)
235
236
237 _ = init.Start(context.TODO())
238
239
240 _ = second.Start(context.TODO())
241
242
243 close(lt.closed)
244
245 pid, status, at, err := lt.DeleteExec(context.TODO(), "")
246
247 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
248 verifyDeleteFailureValues(t, pid, status, at)
249 if second.state != shimExecStateExited {
250 t.Fatalf("2nd exec should be in exited state, got: %v", second.state)
251 }
252 }
253
254 func Test_hcsTask_DeleteExec_InitExecID_2ndExec_ExitedState_Success(t *testing.T) {
255 lt, init, second := setupTestHcsTask(t)
256
257
258 _ = init.Kill(context.TODO(), 0xf)
259
260 _ = second.Kill(context.TODO(), 0xf)
261
262
263 close(lt.closed)
264
265 pid, status, at, err := lt.DeleteExec(context.TODO(), "")
266
267 if err != nil {
268 t.Fatalf("expected nil err got: %v", err)
269 }
270 verifyDeleteSuccessValues(t, pid, status, at, init)
271 }
272
273 func Test_hcsTask_DeleteExec_2ndExecID_CreatedState_Success(t *testing.T) {
274 lt, init, second := setupTestHcsTask(t)
275
276
277 _ = init.Start(context.TODO())
278
279
280 pid, status, at, err := lt.DeleteExec(context.TODO(), second.id)
281
282 if err != nil {
283 t.Fatalf("expected nil err got: %v", err)
284 }
285 verifyDeleteSuccessValues(t, pid, status, at, second)
286 }
287
288 func Test_hcsTask_DeleteExec_2ndExecID_RunningState_Error(t *testing.T) {
289 lt, init, second := setupTestHcsTask(t)
290
291
292 _ = init.Start(context.TODO())
293
294
295 _ = second.Start(context.TODO())
296
297
298 pid, status, at, err := lt.DeleteExec(context.TODO(), second.id)
299
300 verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
301 verifyDeleteFailureValues(t, pid, status, at)
302 }
303
304 func Test_hcsTask_DeleteExec_2ndExecID_ExitedState_Success(t *testing.T) {
305 lt, init, second := setupTestHcsTask(t)
306
307
308 _ = init.Kill(context.TODO(), 0xf)
309
310
311 _ = second.Kill(context.TODO(), 0xf)
312
313
314 pid, status, at, err := lt.DeleteExec(context.TODO(), second.id)
315
316 if err != nil {
317 t.Fatalf("expected nil err got: %v", err)
318 }
319 verifyDeleteSuccessValues(t, pid, status, at, second)
320 }
321
View as plain text