@@ -18,15 +18,18 @@ package fieldmanager_test
18
18
19
19
import (
20
20
"errors"
21
+ "fmt"
21
22
"net/http"
22
23
"testing"
23
24
24
25
corev1 "k8s.io/api/core/v1"
25
26
apierrors "k8s.io/apimachinery/pkg/api/errors"
26
27
"k8s.io/apimachinery/pkg/api/meta"
28
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
27
29
"k8s.io/apimachinery/pkg/runtime"
28
30
"k8s.io/apimachinery/pkg/runtime/schema"
29
31
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
32
+ "sigs.k8s.io/yaml"
30
33
)
31
34
32
35
type fakeObjectConvertor struct {}
@@ -48,7 +51,7 @@ type fakeObjectDefaulter struct{}
48
51
49
52
func (d * fakeObjectDefaulter ) Default (in runtime.Object ) {}
50
53
51
- func NewTestFieldManager (t * testing. T ) * fieldmanager.FieldManager {
54
+ func NewTestFieldManager () * fieldmanager.FieldManager {
52
55
gv := schema.GroupVersion {
53
56
Group : "apps" ,
54
57
Version : "v1" ,
@@ -63,13 +66,13 @@ func NewTestFieldManager(t *testing.T) *fieldmanager.FieldManager {
63
66
}
64
67
65
68
func TestFieldManagerCreation (t * testing.T ) {
66
- if NewTestFieldManager (t ) == nil {
69
+ if NewTestFieldManager () == nil {
67
70
t .Fatal ("failed to create FieldManager" )
68
71
}
69
72
}
70
73
71
74
func TestApplyStripsFields (t * testing.T ) {
72
- f := NewTestFieldManager (t )
75
+ f := NewTestFieldManager ()
73
76
74
77
obj := & corev1.Pod {}
75
78
@@ -114,7 +117,7 @@ func TestApplyStripsFields(t *testing.T) {
114
117
}
115
118
116
119
func TestVersionCheck (t * testing.T ) {
117
- f := NewTestFieldManager (t )
120
+ f := NewTestFieldManager ()
118
121
119
122
obj := & corev1.Pod {}
120
123
@@ -147,7 +150,7 @@ func TestVersionCheck(t *testing.T) {
147
150
}
148
151
149
152
func TestApplyDoesNotStripLabels (t * testing.T ) {
150
- f := NewTestFieldManager (t )
153
+ f := NewTestFieldManager ()
151
154
152
155
obj := & corev1.Pod {}
153
156
@@ -173,3 +176,266 @@ func TestApplyDoesNotStripLabels(t *testing.T) {
173
176
t .Fatalf ("labels shouldn't get stripped on apply: %v" , m )
174
177
}
175
178
}
179
+
180
+ func BenchmarkApplyNewObject (b * testing.B ) {
181
+ f := NewTestFieldManager ()
182
+
183
+ obj := & corev1.Pod {}
184
+
185
+ b .ReportAllocs ()
186
+ b .ResetTimer ()
187
+ for n := 0 ; n < b .N ; n ++ {
188
+ _ , err := f .Apply (obj , []byte (`{
189
+ "apiVersion": "apps/v1",
190
+ "kind": "Pod",
191
+ "metadata": {
192
+ "name": "b",
193
+ "namespace": "b",
194
+ "creationTimestamp": "2016-05-19T09:59:00Z",
195
+ },
196
+ "map": {
197
+ "fieldA": 1,
198
+ "fieldB": 1,
199
+ "fieldC": 1,
200
+ "fieldD": 1,
201
+ "fieldE": 1,
202
+ "fieldF": 1,
203
+ "fieldG": 1,
204
+ "fieldH": 1,
205
+ "fieldI": 1,
206
+ "fieldJ": 1,
207
+ "fieldK": 1,
208
+ "fieldL": 1,
209
+ "fieldM": 1,
210
+ "fieldN": {
211
+ "fieldN": {
212
+ "fieldN": {
213
+ "fieldN": {
214
+ "fieldN": {
215
+ "value": true
216
+ },
217
+ },
218
+ },
219
+ },
220
+ },
221
+ }
222
+ }` ), "fieldmanager_test" , false )
223
+ if err != nil {
224
+ b .Fatal (err )
225
+ }
226
+ }
227
+ }
228
+
229
+ func BenchmarkUpdateNewObject (b * testing.B ) {
230
+ f := NewTestFieldManager ()
231
+
232
+ oldObj := & corev1.Pod {}
233
+ y := `{
234
+ "apiVersion": "apps/v1",
235
+ "kind": "Deployment",
236
+ "metadata": {
237
+ "name": "b",
238
+ "namespace": "b",
239
+ "creationTimestamp": "2016-05-19T09:59:00Z",
240
+ },
241
+ "map": {
242
+ "fieldA": 1,
243
+ "fieldB": 1,
244
+ "fieldC": 1,
245
+ "fieldD": 1,
246
+ "fieldE": 1,
247
+ "fieldF": 1,
248
+ "fieldG": 1,
249
+ "fieldH": 1,
250
+ "fieldI": 1,
251
+ "fieldJ": 1,
252
+ "fieldK": 1,
253
+ "fieldL": 1,
254
+ "fieldM": 1,
255
+ "fieldN": {
256
+ "fieldN": {
257
+ "fieldN": {
258
+ "fieldN": {
259
+ "fieldN": {
260
+ "value": true
261
+ },
262
+ },
263
+ },
264
+ },
265
+ },
266
+ },
267
+
268
+ }`
269
+ newObj := & unstructured.Unstructured {Object : map [string ]interface {}{}}
270
+ if err := yaml .Unmarshal ([]byte (y ), & newObj .Object ); err != nil {
271
+ b .Fatalf ("Failed to parse yaml object: %v" , err )
272
+ }
273
+
274
+ b .ReportAllocs ()
275
+ b .ResetTimer ()
276
+ for n := 0 ; n < b .N ; n ++ {
277
+ _ , err := f .Update (oldObj , newObj , "fieldmanager_test" )
278
+ if err != nil {
279
+ b .Fatal (err )
280
+ }
281
+ }
282
+ }
283
+
284
+ func BenchmarkRepeatedUpdate (b * testing.B ) {
285
+ f := NewTestFieldManager ()
286
+
287
+ var oldObj runtime.Object
288
+ oldObj = & unstructured.Unstructured {Object : map [string ]interface {}{}}
289
+ y1 := `{
290
+ "apiVersion": "apps/v1",
291
+ "kind": "Deployment",
292
+ "metadata": {
293
+ "name": "b",
294
+ "namespace": "b",
295
+ "creationTimestamp": "2016-05-19T09:59:00Z",
296
+ },
297
+ "map": {
298
+ "fieldA": 1,
299
+ "fieldB": 1,
300
+ "fieldC": 1,
301
+ "fieldD": 1,
302
+ "fieldE": 1,
303
+ "fieldF": 1,
304
+ "fieldG": 1,
305
+ "fieldH": 1,
306
+ "fieldI": 1,
307
+ "fieldJ": 1,
308
+ "fieldK": 1,
309
+ "fieldL": 1,
310
+ "fieldM": 1,
311
+ "fieldN": {
312
+ "fieldN": {
313
+ "fieldN": {
314
+ "fieldN": {
315
+ "fieldN": {
316
+ "value": true
317
+ },
318
+ },
319
+ },
320
+ },
321
+ },
322
+ },
323
+
324
+ }`
325
+ obj1 := & unstructured.Unstructured {Object : map [string ]interface {}{}}
326
+ if err := yaml .Unmarshal ([]byte (y1 ), & obj1 .Object ); err != nil {
327
+ b .Fatalf ("Failed to parse yaml object: %v" , err )
328
+ }
329
+ y2 := `{
330
+ "apiVersion": "apps/v1",
331
+ "kind": "Deployment",
332
+ "metadata": {
333
+ "name": "b",
334
+ "namespace": "b",
335
+ "creationTimestamp": "2016-05-19T09:59:00Z",
336
+ },
337
+ "map": {
338
+ "fieldA": 1,
339
+ "fieldB": 1,
340
+ "fieldC": 1,
341
+ "fieldD": 1,
342
+ "fieldE": 1,
343
+ "fieldF": 1,
344
+ "fieldG": 1,
345
+ "fieldH": 1,
346
+ "fieldI": 1,
347
+ "fieldJ": 1,
348
+ "fieldK": 1,
349
+ "fieldL": 1,
350
+ "fieldM": 1,
351
+ "fieldN": {
352
+ "fieldN": {
353
+ "fieldN": {
354
+ "fieldN": {
355
+ "fieldN": {
356
+ "value": false
357
+ },
358
+ },
359
+ },
360
+ },
361
+ },
362
+ },
363
+
364
+ }`
365
+ obj2 := & unstructured.Unstructured {Object : map [string ]interface {}{}}
366
+ if err := yaml .Unmarshal ([]byte (y2 ), & obj2 .Object ); err != nil {
367
+ b .Fatalf ("Failed to parse yaml object: %v" , err )
368
+ }
369
+ y3 := `{
370
+ "apiVersion": "apps/v1",
371
+ "kind": "Deployment",
372
+ "metadata": {
373
+ "name": "b",
374
+ "namespace": "b",
375
+ "creationTimestamp": "2016-05-19T09:59:00Z",
376
+ },
377
+ "map": {
378
+ "fieldA": 1,
379
+ "fieldB": 1,
380
+ "fieldC": 1,
381
+ "fieldD": 1,
382
+ "fieldE": 1,
383
+ "fieldF": 1,
384
+ "fieldG": 1,
385
+ "fieldH": 1,
386
+ "fieldI": 1,
387
+ "fieldJ": 1,
388
+ "fieldK": 1,
389
+ "fieldL": 1,
390
+ "fieldM": 1,
391
+ "fieldN": {
392
+ "fieldN": {
393
+ "fieldN": {
394
+ "fieldN": {
395
+ "fieldN": {
396
+ "value": true
397
+ },
398
+ },
399
+ },
400
+ },
401
+ },
402
+ "fieldO": 1,
403
+ "fieldP": 1,
404
+ "fieldQ": 1,
405
+ "fieldR": 1,
406
+ "fieldS": 1,
407
+ },
408
+
409
+ }`
410
+ obj3 := & unstructured.Unstructured {Object : map [string ]interface {}{}}
411
+ if err := yaml .Unmarshal ([]byte (y3 ), & obj3 .Object ); err != nil {
412
+ b .Fatalf ("Failed to parse yaml object: %v" , err )
413
+ }
414
+
415
+ objs := []* unstructured.Unstructured {obj1 , obj2 , obj3 }
416
+
417
+ var err error
418
+ oldObj , err = f .Update (oldObj , objs [0 ], "fieldmanager_0" )
419
+ if err != nil {
420
+ b .Fatal (err )
421
+ }
422
+
423
+ oldObj , err = f .Update (oldObj , objs [1 ], "fieldmanager_1" )
424
+ if err != nil {
425
+ b .Fatal (err )
426
+ }
427
+
428
+ oldObj , err = f .Update (oldObj , objs [2 ], "fieldmanager_2" )
429
+ if err != nil {
430
+ b .Fatal (err )
431
+ }
432
+
433
+ b .ReportAllocs ()
434
+ b .ResetTimer ()
435
+ for n := 0 ; n < b .N ; n ++ {
436
+ oldObj , err = f .Update (oldObj , objs [n % 3 ], fmt .Sprintf ("fieldmanager_%d" , n % 3 ))
437
+ if err != nil {
438
+ b .Fatal (err )
439
+ }
440
+ }
441
+ }
0 commit comments