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/merge"
25 "sigs.k8s.io/structured-merge-diff/v4/typed"
26 )
27
28 var leafFieldsParser = func() Parser {
29 parser, err := typed.NewParser(`types:
30 - name: leafFields
31 map:
32 fields:
33 - name: numeric
34 type:
35 scalar: numeric
36 - name: string
37 type:
38 scalar: string
39 - name: bool
40 type:
41 scalar: boolean`)
42 if err != nil {
43 panic(err)
44 }
45 return SameVersionParser{T: parser.Type("leafFields")}
46 }()
47
48 func TestUpdateLeaf(t *testing.T) {
49 tests := map[string]TestCase{
50 "apply_twice": {
51 Ops: []Operation{
52 Apply{
53 Manager: "default",
54 Object: `
55 numeric: 1
56 string: "string"
57 `,
58 APIVersion: "v1",
59 },
60 Apply{
61 Manager: "default",
62 Object: `
63 numeric: 2
64 string: "string"
65 bool: false
66 `,
67 APIVersion: "v1",
68 },
69 },
70 Object: `
71 numeric: 2
72 string: "string"
73 bool: false
74 `,
75 APIVersion: "v1",
76 Managed: fieldpath.ManagedFields{
77 "default": fieldpath.NewVersionedSet(
78 _NS(
79 _P("numeric"), _P("string"), _P("bool"),
80 ),
81 "v1",
82 false,
83 ),
84 },
85 },
86 "apply_twice_different_versions": {
87 Ops: []Operation{
88 Apply{
89 Manager: "default",
90 Object: `
91 numeric: 1
92 string: "string"
93 `,
94 APIVersion: "v1",
95 },
96 Apply{
97 Manager: "default",
98 Object: `
99 numeric: 2
100 string: "string"
101 bool: false
102 `,
103 APIVersion: "v2",
104 },
105 },
106 Object: `
107 numeric: 2
108 string: "string"
109 bool: false
110 `,
111 APIVersion: "v1",
112 Managed: fieldpath.ManagedFields{
113 "default": fieldpath.NewVersionedSet(
114 _NS(
115 _P("numeric"), _P("string"), _P("bool"),
116 ),
117 "v2",
118 false,
119 ),
120 },
121 },
122 "apply_update_apply_no_conflict": {
123 Ops: []Operation{
124 Apply{
125 Manager: "default",
126 APIVersion: "v1",
127 Object: `
128 numeric: 1
129 string: "string"
130 `,
131 },
132 Update{
133 Manager: "controller",
134 APIVersion: "v1",
135 Object: `
136 numeric: 1
137 string: "string"
138 bool: true
139 `,
140 },
141 Apply{
142 Manager: "default",
143 APIVersion: "v1",
144 Object: `
145 numeric: 2
146 string: "string"
147 `,
148 },
149 },
150 Object: `
151 numeric: 2
152 string: "string"
153 bool: true
154 `,
155 APIVersion: "v1",
156 Managed: fieldpath.ManagedFields{
157 "default": fieldpath.NewVersionedSet(
158 _NS(
159 _P("numeric"), _P("string"),
160 ),
161 "v1",
162 false,
163 ),
164 "controller": fieldpath.NewVersionedSet(
165 _NS(
166 _P("bool"),
167 ),
168 "v1",
169 false,
170 ),
171 },
172 },
173 "apply_update_apply_no_conflict_different_version": {
174 Ops: []Operation{
175 Apply{
176 Manager: "default",
177 APIVersion: "v1",
178 Object: `
179 numeric: 1
180 string: "string"
181 `,
182 },
183 Update{
184 Manager: "controller",
185 APIVersion: "v2",
186 Object: `
187 numeric: 1
188 string: "string"
189 bool: true
190 `,
191 },
192 Apply{
193 Manager: "default",
194 APIVersion: "v1",
195 Object: `
196 numeric: 2
197 string: "string"
198 `,
199 },
200 },
201 Object: `
202 numeric: 2
203 string: "string"
204 bool: true
205 `,
206 APIVersion: "v1",
207 Managed: fieldpath.ManagedFields{
208 "default": fieldpath.NewVersionedSet(
209 _NS(
210 _P("numeric"), _P("string"),
211 ),
212 "v1",
213 false,
214 ),
215 "controller": fieldpath.NewVersionedSet(
216 _NS(
217 _P("bool"),
218 ),
219 "v2",
220 false,
221 ),
222 },
223 },
224 "apply_update_apply_with_conflict": {
225 Ops: []Operation{
226 Apply{
227 Manager: "default",
228 APIVersion: "v1",
229 Object: `
230 numeric: 1
231 string: "string"
232 `,
233 },
234 Update{
235 Manager: "controller",
236 APIVersion: "v1",
237 Object: `
238 numeric: 1
239 string: "controller string"
240 bool: true
241 `,
242 },
243 Apply{
244 Manager: "default",
245 APIVersion: "v1",
246 Object: `
247 numeric: 2
248 string: "user string"
249 `,
250 Conflicts: merge.Conflicts{
251 merge.Conflict{Manager: "controller", Path: _P("string")},
252 },
253 },
254 ForceApply{
255 Manager: "default",
256 APIVersion: "v1",
257 Object: `
258 numeric: 2
259 string: "user string"
260 `,
261 },
262 },
263 Object: `
264 numeric: 2
265 string: "user string"
266 bool: true
267 `,
268 APIVersion: "v1",
269 Managed: fieldpath.ManagedFields{
270 "default": fieldpath.NewVersionedSet(
271 _NS(
272 _P("numeric"), _P("string"),
273 ),
274 "v1",
275 false,
276 ),
277 "controller": fieldpath.NewVersionedSet(
278 _NS(
279 _P("bool"),
280 ),
281 "v1",
282 false,
283 ),
284 },
285 },
286 "apply_update_apply_with_conflict_across_version": {
287 Ops: []Operation{
288 Apply{
289 Manager: "default",
290 APIVersion: "v1",
291 Object: `
292 numeric: 1
293 string: "string"
294 `,
295 },
296 Update{
297 Manager: "controller",
298 APIVersion: "v2",
299 Object: `
300 numeric: 1
301 string: "controller string"
302 bool: true
303 `,
304 },
305 Apply{
306 Manager: "default",
307 APIVersion: "v1",
308 Object: `
309 numeric: 2
310 string: "user string"
311 `,
312 Conflicts: merge.Conflicts{
313 merge.Conflict{Manager: "controller", Path: _P("string")},
314 },
315 },
316 ForceApply{
317 Manager: "default",
318 APIVersion: "v1",
319 Object: `
320 numeric: 2
321 string: "user string"
322 `,
323 },
324 },
325 Object: `
326 numeric: 2
327 string: "user string"
328 bool: true
329 `,
330 APIVersion: "v1",
331 Managed: fieldpath.ManagedFields{
332 "default": fieldpath.NewVersionedSet(
333 _NS(
334 _P("numeric"), _P("string"),
335 ),
336 "v1",
337 false,
338 ),
339 "controller": fieldpath.NewVersionedSet(
340 _NS(
341 _P("bool"),
342 ),
343 "v2",
344 false,
345 ),
346 },
347 },
348 "apply_twice_remove": {
349 Ops: []Operation{
350 Apply{
351 Manager: "default",
352 APIVersion: "v1",
353 Object: `
354 numeric: 1
355 string: "string"
356 bool: false
357 `,
358 },
359 Apply{
360 Manager: "default",
361 APIVersion: "v1",
362 Object: `
363 string: "new string"
364 `,
365 },
366 },
367 Object: `
368 string: "new string"
369 `,
370 APIVersion: "v1",
371 Managed: fieldpath.ManagedFields{
372 "default": fieldpath.NewVersionedSet(
373 _NS(
374 _P("string"),
375 ),
376 "v1",
377 false,
378 ),
379 },
380 },
381 "update_apply_omits": {
382 Ops: []Operation{
383 Apply{
384 Manager: "default",
385 APIVersion: "v1",
386 Object: `
387 numeric: 2
388 `,
389 },
390 Update{
391 Manager: "controller",
392 APIVersion: "v1",
393 Object: `
394 numeric: 1
395 `,
396 },
397 Apply{
398 Manager: "default",
399 APIVersion: "v1",
400 Object: ``,
401 },
402 },
403 Object: `
404 numeric: 1
405 `,
406 APIVersion: "v1",
407 Managed: fieldpath.ManagedFields{
408 "controller": fieldpath.NewVersionedSet(
409 _NS(
410 _P("numeric"),
411 ),
412 "v1",
413 false,
414 ),
415 },
416 },
417 "apply_twice_remove_different_version": {
418 Ops: []Operation{
419 Apply{
420 Manager: "default",
421 APIVersion: "v1",
422 Object: `
423 numeric: 1
424 string: "string"
425 bool: false
426 `,
427 },
428 Apply{
429 Manager: "default",
430 APIVersion: "v2",
431 Object: `
432 string: "new string"
433 `,
434 },
435 },
436 Object: `
437 string: "new string"
438 `,
439 APIVersion: "v1",
440 Managed: fieldpath.ManagedFields{
441 "default": fieldpath.NewVersionedSet(
442 _NS(
443 _P("string"),
444 ),
445 "v2",
446 false,
447 ),
448 },
449 },
450 "update_remove_empty_set": {
451 Ops: []Operation{
452 Apply{
453 Manager: "default",
454 APIVersion: "v1",
455 Object: `
456 string: "string"
457 `,
458 },
459 Update{
460 Manager: "controller",
461 APIVersion: "v1",
462 Object: `
463 string: "new string"
464 `,
465 },
466 },
467 Object: `
468 string: "new string"
469 `,
470 APIVersion: "v1",
471 Managed: fieldpath.ManagedFields{
472 "controller": fieldpath.NewVersionedSet(
473 _NS(
474 _P("string"),
475 ),
476 "v1",
477 false,
478 ),
479 },
480 },
481 "apply_remove_empty_set": {
482 Ops: []Operation{
483 Apply{
484 Manager: "default",
485 APIVersion: "v1",
486 Object: `
487 string: "string"
488 `,
489 },
490 Apply{
491 Manager: "default",
492 APIVersion: "v1",
493 Object: "",
494 },
495 },
496 Object: `
497 `,
498 APIVersion: "v1",
499 Managed: fieldpath.ManagedFields{},
500 },
501 }
502
503 for name, test := range tests {
504 t.Run(name, func(t *testing.T) {
505 if err := test.Test(leafFieldsParser); err != nil {
506 t.Fatal(err)
507 }
508 })
509 }
510 }
511
512 func BenchmarkLeafConflictAcrossVersion(b *testing.B) {
513 test := TestCase{
514 Ops: []Operation{
515 Apply{
516 Manager: "default",
517 APIVersion: "v1",
518 Object: `
519 numeric: 1
520 string: "string"
521 `,
522 },
523 Update{
524 Manager: "controller",
525 APIVersion: "v2",
526 Object: `
527 numeric: 1
528 string: "controller string"
529 bool: true
530 `,
531 },
532 Apply{
533 Manager: "default",
534 APIVersion: "v1",
535 Object: `
536 numeric: 2
537 string: "user string"
538 `,
539 Conflicts: merge.Conflicts{
540 merge.Conflict{Manager: "controller", Path: _P("string")},
541 },
542 },
543 ForceApply{
544 Manager: "default",
545 APIVersion: "v1",
546 Object: `
547 numeric: 2
548 string: "user string"
549 `,
550 },
551 },
552 Object: `
553 numeric: 2
554 string: "user string"
555 bool: true
556 `,
557 APIVersion: "v1",
558 Managed: fieldpath.ManagedFields{
559 "default": fieldpath.NewVersionedSet(
560 _NS(
561 _P("numeric"), _P("string"),
562 ),
563 "v1",
564 false,
565 ),
566 "controller": fieldpath.NewVersionedSet(
567 _NS(
568 _P("bool"),
569 ),
570 "v2",
571 false,
572 ),
573 },
574 }
575
576
577 if err := test.Test(leafFieldsParser); err != nil {
578 b.Fatal(err)
579 }
580
581 test.PreprocessOperations(leafFieldsParser)
582
583 b.ReportAllocs()
584 b.ResetTimer()
585 for n := 0; n < b.N; n++ {
586 if err := test.Bench(leafFieldsParser); err != nil {
587 b.Fatal(err)
588 }
589 }
590 }
591
View as plain text