1
2
3
4 package e2e
5
6 import (
7 "context"
8 "strings"
9 "time"
10
11 . "github.com/onsi/ginkgo/v2"
12 . "github.com/onsi/gomega"
13 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14 "sigs.k8s.io/cli-utils/pkg/apply"
15 "sigs.k8s.io/cli-utils/pkg/apply/event"
16 "sigs.k8s.io/cli-utils/pkg/inventory"
17 "sigs.k8s.io/cli-utils/pkg/object"
18 "sigs.k8s.io/cli-utils/pkg/testutil"
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 func crdTest(ctx context.Context, _ client.Client, invConfig invconfig.InventoryConfig, inventoryName, namespaceName string) {
26 By("apply a set of resources that includes both a crd and a cr")
27 applier := invConfig.ApplierFactoryFunc()
28
29 inv := invConfig.InvWrapperFunc(invConfig.FactoryFunc(inventoryName, namespaceName, "test"))
30
31 crdObj := e2eutil.ManifestToUnstructured(crd)
32 crObj := e2eutil.ManifestToUnstructured(cr)
33
34 resources := []*unstructured.Unstructured{
35 crObj,
36 crdObj,
37 }
38
39 applierEvents := e2eutil.RunCollect(applier.Run(ctx, inv, resources, apply.ApplierOptions{
40 ReconcileTimeout: 2 * time.Minute,
41 EmitStatusEvents: false,
42 }))
43
44 expEvents := []testutil.ExpEvent{
45 {
46
47 EventType: event.InitType,
48 InitEvent: &testutil.ExpInitEvent{},
49 },
50 {
51
52 EventType: event.ActionGroupType,
53 ActionGroupEvent: &testutil.ExpActionGroupEvent{
54 Action: event.InventoryAction,
55 GroupName: "inventory-add-0",
56 Type: event.Started,
57 },
58 },
59 {
60
61 EventType: event.ActionGroupType,
62 ActionGroupEvent: &testutil.ExpActionGroupEvent{
63 Action: event.InventoryAction,
64 GroupName: "inventory-add-0",
65 Type: event.Finished,
66 },
67 },
68 {
69
70 EventType: event.ActionGroupType,
71 ActionGroupEvent: &testutil.ExpActionGroupEvent{
72 Action: event.ApplyAction,
73 GroupName: "apply-0",
74 Type: event.Started,
75 },
76 },
77 {
78
79 EventType: event.ApplyType,
80 ApplyEvent: &testutil.ExpApplyEvent{
81 GroupName: "apply-0",
82 Status: event.ApplySuccessful,
83 Identifier: object.UnstructuredToObjMetadata(crdObj),
84 Error: nil,
85 },
86 },
87 {
88
89 EventType: event.ActionGroupType,
90 ActionGroupEvent: &testutil.ExpActionGroupEvent{
91 Action: event.ApplyAction,
92 GroupName: "apply-0",
93 Type: event.Finished,
94 },
95 },
96 {
97
98 EventType: event.ActionGroupType,
99 ActionGroupEvent: &testutil.ExpActionGroupEvent{
100 Action: event.WaitAction,
101 GroupName: "wait-0",
102 Type: event.Started,
103 },
104 },
105 {
106
107 EventType: event.WaitType,
108 WaitEvent: &testutil.ExpWaitEvent{
109 GroupName: "wait-0",
110 Status: event.ReconcilePending,
111 Identifier: object.UnstructuredToObjMetadata(crdObj),
112 },
113 },
114 {
115
116 EventType: event.WaitType,
117 WaitEvent: &testutil.ExpWaitEvent{
118 GroupName: "wait-0",
119 Status: event.ReconcileSuccessful,
120 Identifier: object.UnstructuredToObjMetadata(crdObj),
121 },
122 },
123 {
124
125 EventType: event.ActionGroupType,
126 ActionGroupEvent: &testutil.ExpActionGroupEvent{
127 Action: event.WaitAction,
128 GroupName: "wait-0",
129 Type: event.Finished,
130 },
131 },
132 {
133
134 EventType: event.ActionGroupType,
135 ActionGroupEvent: &testutil.ExpActionGroupEvent{
136 Action: event.ApplyAction,
137 GroupName: "apply-1",
138 Type: event.Started,
139 },
140 },
141 {
142
143 EventType: event.ApplyType,
144 ApplyEvent: &testutil.ExpApplyEvent{
145 GroupName: "apply-1",
146 Status: event.ApplySuccessful,
147 Identifier: object.UnstructuredToObjMetadata(crObj),
148 Error: nil,
149 },
150 },
151 {
152
153 EventType: event.ActionGroupType,
154 ActionGroupEvent: &testutil.ExpActionGroupEvent{
155 Action: event.ApplyAction,
156 GroupName: "apply-1",
157 Type: event.Finished,
158 },
159 },
160 {
161
162 EventType: event.ActionGroupType,
163 ActionGroupEvent: &testutil.ExpActionGroupEvent{
164 Action: event.WaitAction,
165 GroupName: "wait-1",
166 Type: event.Started,
167 },
168 },
169 {
170
171 EventType: event.WaitType,
172 WaitEvent: &testutil.ExpWaitEvent{
173 GroupName: "wait-1",
174 Status: event.ReconcilePending,
175 Identifier: object.UnstructuredToObjMetadata(crObj),
176 },
177 },
178 {
179
180 EventType: event.WaitType,
181 WaitEvent: &testutil.ExpWaitEvent{
182 GroupName: "wait-1",
183 Status: event.ReconcileSuccessful,
184 Identifier: object.UnstructuredToObjMetadata(crObj),
185 },
186 },
187 {
188
189 EventType: event.ActionGroupType,
190 ActionGroupEvent: &testutil.ExpActionGroupEvent{
191 Action: event.WaitAction,
192 GroupName: "wait-1",
193 Type: event.Finished,
194 },
195 },
196 {
197
198 EventType: event.ActionGroupType,
199 ActionGroupEvent: &testutil.ExpActionGroupEvent{
200 Action: event.InventoryAction,
201 GroupName: "inventory-set-0",
202 Type: event.Started,
203 },
204 },
205 {
206
207 EventType: event.ActionGroupType,
208 ActionGroupEvent: &testutil.ExpActionGroupEvent{
209 Action: event.InventoryAction,
210 GroupName: "inventory-set-0",
211 Type: event.Finished,
212 },
213 },
214 }
215 receivedEvents := testutil.EventsToExpEvents(applierEvents)
216
217 expEvents, receivedEvents = e2eutil.FilterOptionalEvents(expEvents, receivedEvents)
218
219 Expect(receivedEvents).To(testutil.Equal(expEvents))
220
221 By("destroy the resources, including the crd")
222 destroyer := invConfig.DestroyerFactoryFunc()
223 options := apply.DestroyerOptions{InventoryPolicy: inventory.PolicyAdoptIfNoInventory}
224 destroyerEvents := e2eutil.RunCollect(destroyer.Run(ctx, inv, options))
225
226 expEvents = []testutil.ExpEvent{
227 {
228
229 EventType: event.InitType,
230 InitEvent: &testutil.ExpInitEvent{},
231 },
232 {
233
234 EventType: event.ActionGroupType,
235 ActionGroupEvent: &testutil.ExpActionGroupEvent{
236 Action: event.DeleteAction,
237 GroupName: "prune-0",
238 Type: event.Started,
239 },
240 },
241 {
242
243 EventType: event.DeleteType,
244 DeleteEvent: &testutil.ExpDeleteEvent{
245 GroupName: "prune-0",
246 Status: event.DeleteSuccessful,
247 Identifier: object.UnstructuredToObjMetadata(crObj),
248 Error: nil,
249 },
250 },
251 {
252
253 EventType: event.ActionGroupType,
254 ActionGroupEvent: &testutil.ExpActionGroupEvent{
255 Action: event.DeleteAction,
256 GroupName: "prune-0",
257 Type: event.Finished,
258 },
259 },
260 {
261
262 EventType: event.ActionGroupType,
263 ActionGroupEvent: &testutil.ExpActionGroupEvent{
264 Action: event.WaitAction,
265 GroupName: "wait-0",
266 Type: event.Started,
267 },
268 },
269 {
270
271 EventType: event.WaitType,
272 WaitEvent: &testutil.ExpWaitEvent{
273 GroupName: "wait-0",
274 Status: event.ReconcilePending,
275 Identifier: object.UnstructuredToObjMetadata(crObj),
276 },
277 },
278 {
279
280 EventType: event.WaitType,
281 WaitEvent: &testutil.ExpWaitEvent{
282 GroupName: "wait-0",
283 Status: event.ReconcileSuccessful,
284 Identifier: object.UnstructuredToObjMetadata(crObj),
285 },
286 },
287 {
288
289 EventType: event.ActionGroupType,
290 ActionGroupEvent: &testutil.ExpActionGroupEvent{
291 Action: event.WaitAction,
292 GroupName: "wait-0",
293 Type: event.Finished,
294 },
295 },
296 {
297
298 EventType: event.ActionGroupType,
299 ActionGroupEvent: &testutil.ExpActionGroupEvent{
300 Action: event.DeleteAction,
301 GroupName: "prune-1",
302 Type: event.Started,
303 },
304 },
305 {
306
307 EventType: event.DeleteType,
308 DeleteEvent: &testutil.ExpDeleteEvent{
309 GroupName: "prune-1",
310 Status: event.DeleteSuccessful,
311 Identifier: object.UnstructuredToObjMetadata(crdObj),
312 Error: nil,
313 },
314 },
315 {
316
317 EventType: event.ActionGroupType,
318 ActionGroupEvent: &testutil.ExpActionGroupEvent{
319 Action: event.DeleteAction,
320 GroupName: "prune-1",
321 Type: event.Finished,
322 },
323 },
324 {
325
326 EventType: event.ActionGroupType,
327 ActionGroupEvent: &testutil.ExpActionGroupEvent{
328 Action: event.WaitAction,
329 GroupName: "wait-1",
330 Type: event.Started,
331 },
332 },
333 {
334
335 EventType: event.WaitType,
336 WaitEvent: &testutil.ExpWaitEvent{
337 GroupName: "wait-1",
338 Status: event.ReconcilePending,
339 Identifier: object.UnstructuredToObjMetadata(crdObj),
340 },
341 },
342 {
343
344 EventType: event.WaitType,
345 WaitEvent: &testutil.ExpWaitEvent{
346 GroupName: "wait-1",
347 Status: event.ReconcileSuccessful,
348 Identifier: object.UnstructuredToObjMetadata(crdObj),
349 },
350 },
351 {
352
353 EventType: event.ActionGroupType,
354 ActionGroupEvent: &testutil.ExpActionGroupEvent{
355 Action: event.WaitAction,
356 GroupName: "wait-1",
357 Type: event.Finished,
358 },
359 },
360 {
361
362 EventType: event.ActionGroupType,
363 ActionGroupEvent: &testutil.ExpActionGroupEvent{
364 Action: event.InventoryAction,
365 GroupName: "delete-inventory-0",
366 Type: event.Started,
367 },
368 },
369 {
370
371 EventType: event.ActionGroupType,
372 ActionGroupEvent: &testutil.ExpActionGroupEvent{
373 Action: event.InventoryAction,
374 GroupName: "delete-inventory-0",
375 Type: event.Finished,
376 },
377 },
378 }
379 receivedEvents = testutil.EventsToExpEvents(destroyerEvents)
380
381 expEvents, receivedEvents = e2eutil.FilterOptionalEvents(expEvents, receivedEvents)
382
383 Expect(receivedEvents).To(testutil.Equal(expEvents))
384 }
385
386 var crd = []byte(strings.TrimSpace(`
387 apiVersion: apiextensions.k8s.io/v1
388 kind: CustomResourceDefinition
389 metadata:
390 name: examples.cli-utils.example.io
391 spec:
392 conversion:
393 strategy: None
394 group: cli-utils.example.io
395 names:
396 kind: Example
397 listKind: ExampleList
398 plural: examples
399 singular: example
400 scope: Cluster
401 versions:
402 - name: v1alpha1
403 schema:
404 openAPIV3Schema:
405 description: Example for cli-utils e2e tests
406 properties:
407 apiVersion:
408 type: string
409 kind:
410 type: string
411 metadata:
412 type: object
413 spec:
414 description: Example for cli-utils e2e tests
415 properties:
416 replicas:
417 description: Number of replicas
418 type: integer
419 required:
420 - replicas
421 type: object
422 type: object
423 served: true
424 storage: true
425 subresources: {}
426 `))
427
428 var cr = []byte(strings.TrimSpace(`
429 apiVersion: cli-utils.example.io/v1alpha1
430 kind: Example
431 metadata:
432 name: example-cr
433 spec:
434 replicas: 4
435 `))
436
View as plain text