1
2
3
4 package e2e
5
6 import (
7 "context"
8 "fmt"
9
10 . "github.com/onsi/ginkgo/v2"
11 . "github.com/onsi/gomega"
12 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
13 "sigs.k8s.io/cli-utils/pkg/apis/actuation"
14 "sigs.k8s.io/cli-utils/pkg/apply"
15 "sigs.k8s.io/cli-utils/pkg/apply/event"
16 "sigs.k8s.io/cli-utils/pkg/apply/filter"
17 "sigs.k8s.io/cli-utils/pkg/object"
18 "sigs.k8s.io/cli-utils/pkg/object/validation"
19 "sigs.k8s.io/cli-utils/pkg/testutil"
20 "sigs.k8s.io/cli-utils/test/e2e/e2eutil"
21 "sigs.k8s.io/cli-utils/test/e2e/invconfig"
22 "sigs.k8s.io/controller-runtime/pkg/client"
23 )
24
25
26 func dependencyFilterTest(ctx context.Context, c client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) {
27 By("apply resources in order based on depends-on annotation")
28 applier := invConfig.ApplierFactoryFunc()
29
30 inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
31
32 pod1Obj := e2eutil.WithDependsOn(e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(pod1), namespaceName), fmt.Sprintf("/namespaces/%s/Pod/pod2", namespaceName))
33 pod2Obj := e2eutil.WithNamespace(e2eutil.ManifestToUnstructured(pod2), namespaceName)
34
35
36
37 resources := []*unstructured.Unstructured{
38 pod1Obj,
39 pod2Obj,
40 }
41
42
43 defer func(ctx context.Context, c client.Client) {
44 e2eutil.DeleteUnstructuredIfExists(ctx, c, pod1Obj)
45 e2eutil.DeleteUnstructuredIfExists(ctx, c, pod2Obj)
46 }(ctx, c)
47
48 applierEvents := e2eutil.RunCollect(applier.Run(ctx, inv, resources, apply.ApplierOptions{
49 EmitStatusEvents: false,
50 }))
51
52 expEvents := []testutil.ExpEvent{
53 {
54
55 EventType: event.InitType,
56 InitEvent: &testutil.ExpInitEvent{},
57 },
58 {
59
60 EventType: event.ActionGroupType,
61 ActionGroupEvent: &testutil.ExpActionGroupEvent{
62 Action: event.InventoryAction,
63 GroupName: "inventory-add-0",
64 Type: event.Started,
65 },
66 },
67 {
68
69 EventType: event.ActionGroupType,
70 ActionGroupEvent: &testutil.ExpActionGroupEvent{
71 Action: event.InventoryAction,
72 GroupName: "inventory-add-0",
73 Type: event.Finished,
74 },
75 },
76 {
77
78 EventType: event.ActionGroupType,
79 ActionGroupEvent: &testutil.ExpActionGroupEvent{
80 Action: event.ApplyAction,
81 GroupName: "apply-0",
82 Type: event.Started,
83 },
84 },
85 {
86
87 EventType: event.ApplyType,
88 ApplyEvent: &testutil.ExpApplyEvent{
89 GroupName: "apply-0",
90 Status: event.ApplySuccessful,
91 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
92 Error: nil,
93 },
94 },
95 {
96
97 EventType: event.ActionGroupType,
98 ActionGroupEvent: &testutil.ExpActionGroupEvent{
99 Action: event.ApplyAction,
100 GroupName: "apply-0",
101 Type: event.Finished,
102 },
103 },
104 {
105
106 EventType: event.ActionGroupType,
107 ActionGroupEvent: &testutil.ExpActionGroupEvent{
108 Action: event.WaitAction,
109 GroupName: "wait-0",
110 Type: event.Started,
111 },
112 },
113 {
114
115 EventType: event.WaitType,
116 WaitEvent: &testutil.ExpWaitEvent{
117 GroupName: "wait-0",
118 Status: event.ReconcilePending,
119 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
120 },
121 },
122 {
123
124 EventType: event.WaitType,
125 WaitEvent: &testutil.ExpWaitEvent{
126 GroupName: "wait-0",
127 Status: event.ReconcileSuccessful,
128 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
129 },
130 },
131 {
132
133 EventType: event.ActionGroupType,
134 ActionGroupEvent: &testutil.ExpActionGroupEvent{
135 Action: event.WaitAction,
136 GroupName: "wait-0",
137 Type: event.Finished,
138 },
139 },
140 {
141
142 EventType: event.ActionGroupType,
143 ActionGroupEvent: &testutil.ExpActionGroupEvent{
144 Action: event.ApplyAction,
145 GroupName: "apply-1",
146 Type: event.Started,
147 },
148 },
149 {
150
151 EventType: event.ApplyType,
152 ApplyEvent: &testutil.ExpApplyEvent{
153 GroupName: "apply-1",
154 Status: event.ApplySuccessful,
155 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
156 Error: nil,
157 },
158 },
159 {
160
161 EventType: event.ActionGroupType,
162 ActionGroupEvent: &testutil.ExpActionGroupEvent{
163 Action: event.ApplyAction,
164 GroupName: "apply-1",
165 Type: event.Finished,
166 },
167 },
168 {
169
170 EventType: event.ActionGroupType,
171 ActionGroupEvent: &testutil.ExpActionGroupEvent{
172 Action: event.WaitAction,
173 GroupName: "wait-1",
174 Type: event.Started,
175 },
176 },
177 {
178
179 EventType: event.WaitType,
180 WaitEvent: &testutil.ExpWaitEvent{
181 GroupName: "wait-1",
182 Status: event.ReconcilePending,
183 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
184 },
185 },
186 {
187
188 EventType: event.WaitType,
189 WaitEvent: &testutil.ExpWaitEvent{
190 GroupName: "wait-1",
191 Status: event.ReconcileSuccessful,
192 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
193 },
194 },
195 {
196
197 EventType: event.ActionGroupType,
198 ActionGroupEvent: &testutil.ExpActionGroupEvent{
199 Action: event.WaitAction,
200 GroupName: "wait-1",
201 Type: event.Finished,
202 },
203 },
204 {
205
206 EventType: event.ActionGroupType,
207 ActionGroupEvent: &testutil.ExpActionGroupEvent{
208 Action: event.InventoryAction,
209 GroupName: "inventory-set-0",
210 Type: event.Started,
211 },
212 },
213 {
214
215 EventType: event.ActionGroupType,
216 ActionGroupEvent: &testutil.ExpActionGroupEvent{
217 Action: event.InventoryAction,
218 GroupName: "inventory-set-0",
219 Type: event.Finished,
220 },
221 },
222 }
223 receivedEvents := testutil.EventsToExpEvents(applierEvents)
224
225 expEvents, receivedEvents = e2eutil.FilterOptionalEvents(expEvents, receivedEvents)
226
227 Expect(receivedEvents).To(testutil.Equal(expEvents))
228
229 By("verify pod1 created and ready")
230 result := e2eutil.AssertUnstructuredExists(ctx, c, pod1Obj)
231 podIP, found, err := object.NestedField(result.Object, "status", "podIP")
232 Expect(err).NotTo(HaveOccurred())
233 Expect(found).To(BeTrue())
234 Expect(podIP).NotTo(BeEmpty())
235
236 By("verify pod2 created and ready")
237 result = e2eutil.AssertUnstructuredExists(ctx, c, pod2Obj)
238 podIP, found, err = object.NestedField(result.Object, "status", "podIP")
239 Expect(err).NotTo(HaveOccurred())
240 Expect(found).To(BeTrue())
241 Expect(podIP).NotTo(BeEmpty())
242
243
244 resources = []*unstructured.Unstructured{
245 pod1Obj,
246 }
247
248 applierEvents = e2eutil.RunCollect(applier.Run(ctx, inv, resources, apply.ApplierOptions{
249 EmitStatusEvents: false,
250 ValidationPolicy: validation.SkipInvalid,
251 }))
252
253 expEvents = []testutil.ExpEvent{
254 {
255
256 EventType: event.InitType,
257 InitEvent: &testutil.ExpInitEvent{},
258 },
259 {
260
261 EventType: event.ActionGroupType,
262 ActionGroupEvent: &testutil.ExpActionGroupEvent{
263 Action: event.InventoryAction,
264 GroupName: "inventory-add-0",
265 Type: event.Started,
266 },
267 },
268 {
269
270 EventType: event.ActionGroupType,
271 ActionGroupEvent: &testutil.ExpActionGroupEvent{
272 Action: event.InventoryAction,
273 GroupName: "inventory-add-0",
274 Type: event.Finished,
275 },
276 },
277 {
278
279 EventType: event.ActionGroupType,
280 ActionGroupEvent: &testutil.ExpActionGroupEvent{
281 Action: event.ApplyAction,
282 GroupName: "apply-0",
283 Type: event.Started,
284 },
285 },
286 {
287
288 EventType: event.ApplyType,
289 ApplyEvent: &testutil.ExpApplyEvent{
290 GroupName: "apply-0",
291 Status: event.ApplySkipped,
292 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
293 Error: testutil.EqualError(&filter.DependencyActuationMismatchError{
294 Object: object.UnstructuredToObjMetadata(pod1Obj),
295 Strategy: actuation.ActuationStrategyApply,
296 Relationship: filter.RelationshipDependency,
297 Relation: object.UnstructuredToObjMetadata(pod2Obj),
298 RelationStrategy: actuation.ActuationStrategyDelete,
299 }),
300 },
301 },
302 {
303
304 EventType: event.ActionGroupType,
305 ActionGroupEvent: &testutil.ExpActionGroupEvent{
306 Action: event.ApplyAction,
307 GroupName: "apply-0",
308 Type: event.Finished,
309 },
310 },
311 {
312
313 EventType: event.ActionGroupType,
314 ActionGroupEvent: &testutil.ExpActionGroupEvent{
315 Action: event.WaitAction,
316 GroupName: "wait-0",
317 Type: event.Started,
318 },
319 },
320 {
321
322 EventType: event.WaitType,
323 WaitEvent: &testutil.ExpWaitEvent{
324 GroupName: "wait-0",
325 Status: event.ReconcileSkipped,
326 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
327 },
328 },
329 {
330
331 EventType: event.ActionGroupType,
332 ActionGroupEvent: &testutil.ExpActionGroupEvent{
333 Action: event.WaitAction,
334 GroupName: "wait-0",
335 Type: event.Finished,
336 },
337 },
338 {
339
340 EventType: event.ActionGroupType,
341 ActionGroupEvent: &testutil.ExpActionGroupEvent{
342 Action: event.PruneAction,
343 GroupName: "prune-0",
344 Type: event.Started,
345 },
346 },
347 {
348
349 EventType: event.PruneType,
350 PruneEvent: &testutil.ExpPruneEvent{
351 GroupName: "prune-0",
352 Status: event.PruneSkipped,
353 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
354 Error: testutil.EqualError(&filter.DependencyActuationMismatchError{
355 Object: object.UnstructuredToObjMetadata(pod2Obj),
356 Strategy: actuation.ActuationStrategyDelete,
357 Relationship: filter.RelationshipDependent,
358 Relation: object.UnstructuredToObjMetadata(pod1Obj),
359 RelationStrategy: actuation.ActuationStrategyApply,
360 }),
361 },
362 },
363 {
364
365 EventType: event.ActionGroupType,
366 ActionGroupEvent: &testutil.ExpActionGroupEvent{
367 Action: event.PruneAction,
368 GroupName: "prune-0",
369 Type: event.Finished,
370 },
371 },
372 {
373
374 EventType: event.ActionGroupType,
375 ActionGroupEvent: &testutil.ExpActionGroupEvent{
376 Action: event.WaitAction,
377 GroupName: "wait-1",
378 Type: event.Started,
379 },
380 },
381 {
382
383 EventType: event.WaitType,
384 WaitEvent: &testutil.ExpWaitEvent{
385 GroupName: "wait-1",
386 Status: event.ReconcileSkipped,
387 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
388 },
389 },
390 {
391
392 EventType: event.ActionGroupType,
393 ActionGroupEvent: &testutil.ExpActionGroupEvent{
394 Action: event.WaitAction,
395 GroupName: "wait-1",
396 Type: event.Finished,
397 },
398 },
399 {
400
401 EventType: event.ActionGroupType,
402 ActionGroupEvent: &testutil.ExpActionGroupEvent{
403 Action: event.InventoryAction,
404 GroupName: "inventory-set-0",
405 Type: event.Started,
406 },
407 },
408 {
409
410 EventType: event.ActionGroupType,
411 ActionGroupEvent: &testutil.ExpActionGroupEvent{
412 Action: event.InventoryAction,
413 GroupName: "inventory-set-0",
414 Type: event.Finished,
415 },
416 },
417 }
418 receivedEvents = testutil.EventsToExpEvents(applierEvents)
419
420 expEvents, receivedEvents = e2eutil.FilterOptionalEvents(expEvents, receivedEvents)
421
422 Expect(receivedEvents).To(testutil.Equal(expEvents))
423
424 By("verify pod1 not deleted")
425 result = e2eutil.AssertUnstructuredExists(ctx, c, pod1Obj)
426 ts, found, err := object.NestedField(result.Object, "metadata", "deletionTimestamp")
427 Expect(err).NotTo(HaveOccurred())
428 Expect(found).To(BeFalse(), "deletionTimestamp found: ", ts)
429
430 By("verify pod2 not deleted")
431 result = e2eutil.AssertUnstructuredExists(ctx, c, pod2Obj)
432 ts, found, err = object.NestedField(result.Object, "metadata", "deletionTimestamp")
433 Expect(err).NotTo(HaveOccurred())
434 Expect(found).To(BeFalse(), "deletionTimestamp found: ", ts)
435 }
436
View as plain text