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/apply"
14 "sigs.k8s.io/cli-utils/pkg/apply/event"
15 "sigs.k8s.io/cli-utils/pkg/inventory"
16 "sigs.k8s.io/cli-utils/pkg/object"
17 "sigs.k8s.io/cli-utils/pkg/testutil"
18 "sigs.k8s.io/cli-utils/test/e2e/e2eutil"
19 "sigs.k8s.io/cli-utils/test/e2e/invconfig"
20 "sigs.k8s.io/controller-runtime/pkg/client"
21 )
22
23 func dependsOnTest(ctx context.Context, c client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) {
24 By("apply resources in order based on depends-on annotation")
25 applier := invConfig.ApplierFactoryFunc()
26
27 inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
28
29 namespace1Name := fmt.Sprintf("%s-ns1", namespaceName)
30 namespace1Obj := e2eutil.UnstructuredNamespace(namespace1Name)
31
32 namespace2Name := fmt.Sprintf("%s-ns2", namespaceName)
33 namespace2Obj := e2eutil.UnstructuredNamespace(namespace2Name)
34
35 pod1Obj := e2eutil.ManifestToUnstructured(pod1)
36 pod1Obj = e2eutil.WithNamespace(pod1Obj, namespace1Name)
37 pod1Obj = e2eutil.WithDependsOn(pod1Obj, fmt.Sprintf("/namespaces/%s/Pod/pod3", namespace1Name))
38
39 pod2Obj := e2eutil.ManifestToUnstructured(pod2)
40 pod2Obj = e2eutil.WithNamespace(pod2Obj, namespace2Name)
41
42 pod3Obj := e2eutil.ManifestToUnstructured(pod3)
43 pod3Obj = e2eutil.WithNamespace(pod3Obj, namespace1Name)
44 pod3Obj = e2eutil.WithDependsOn(pod3Obj, fmt.Sprintf("/namespaces/%s/Pod/pod2", namespace2Name))
45
46
47
48 resources := []*unstructured.Unstructured{
49 namespace1Obj,
50 namespace2Obj,
51 pod1Obj,
52 pod2Obj,
53 pod3Obj,
54 }
55
56 applierEvents := e2eutil.RunCollect(applier.Run(ctx, inv, resources, apply.ApplierOptions{
57 EmitStatusEvents: false,
58 }))
59
60 expEvents := []testutil.ExpEvent{
61 {
62
63 EventType: event.InitType,
64 InitEvent: &testutil.ExpInitEvent{},
65 },
66 {
67
68 EventType: event.ActionGroupType,
69 ActionGroupEvent: &testutil.ExpActionGroupEvent{
70 Action: event.InventoryAction,
71 GroupName: "inventory-add-0",
72 Type: event.Started,
73 },
74 },
75 {
76
77 EventType: event.ActionGroupType,
78 ActionGroupEvent: &testutil.ExpActionGroupEvent{
79 Action: event.InventoryAction,
80 GroupName: "inventory-add-0",
81 Type: event.Finished,
82 },
83 },
84 {
85
86 EventType: event.ActionGroupType,
87 ActionGroupEvent: &testutil.ExpActionGroupEvent{
88 Action: event.ApplyAction,
89 GroupName: "apply-0",
90 Type: event.Started,
91 },
92 },
93 {
94
95 EventType: event.ApplyType,
96 ApplyEvent: &testutil.ExpApplyEvent{
97 GroupName: "apply-0",
98 Status: event.ApplySuccessful,
99 Identifier: object.UnstructuredToObjMetadata(namespace1Obj),
100 },
101 },
102 {
103
104 EventType: event.ApplyType,
105 ApplyEvent: &testutil.ExpApplyEvent{
106 GroupName: "apply-0",
107 Status: event.ApplySuccessful,
108 Identifier: object.UnstructuredToObjMetadata(namespace2Obj),
109 },
110 },
111 {
112
113 EventType: event.ActionGroupType,
114 ActionGroupEvent: &testutil.ExpActionGroupEvent{
115 Action: event.ApplyAction,
116 GroupName: "apply-0",
117 Type: event.Finished,
118 },
119 },
120 {
121
122 EventType: event.ActionGroupType,
123 ActionGroupEvent: &testutil.ExpActionGroupEvent{
124 Action: event.WaitAction,
125 GroupName: "wait-0",
126 Type: event.Started,
127 },
128 },
129 {
130
131 EventType: event.WaitType,
132 WaitEvent: &testutil.ExpWaitEvent{
133 GroupName: "wait-0",
134 Status: event.ReconcilePending,
135 Identifier: object.UnstructuredToObjMetadata(namespace1Obj),
136 },
137 },
138 {
139
140 EventType: event.WaitType,
141 WaitEvent: &testutil.ExpWaitEvent{
142 GroupName: "wait-0",
143 Status: event.ReconcilePending,
144 Identifier: object.UnstructuredToObjMetadata(namespace2Obj),
145 },
146 },
147 {
148
149 EventType: event.WaitType,
150 WaitEvent: &testutil.ExpWaitEvent{
151 GroupName: "wait-0",
152 Status: event.ReconcileSuccessful,
153 Identifier: object.UnstructuredToObjMetadata(namespace1Obj),
154 },
155 },
156 {
157
158 EventType: event.WaitType,
159 WaitEvent: &testutil.ExpWaitEvent{
160 GroupName: "wait-0",
161 Status: event.ReconcileSuccessful,
162 Identifier: object.UnstructuredToObjMetadata(namespace2Obj),
163 },
164 },
165 {
166
167 EventType: event.ActionGroupType,
168 ActionGroupEvent: &testutil.ExpActionGroupEvent{
169 Action: event.WaitAction,
170 GroupName: "wait-0",
171 Type: event.Finished,
172 },
173 },
174 {
175
176 EventType: event.ActionGroupType,
177 ActionGroupEvent: &testutil.ExpActionGroupEvent{
178 Action: event.ApplyAction,
179 GroupName: "apply-1",
180 Type: event.Started,
181 },
182 },
183 {
184
185 EventType: event.ApplyType,
186 ApplyEvent: &testutil.ExpApplyEvent{
187 GroupName: "apply-1",
188 Status: event.ApplySuccessful,
189 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
190 Error: nil,
191 },
192 },
193 {
194
195 EventType: event.ActionGroupType,
196 ActionGroupEvent: &testutil.ExpActionGroupEvent{
197 Action: event.ApplyAction,
198 GroupName: "apply-1",
199 Type: event.Finished,
200 },
201 },
202 {
203
204 EventType: event.ActionGroupType,
205 ActionGroupEvent: &testutil.ExpActionGroupEvent{
206 Action: event.WaitAction,
207 GroupName: "wait-1",
208 Type: event.Started,
209 },
210 },
211 {
212
213 EventType: event.WaitType,
214 WaitEvent: &testutil.ExpWaitEvent{
215 GroupName: "wait-1",
216 Status: event.ReconcilePending,
217 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
218 },
219 },
220 {
221
222 EventType: event.WaitType,
223 WaitEvent: &testutil.ExpWaitEvent{
224 GroupName: "wait-1",
225 Status: event.ReconcileSuccessful,
226 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
227 },
228 },
229 {
230
231 EventType: event.ActionGroupType,
232 ActionGroupEvent: &testutil.ExpActionGroupEvent{
233 Action: event.WaitAction,
234 GroupName: "wait-1",
235 Type: event.Finished,
236 },
237 },
238 {
239
240 EventType: event.ActionGroupType,
241 ActionGroupEvent: &testutil.ExpActionGroupEvent{
242 Action: event.ApplyAction,
243 GroupName: "apply-2",
244 Type: event.Started,
245 },
246 },
247 {
248
249 EventType: event.ApplyType,
250 ApplyEvent: &testutil.ExpApplyEvent{
251 GroupName: "apply-2",
252 Status: event.ApplySuccessful,
253 Identifier: object.UnstructuredToObjMetadata(pod3Obj),
254 Error: nil,
255 },
256 },
257 {
258
259 EventType: event.ActionGroupType,
260 ActionGroupEvent: &testutil.ExpActionGroupEvent{
261 Action: event.ApplyAction,
262 GroupName: "apply-2",
263 Type: event.Finished,
264 },
265 },
266 {
267
268 EventType: event.ActionGroupType,
269 ActionGroupEvent: &testutil.ExpActionGroupEvent{
270 Action: event.WaitAction,
271 GroupName: "wait-2",
272 Type: event.Started,
273 },
274 },
275 {
276
277 EventType: event.WaitType,
278 WaitEvent: &testutil.ExpWaitEvent{
279 GroupName: "wait-2",
280 Status: event.ReconcilePending,
281 Identifier: object.UnstructuredToObjMetadata(pod3Obj),
282 },
283 },
284 {
285
286 EventType: event.WaitType,
287 WaitEvent: &testutil.ExpWaitEvent{
288 GroupName: "wait-2",
289 Status: event.ReconcileSuccessful,
290 Identifier: object.UnstructuredToObjMetadata(pod3Obj),
291 },
292 },
293 {
294
295 EventType: event.ActionGroupType,
296 ActionGroupEvent: &testutil.ExpActionGroupEvent{
297 Action: event.WaitAction,
298 GroupName: "wait-2",
299 Type: event.Finished,
300 },
301 },
302 {
303
304 EventType: event.ActionGroupType,
305 ActionGroupEvent: &testutil.ExpActionGroupEvent{
306 Action: event.ApplyAction,
307 GroupName: "apply-3",
308 Type: event.Started,
309 },
310 },
311 {
312
313 EventType: event.ApplyType,
314 ApplyEvent: &testutil.ExpApplyEvent{
315 GroupName: "apply-3",
316 Status: event.ApplySuccessful,
317 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
318 Error: nil,
319 },
320 },
321 {
322
323 EventType: event.ActionGroupType,
324 ActionGroupEvent: &testutil.ExpActionGroupEvent{
325 Action: event.ApplyAction,
326 GroupName: "apply-3",
327 Type: event.Finished,
328 },
329 },
330 {
331
332 EventType: event.ActionGroupType,
333 ActionGroupEvent: &testutil.ExpActionGroupEvent{
334 Action: event.WaitAction,
335 GroupName: "wait-3",
336 Type: event.Started,
337 },
338 },
339 {
340
341 EventType: event.WaitType,
342 WaitEvent: &testutil.ExpWaitEvent{
343 GroupName: "wait-3",
344 Status: event.ReconcilePending,
345 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
346 },
347 },
348 {
349
350 EventType: event.WaitType,
351 WaitEvent: &testutil.ExpWaitEvent{
352 GroupName: "wait-3",
353 Status: event.ReconcileSuccessful,
354 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
355 },
356 },
357 {
358
359 EventType: event.ActionGroupType,
360 ActionGroupEvent: &testutil.ExpActionGroupEvent{
361 Action: event.WaitAction,
362 GroupName: "wait-3",
363 Type: event.Finished,
364 },
365 },
366 {
367
368 EventType: event.ActionGroupType,
369 ActionGroupEvent: &testutil.ExpActionGroupEvent{
370 Action: event.InventoryAction,
371 GroupName: "inventory-set-0",
372 Type: event.Started,
373 },
374 },
375 {
376
377 EventType: event.ActionGroupType,
378 ActionGroupEvent: &testutil.ExpActionGroupEvent{
379 Action: event.InventoryAction,
380 GroupName: "inventory-set-0",
381 Type: event.Finished,
382 },
383 },
384 }
385 receivedEvents := testutil.EventsToExpEvents(applierEvents)
386
387 expEvents, receivedEvents = e2eutil.FilterOptionalEvents(expEvents, receivedEvents)
388
389
390 testutil.SortExpEvents(receivedEvents)
391
392 Expect(receivedEvents).To(testutil.Equal(expEvents))
393
394 By("verify namespace1 created")
395 e2eutil.AssertUnstructuredExists(ctx, c, namespace1Obj)
396
397 By("verify namespace2 created")
398 e2eutil.AssertUnstructuredExists(ctx, c, namespace2Obj)
399
400 By("verify pod1 created and ready")
401 result := e2eutil.AssertUnstructuredExists(ctx, c, pod1Obj)
402 podIP, found, err := object.NestedField(result.Object, "status", "podIP")
403 Expect(err).NotTo(HaveOccurred())
404 Expect(found).To(BeTrue())
405 Expect(podIP).NotTo(BeEmpty())
406
407 By("verify pod2 created and ready")
408 result = e2eutil.AssertUnstructuredExists(ctx, c, pod2Obj)
409 podIP, found, err = object.NestedField(result.Object, "status", "podIP")
410 Expect(err).NotTo(HaveOccurred())
411 Expect(found).To(BeTrue())
412 Expect(podIP).NotTo(BeEmpty())
413
414 By("verify pod3 created and ready")
415 result = e2eutil.AssertUnstructuredExists(ctx, c, pod3Obj)
416 podIP, found, err = object.NestedField(result.Object, "status", "podIP")
417 Expect(err).NotTo(HaveOccurred())
418 Expect(found).To(BeTrue())
419 Expect(podIP).NotTo(BeEmpty())
420
421 By("destroy resources in opposite order")
422 destroyer := invConfig.DestroyerFactoryFunc()
423 options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
424 destroyerEvents := e2eutil.RunCollect(destroyer.Run(ctx, inv, options))
425
426 expEvents = []testutil.ExpEvent{
427 {
428
429 EventType: event.InitType,
430 InitEvent: &testutil.ExpInitEvent{},
431 },
432 {
433
434 EventType: event.ActionGroupType,
435 ActionGroupEvent: &testutil.ExpActionGroupEvent{
436 Action: event.DeleteAction,
437 GroupName: "prune-0",
438 Type: event.Started,
439 },
440 },
441 {
442
443 EventType: event.DeleteType,
444 DeleteEvent: &testutil.ExpDeleteEvent{
445 GroupName: "prune-0",
446 Status: event.DeleteSuccessful,
447 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
448 Error: nil,
449 },
450 },
451 {
452
453 EventType: event.ActionGroupType,
454 ActionGroupEvent: &testutil.ExpActionGroupEvent{
455 Action: event.DeleteAction,
456 GroupName: "prune-0",
457 Type: event.Finished,
458 },
459 },
460 {
461
462 EventType: event.ActionGroupType,
463 ActionGroupEvent: &testutil.ExpActionGroupEvent{
464 Action: event.WaitAction,
465 GroupName: "wait-0",
466 Type: event.Started,
467 },
468 },
469 {
470
471 EventType: event.WaitType,
472 WaitEvent: &testutil.ExpWaitEvent{
473 GroupName: "wait-0",
474 Status: event.ReconcilePending,
475 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
476 },
477 },
478 {
479
480 EventType: event.WaitType,
481 WaitEvent: &testutil.ExpWaitEvent{
482 GroupName: "wait-0",
483 Status: event.ReconcileSuccessful,
484 Identifier: object.UnstructuredToObjMetadata(pod1Obj),
485 },
486 },
487 {
488
489 EventType: event.ActionGroupType,
490 ActionGroupEvent: &testutil.ExpActionGroupEvent{
491 Action: event.WaitAction,
492 GroupName: "wait-0",
493 Type: event.Finished,
494 },
495 },
496 {
497
498 EventType: event.ActionGroupType,
499 ActionGroupEvent: &testutil.ExpActionGroupEvent{
500 Action: event.DeleteAction,
501 GroupName: "prune-1",
502 Type: event.Started,
503 },
504 },
505 {
506
507 EventType: event.DeleteType,
508 DeleteEvent: &testutil.ExpDeleteEvent{
509 GroupName: "prune-1",
510 Status: event.DeleteSuccessful,
511 Identifier: object.UnstructuredToObjMetadata(pod3Obj),
512 Error: nil,
513 },
514 },
515 {
516
517 EventType: event.ActionGroupType,
518 ActionGroupEvent: &testutil.ExpActionGroupEvent{
519 Action: event.DeleteAction,
520 GroupName: "prune-1",
521 Type: event.Finished,
522 },
523 },
524 {
525
526 EventType: event.ActionGroupType,
527 ActionGroupEvent: &testutil.ExpActionGroupEvent{
528 Action: event.WaitAction,
529 GroupName: "wait-1",
530 Type: event.Started,
531 },
532 },
533 {
534
535 EventType: event.WaitType,
536 WaitEvent: &testutil.ExpWaitEvent{
537 GroupName: "wait-1",
538 Status: event.ReconcilePending,
539 Identifier: object.UnstructuredToObjMetadata(pod3Obj),
540 },
541 },
542 {
543
544 EventType: event.WaitType,
545 WaitEvent: &testutil.ExpWaitEvent{
546 GroupName: "wait-1",
547 Status: event.ReconcileSuccessful,
548 Identifier: object.UnstructuredToObjMetadata(pod3Obj),
549 },
550 },
551 {
552
553 EventType: event.ActionGroupType,
554 ActionGroupEvent: &testutil.ExpActionGroupEvent{
555 Action: event.WaitAction,
556 GroupName: "wait-1",
557 Type: event.Finished,
558 },
559 },
560 {
561
562 EventType: event.ActionGroupType,
563 ActionGroupEvent: &testutil.ExpActionGroupEvent{
564 Action: event.DeleteAction,
565 GroupName: "prune-2",
566 Type: event.Started,
567 },
568 },
569 {
570
571 EventType: event.DeleteType,
572 DeleteEvent: &testutil.ExpDeleteEvent{
573 GroupName: "prune-2",
574 Status: event.DeleteSuccessful,
575 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
576 Error: nil,
577 },
578 },
579 {
580
581 EventType: event.ActionGroupType,
582 ActionGroupEvent: &testutil.ExpActionGroupEvent{
583 Action: event.DeleteAction,
584 GroupName: "prune-2",
585 Type: event.Finished,
586 },
587 },
588 {
589
590 EventType: event.ActionGroupType,
591 ActionGroupEvent: &testutil.ExpActionGroupEvent{
592 Action: event.WaitAction,
593 GroupName: "wait-2",
594 Type: event.Started,
595 },
596 },
597 {
598
599 EventType: event.WaitType,
600 WaitEvent: &testutil.ExpWaitEvent{
601 GroupName: "wait-2",
602 Status: event.ReconcilePending,
603 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
604 },
605 },
606 {
607
608 EventType: event.WaitType,
609 WaitEvent: &testutil.ExpWaitEvent{
610 GroupName: "wait-2",
611 Status: event.ReconcileSuccessful,
612 Identifier: object.UnstructuredToObjMetadata(pod2Obj),
613 },
614 },
615 {
616
617 EventType: event.ActionGroupType,
618 ActionGroupEvent: &testutil.ExpActionGroupEvent{
619 Action: event.WaitAction,
620 GroupName: "wait-2",
621 Type: event.Finished,
622 },
623 },
624 {
625
626 EventType: event.ActionGroupType,
627 ActionGroupEvent: &testutil.ExpActionGroupEvent{
628 Action: event.DeleteAction,
629 GroupName: "prune-3",
630 Type: event.Started,
631 },
632 },
633 {
634
635 EventType: event.DeleteType,
636 DeleteEvent: &testutil.ExpDeleteEvent{
637 GroupName: "prune-3",
638 Status: event.DeleteSuccessful,
639 Identifier: object.UnstructuredToObjMetadata(namespace2Obj),
640 },
641 },
642 {
643
644 EventType: event.DeleteType,
645 DeleteEvent: &testutil.ExpDeleteEvent{
646 GroupName: "prune-3",
647 Status: event.DeleteSuccessful,
648 Identifier: object.UnstructuredToObjMetadata(namespace1Obj),
649 },
650 },
651 {
652
653 EventType: event.ActionGroupType,
654 ActionGroupEvent: &testutil.ExpActionGroupEvent{
655 Action: event.DeleteAction,
656 GroupName: "prune-3",
657 Type: event.Finished,
658 },
659 },
660 {
661
662 EventType: event.ActionGroupType,
663 ActionGroupEvent: &testutil.ExpActionGroupEvent{
664 Action: event.WaitAction,
665 GroupName: "wait-3",
666 Type: event.Started,
667 },
668 },
669 {
670
671 EventType: event.WaitType,
672 WaitEvent: &testutil.ExpWaitEvent{
673 GroupName: "wait-3",
674 Status: event.ReconcilePending,
675 Identifier: object.UnstructuredToObjMetadata(namespace1Obj),
676 },
677 },
678 {
679
680 EventType: event.WaitType,
681 WaitEvent: &testutil.ExpWaitEvent{
682 GroupName: "wait-3",
683 Status: event.ReconcilePending,
684 Identifier: object.UnstructuredToObjMetadata(namespace2Obj),
685 },
686 },
687 {
688
689 EventType: event.WaitType,
690 WaitEvent: &testutil.ExpWaitEvent{
691 GroupName: "wait-3",
692 Status: event.ReconcileSuccessful,
693 Identifier: object.UnstructuredToObjMetadata(namespace1Obj),
694 },
695 },
696 {
697
698 EventType: event.WaitType,
699 WaitEvent: &testutil.ExpWaitEvent{
700 GroupName: "wait-3",
701 Status: event.ReconcileSuccessful,
702 Identifier: object.UnstructuredToObjMetadata(namespace2Obj),
703 },
704 },
705 {
706
707 EventType: event.ActionGroupType,
708 ActionGroupEvent: &testutil.ExpActionGroupEvent{
709 Action: event.WaitAction,
710 GroupName: "wait-3",
711 Type: event.Finished,
712 },
713 },
714 {
715
716 EventType: event.ActionGroupType,
717 ActionGroupEvent: &testutil.ExpActionGroupEvent{
718 Action: event.InventoryAction,
719 GroupName: "delete-inventory-0",
720 Type: event.Started,
721 },
722 },
723 {
724
725 EventType: event.ActionGroupType,
726 ActionGroupEvent: &testutil.ExpActionGroupEvent{
727 Action: event.InventoryAction,
728 GroupName: "delete-inventory-0",
729 Type: event.Finished,
730 },
731 },
732 }
733 receivedEvents = testutil.EventsToExpEvents(destroyerEvents)
734
735 expEvents, receivedEvents = e2eutil.FilterOptionalEvents(expEvents, receivedEvents)
736
737
738 testutil.SortExpEvents(receivedEvents)
739
740 Expect(receivedEvents).To(testutil.Equal(expEvents))
741
742 By("verify pod1 deleted")
743 e2eutil.AssertUnstructuredDoesNotExist(ctx, c, pod1Obj)
744
745 By("verify pod2 deleted")
746 e2eutil.AssertUnstructuredDoesNotExist(ctx, c, pod2Obj)
747
748 By("verify pod3 deleted")
749 e2eutil.AssertUnstructuredDoesNotExist(ctx, c, pod3Obj)
750
751 By("verify namespace1 deleted")
752 e2eutil.AssertUnstructuredDoesNotExist(ctx, c, namespace1Obj)
753
754 By("verify namespace2 deleted")
755 e2eutil.AssertUnstructuredDoesNotExist(ctx, c, namespace2Obj)
756 }
757
View as plain text