1
2
3
4 package stress
5
6 import (
7 "context"
8 "fmt"
9 "time"
10
11 . "github.com/onsi/ginkgo/v2"
12 . "github.com/onsi/gomega"
13 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14 "k8s.io/klog/v2"
15 "sigs.k8s.io/cli-utils/pkg/apply"
16 "sigs.k8s.io/cli-utils/pkg/apply/event"
17 "sigs.k8s.io/cli-utils/pkg/common"
18 "sigs.k8s.io/cli-utils/pkg/inventory"
19 "sigs.k8s.io/cli-utils/test/e2e/e2eutil"
20 "sigs.k8s.io/cli-utils/test/e2e/invconfig"
21 "sigs.k8s.io/controller-runtime/pkg/client"
22 )
23
24
25
26
27
28
29
30
31
32
33 func thousandNamespacesTest(ctx context.Context, c client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) {
34 By("Apply LOTS of resources")
35 applier := invConfig.ApplierFactoryFunc()
36 inventoryID := fmt.Sprintf("%s-%s", inventoryName, namespaceName)
37
38 inventoryInfo := invconfig.CreateInventoryInfo(invConfig, inventoryName, namespaceName, inventoryID)
39
40 crdObj := e2eutil.ManifestToUnstructured([]byte(cronTabCRDYaml))
41
42 resources := []*unstructured.Unstructured{crdObj}
43
44 namespaceObjTemplate := e2eutil.ManifestToUnstructured([]byte(namespaceYaml))
45 namespaceObjTemplate.SetLabels(map[string]string{e2eutil.TestIDLabel: inventoryID})
46
47 configMapObjTemplate := e2eutil.ManifestToUnstructured([]byte(configMapYaml))
48 configMapObjTemplate.SetLabels(map[string]string{e2eutil.TestIDLabel: inventoryID})
49
50 cronTabObjTemplate := e2eutil.ManifestToUnstructured([]byte(cronTabYaml))
51 cronTabObjTemplate.SetLabels(map[string]string{e2eutil.TestIDLabel: inventoryID})
52
53 objectCount := 1000
54
55 for i := 1; i <= objectCount; i++ {
56 ns := fmt.Sprintf("%s-%d", namespaceName, i)
57 namespaceObj := namespaceObjTemplate.DeepCopy()
58 namespaceObj.SetName(ns)
59 resources = append(resources, namespaceObj)
60
61 configMapObj := configMapObjTemplate.DeepCopy()
62 configMapObj.SetName(fmt.Sprintf("configmap-%d", i))
63 configMapObj.SetNamespace(ns)
64 resources = append(resources, configMapObj)
65
66 cronTabObj := cronTabObjTemplate.DeepCopy()
67 cronTabObj.SetName(fmt.Sprintf("crontab-%d", i))
68 cronTabObj.SetNamespace(ns)
69 resources = append(resources, cronTabObj)
70 }
71
72 defer func() {
73
74 if e2eutil.UnstructuredExistsAndIsNotTerminating(ctx, c, crdObj) {
75 By("Cleanup CronTabs")
76 e2eutil.DeleteAllUnstructuredIfExists(ctx, c, cronTabObjTemplate)
77 By("Cleanup CRD")
78 e2eutil.DeleteUnstructuredIfExists(ctx, c, crdObj)
79 }
80
81 By("Cleanup ConfigMaps")
82 e2eutil.DeleteAllUnstructuredIfExists(ctx, c, configMapObjTemplate)
83 By("Cleanup Namespaces")
84 e2eutil.DeleteAllUnstructuredIfExists(ctx, c, namespaceObjTemplate)
85 }()
86
87 start := time.Now()
88
89 applierEvents := e2eutil.RunCollect(applier.Run(ctx, inventoryInfo, resources, apply.ApplierOptions{
90
91 ServerSideOptions: common.ServerSideOptions{
92 ServerSideApply: true,
93 ForceConflicts: true,
94 FieldManager: "cli-utils.kubernetes.io",
95 },
96 ReconcileTimeout: 30 * time.Minute,
97 EmitStatusEvents: false,
98 }))
99
100 duration := time.Since(start)
101 klog.Infof("Applier.Run execution time: %v", duration)
102
103 for _, e := range applierEvents {
104 Expect(e.ErrorEvent.Err).To(BeNil())
105 }
106 for _, e := range applierEvents {
107 Expect(e.ApplyEvent.Error).To(BeNil(), "ApplyEvent: %v", e.ApplyEvent)
108 }
109 for _, e := range applierEvents {
110 if e.Type == event.WaitType {
111 Expect(e.WaitEvent.Status).To(BeElementOf(event.ReconcilePending, event.ReconcileSuccessful), "WaitEvent: %v", e.WaitEvent)
112 }
113 }
114
115 By("Verify inventory created")
116 invConfig.InvSizeVerifyFunc(ctx, c, inventoryName, namespaceName, inventoryID, len(resources), len(resources))
117
118 By("Verify CRD created")
119 e2eutil.AssertUnstructuredExists(ctx, c, crdObj)
120
121 By(fmt.Sprintf("Verify %d Namespaces created", objectCount))
122 e2eutil.AssertUnstructuredCount(ctx, c, namespaceObjTemplate, objectCount)
123
124 By(fmt.Sprintf("Verify %d ConfigMaps created", objectCount))
125 e2eutil.AssertUnstructuredCount(ctx, c, configMapObjTemplate, objectCount)
126
127 By(fmt.Sprintf("Verify %d CronTabs created", objectCount))
128 e2eutil.AssertUnstructuredCount(ctx, c, cronTabObjTemplate, objectCount)
129
130 By("Destroy LOTS of resources")
131 destroyer := invConfig.DestroyerFactoryFunc()
132
133 start = time.Now()
134
135 destroyerEvents := e2eutil.RunCollect(destroyer.Run(ctx, inventoryInfo, apply.DestroyerOptions{
136 InventoryPolicy: inventory.PolicyAdoptIfNoInventory,
137 DeleteTimeout: 30 * time.Minute,
138 }))
139
140 duration = time.Since(start)
141 klog.Infof("Destroyer.Run execution time: %v", duration)
142
143 for _, e := range destroyerEvents {
144 Expect(e.ErrorEvent.Err).To(BeNil())
145 }
146 for _, e := range destroyerEvents {
147 Expect(e.PruneEvent.Error).To(BeNil(), "PruneEvent: %v", e.PruneEvent)
148 }
149 for _, e := range destroyerEvents {
150 if e.Type == event.WaitType {
151 Expect(e.WaitEvent.Status).To(BeElementOf(event.ReconcilePending, event.ReconcileSuccessful), "WaitEvent: %v", e.WaitEvent)
152 }
153 }
154
155 By("Verify inventory deleted")
156 invConfig.InvNotExistsFunc(ctx, c, inventoryName, namespaceName, inventoryID)
157
158 By(fmt.Sprintf("Verify %d CronTabs deleted", objectCount))
159 e2eutil.AssertUnstructuredCount(ctx, c, cronTabObjTemplate, 0)
160
161 By(fmt.Sprintf("Verify %d ConfigMaps deleted", objectCount))
162 e2eutil.AssertUnstructuredCount(ctx, c, configMapObjTemplate, 0)
163
164 By(fmt.Sprintf("Verify %d Namespaces deleted", objectCount))
165 e2eutil.AssertUnstructuredCount(ctx, c, namespaceObjTemplate, 0)
166
167 By("Verify CRD deleted")
168 e2eutil.AssertUnstructuredDoesNotExist(ctx, c, crdObj)
169 }
170
View as plain text