1
16
17 package merge_test
18
19 import (
20 "testing"
21
22 "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
23 . "sigs.k8s.io/structured-merge-diff/v4/internal/fixture"
24 "sigs.k8s.io/structured-merge-diff/v4/typed"
25 )
26
27 var nestedTypeParser = func() Parser {
28 parser, err := typed.NewParser(`types:
29 - name: type
30 map:
31 fields:
32 - name: listOfLists
33 type:
34 namedType: listOfLists
35 - name: listOfMaps
36 type:
37 namedType: listOfMaps
38 - name: mapOfLists
39 type:
40 namedType: mapOfLists
41 - name: mapOfMaps
42 type:
43 namedType: mapOfMaps
44 - name: mapOfMapsRecursive
45 type:
46 namedType: mapOfMapsRecursive
47 - name: struct
48 type:
49 namedType: struct
50 - name: struct
51 map:
52 fields:
53 - name: name
54 type:
55 scalar: string
56 - name: value
57 type:
58 scalar: numeric
59 - name: listOfLists
60 list:
61 elementType:
62 map:
63 fields:
64 - name: name
65 type:
66 scalar: string
67 - name: value
68 type:
69 namedType: list
70 elementRelationship: associative
71 keys:
72 - name
73 - name: list
74 list:
75 elementType:
76 scalar: string
77 elementRelationship: associative
78 - name: listOfMaps
79 list:
80 elementType:
81 map:
82 fields:
83 - name: name
84 type:
85 scalar: string
86 - name: value
87 type:
88 namedType: map
89 elementRelationship: associative
90 keys:
91 - name
92 - name: map
93 map:
94 elementType:
95 scalar: string
96 elementRelationship: associative
97 - name: mapOfLists
98 map:
99 elementType:
100 namedType: list
101 elementRelationship: associative
102 - name: mapOfMaps
103 map:
104 elementType:
105 namedType: map
106 elementRelationship: associative
107 - name: mapOfMapsRecursive
108 map:
109 elementType:
110 namedType: mapOfMapsRecursive
111 elementRelationship: associative
112 `)
113 if err != nil {
114 panic(err)
115 }
116 return SameVersionParser{T: parser.Type("type")}
117 }()
118
119 func TestUpdateNestedType(t *testing.T) {
120 tests := map[string]TestCase{
121 "listOfLists_change_value": {
122 Ops: []Operation{
123 Apply{
124 Manager: "default",
125 Object: `
126 listOfLists:
127 - name: a
128 value:
129 - b
130 - c
131 `,
132 APIVersion: "v1",
133 },
134 Apply{
135 Manager: "default",
136 Object: `
137 listOfLists:
138 - name: a
139 value:
140 - a
141 - c
142 `,
143 APIVersion: "v1",
144 },
145 },
146 Object: `
147 listOfLists:
148 - name: a
149 value:
150 - a
151 - c
152 `,
153 APIVersion: "v1",
154 Managed: fieldpath.ManagedFields{
155 "default": fieldpath.NewVersionedSet(
156 _NS(
157 _P("listOfLists", _KBF("name", "a")),
158 _P("listOfLists", _KBF("name", "a"), "name"),
159 _P("listOfLists", _KBF("name", "a"), "value", _V("a")),
160 _P("listOfLists", _KBF("name", "a"), "value", _V("c")),
161 ),
162 "v1",
163 false,
164 ),
165 },
166 },
167 "listOfLists_change_key_and_value": {
168 Ops: []Operation{
169 Apply{
170 Manager: "default",
171 Object: `
172 listOfLists:
173 - name: a
174 value:
175 - b
176 - c
177 `,
178 APIVersion: "v1",
179 },
180 Apply{
181 Manager: "default",
182 Object: `
183 listOfLists:
184 - name: b
185 value:
186 - a
187 - c
188 `,
189 APIVersion: "v1",
190 },
191 },
192 Object: `
193 listOfLists:
194 - name: b
195 value:
196 - a
197 - c
198 `,
199 APIVersion: "v1",
200 Managed: fieldpath.ManagedFields{
201 "default": fieldpath.NewVersionedSet(
202 _NS(
203 _P("listOfLists", _KBF("name", "b")),
204 _P("listOfLists", _KBF("name", "b"), "name"),
205 _P("listOfLists", _KBF("name", "b"), "value", _V("a")),
206 _P("listOfLists", _KBF("name", "b"), "value", _V("c")),
207 ),
208 "v1",
209 false,
210 ),
211 },
212 },
213 "listOfMaps_change_value": {
214 Ops: []Operation{
215 Apply{
216 Manager: "default",
217 Object: `
218 listOfMaps:
219 - name: a
220 value:
221 b: "x"
222 c: "y"
223 `,
224 APIVersion: "v1",
225 },
226 Apply{
227 Manager: "default",
228 Object: `
229 listOfMaps:
230 - name: a
231 value:
232 a: "x"
233 c: "z"
234 `,
235 APIVersion: "v1",
236 },
237 },
238 Object: `
239 listOfMaps:
240 - name: a
241 value:
242 a: "x"
243 c: "z"
244 `,
245 APIVersion: "v1",
246 Managed: fieldpath.ManagedFields{
247 "default": fieldpath.NewVersionedSet(
248 _NS(
249 _P("listOfMaps", _KBF("name", "a")),
250 _P("listOfMaps", _KBF("name", "a"), "name"),
251 _P("listOfMaps", _KBF("name", "a"), "value", "a"),
252 _P("listOfMaps", _KBF("name", "a"), "value", "c"),
253 ),
254 "v1",
255 true,
256 ),
257 },
258 },
259 "listOfMaps_change_key_and_value": {
260 Ops: []Operation{
261 Apply{
262 Manager: "default",
263 Object: `
264 listOfMaps:
265 - name: a
266 value:
267 b: "x"
268 c: "y"
269 `,
270 APIVersion: "v1",
271 },
272 Apply{
273 Manager: "default",
274 Object: `
275 listOfMaps:
276 - name: b
277 value:
278 a: "x"
279 c: "z"
280 `,
281 APIVersion: "v1",
282 },
283 },
284 Object: `
285 listOfMaps:
286 - name: b
287 value:
288 a: "x"
289 c: "z"
290 `,
291 APIVersion: "v1",
292 Managed: fieldpath.ManagedFields{
293 "default": fieldpath.NewVersionedSet(
294 _NS(
295 _P("listOfMaps", _KBF("name", "b")),
296 _P("listOfMaps", _KBF("name", "b"), "name"),
297 _P("listOfMaps", _KBF("name", "b"), "value", "a"),
298 _P("listOfMaps", _KBF("name", "b"), "value", "c"),
299 ),
300 "v1",
301 false,
302 ),
303 },
304 },
305 "mapOfLists_change_value": {
306 Ops: []Operation{
307 Apply{
308 Manager: "default",
309 Object: `
310 mapOfLists:
311 a:
312 - b
313 - c
314 `,
315 APIVersion: "v1",
316 },
317 Apply{
318 Manager: "default",
319 Object: `
320 mapOfLists:
321 a:
322 - a
323 - c
324 `,
325 APIVersion: "v1",
326 },
327 },
328 Object: `
329 mapOfLists:
330 a:
331 - a
332 - c
333 `,
334 APIVersion: "v1",
335 Managed: fieldpath.ManagedFields{
336 "default": fieldpath.NewVersionedSet(
337 _NS(
338 _P("mapOfLists", "a"),
339 _P("mapOfLists", "a", _V("a")),
340 _P("mapOfLists", "a", _V("c")),
341 ),
342 "v1",
343 true,
344 ),
345 },
346 },
347 "mapOfLists_change_key_and_value": {
348 Ops: []Operation{
349 Apply{
350 Manager: "default",
351 Object: `
352 mapOfLists:
353 a:
354 - b
355 - c
356 `,
357 APIVersion: "v1",
358 },
359 Apply{
360 Manager: "default",
361 Object: `
362 mapOfLists:
363 b:
364 - a
365 - c
366 `,
367 APIVersion: "v1",
368 },
369 },
370 Object: `
371 mapOfLists:
372 b:
373 - a
374 - c
375 `,
376 APIVersion: "v1",
377 Managed: fieldpath.ManagedFields{
378 "default": fieldpath.NewVersionedSet(
379 _NS(
380 _P("mapOfLists", "b"),
381 _P("mapOfLists", "b", _V("a")),
382 _P("mapOfLists", "b", _V("c")),
383 ),
384 "v1",
385 false,
386 ),
387 },
388 },
389 "mapOfMaps_change_value": {
390 Ops: []Operation{
391 Apply{
392 Manager: "default",
393 Object: `
394 mapOfMaps:
395 a:
396 b: "x"
397 c: "y"
398 `,
399 APIVersion: "v1",
400 },
401 Apply{
402 Manager: "default",
403 Object: `
404 mapOfMaps:
405 a:
406 a: "x"
407 c: "z"
408 `,
409 APIVersion: "v1",
410 },
411 },
412 Object: `
413 mapOfMaps:
414 a:
415 a: "x"
416 c: "z"
417 `,
418 APIVersion: "v1",
419 Managed: fieldpath.ManagedFields{
420 "default": fieldpath.NewVersionedSet(
421 _NS(
422 _P("mapOfMaps", "a"),
423 _P("mapOfMaps", "a", "a"),
424 _P("mapOfMaps", "a", "c"),
425 ),
426 "v1",
427 false,
428 ),
429 },
430 },
431 "mapOfMaps_change_key_and_value": {
432 Ops: []Operation{
433 Apply{
434 Manager: "default",
435 Object: `
436 mapOfMaps:
437 a:
438 b: "x"
439 c: "y"
440 `,
441 APIVersion: "v1",
442 },
443 Apply{
444 Manager: "default",
445 Object: `
446 mapOfMaps:
447 b:
448 a: "x"
449 c: "z"
450 `,
451 APIVersion: "v1",
452 },
453 },
454 Object: `
455 mapOfMaps:
456 b:
457 a: "x"
458 c: "z"
459 `,
460 APIVersion: "v1",
461 Managed: fieldpath.ManagedFields{
462 "default": fieldpath.NewVersionedSet(
463 _NS(
464 _P("mapOfMaps", "b"),
465 _P("mapOfMaps", "b", "a"),
466 _P("mapOfMaps", "b", "c"),
467 ),
468 "v1",
469 false,
470 ),
471 },
472 },
473 "mapOfMapsRecursive_change_middle_key": {
474 Ops: []Operation{
475 Apply{
476 Manager: "default",
477 Object: `
478 mapOfMapsRecursive:
479 a:
480 b:
481 c:
482 `,
483 APIVersion: "v1",
484 },
485 Apply{
486 Manager: "default",
487 Object: `
488 mapOfMapsRecursive:
489 a:
490 d:
491 c:
492 `,
493 APIVersion: "v1",
494 },
495 },
496 Object: `
497 mapOfMapsRecursive:
498 a:
499 d:
500 c:
501 `,
502 APIVersion: "v1",
503 Managed: fieldpath.ManagedFields{
504 "default": fieldpath.NewVersionedSet(
505 _NS(
506 _P("mapOfMapsRecursive", "a"),
507 _P("mapOfMapsRecursive", "a", "d"),
508 _P("mapOfMapsRecursive", "a", "d", "c"),
509 ),
510 "v1",
511 false,
512 ),
513 },
514 },
515 "struct_apply_remove_all": {
516 Ops: []Operation{
517 Apply{
518 Manager: "default",
519 Object: `
520 struct:
521 name: a
522 value: 1
523 `,
524 APIVersion: "v1",
525 },
526 Apply{
527 Manager: "default",
528 Object: `
529 `,
530 APIVersion: "v1",
531 },
532 },
533 Object: `
534 `,
535 APIVersion: "v1",
536 Managed: fieldpath.ManagedFields{},
537 },
538 "struct_apply_remove_dangling": {
539 Ops: []Operation{
540 Apply{
541 Manager: "default",
542 Object: `
543 struct:
544 name: a
545 `,
546 APIVersion: "v1",
547 },
548 Apply{
549 Manager: "default",
550 Object: `
551 struct:
552 `,
553 APIVersion: "v1",
554 },
555 },
556 Object: `
557 struct:
558 `,
559 APIVersion: "v1",
560 Managed: fieldpath.ManagedFields{
561 "default": fieldpath.NewVersionedSet(
562 _NS(
563 _P("struct"),
564 ),
565 "v1",
566 true,
567 ),
568 },
569 },
570 "struct_apply_update_remove_all": {
571 Ops: []Operation{
572 Apply{
573 Manager: "default",
574 Object: `
575 struct:
576 name: a
577 `,
578 APIVersion: "v1",
579 },
580 Update{
581 Manager: "controller",
582 Object: `
583 struct:
584 name: a
585 value: 1
586 `,
587 APIVersion: "v1",
588 },
589 Apply{
590 Manager: "default",
591 Object: `
592 `,
593 APIVersion: "v1",
594 },
595 },
596 Object: `
597 struct:
598 value: 1
599 `,
600 APIVersion: "v1",
601 },
602 "struct_apply_update_dict_dangling": {
603 Ops: []Operation{
604 Apply{
605 Manager: "default",
606 Object: `
607 struct:
608 name: a
609 `,
610 APIVersion: "v1",
611 },
612 Update{
613 Manager: "controller",
614 Object: `
615 struct:
616 name: a
617 value: 1
618 `,
619 APIVersion: "v1",
620 },
621 Apply{
622 Manager: "default",
623 Object: `
624 struct: {}
625 `,
626 APIVersion: "v1",
627 },
628 },
629 Object: `
630 struct:
631 value: 1
632 `,
633 APIVersion: "v1",
634 },
635 "struct_apply_update_dict_null": {
636 Ops: []Operation{
637 Apply{
638 Manager: "default",
639 Object: `
640 struct:
641 name: a
642 `,
643 APIVersion: "v1",
644 },
645 Update{
646 Manager: "controller",
647 Object: `
648 struct:
649 name: a
650 value: 1
651 `,
652 APIVersion: "v1",
653 },
654 Apply{
655 Manager: "default",
656 Object: `
657 struct:
658 `,
659 APIVersion: "v1",
660 },
661 },
662 Object: `
663 struct:
664 value: 1
665 `,
666 APIVersion: "v1",
667 },
668 "struct_apply_update_took_over": {
669 Ops: []Operation{
670 Apply{
671 Manager: "default",
672 Object: `
673 struct:
674 name: a
675 `,
676 APIVersion: "v1",
677 },
678 Update{
679 Manager: "controller",
680 Object: `
681 struct:
682 name: b
683 value: 1
684 `,
685 APIVersion: "v1",
686 },
687 Apply{
688 Manager: "default",
689 Object: `
690 struct:
691 `,
692 APIVersion: "v1",
693 },
694 },
695 Object: `
696 struct:
697 name: b
698 value: 1
699 `,
700 APIVersion: "v1",
701 },
702 }
703
704 for name, test := range tests {
705 t.Run(name, func(t *testing.T) {
706 if err := test.Test(nestedTypeParser); err != nil {
707 t.Fatal(err)
708 }
709 })
710 }
711 }
712
View as plain text