Skip to content

Commit

Permalink
Merge pull request kubernetes#79946 from apelisse/add-apply-benchmarks
Browse files Browse the repository at this point in the history
Add benchmarks for FieldManager handling
  • Loading branch information
k8s-ci-robot authored Jul 10, 2019
2 parents 57eef32 + 92cf376 commit e2b21c8
Show file tree
Hide file tree
Showing 5 changed files with 382 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ go_test(
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/sigs.k8s.io/yaml:go_default_library",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ package fieldmanager_test

import (
"errors"
"fmt"
"net/http"
"testing"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
"sigs.k8s.io/yaml"
)

type fakeObjectConvertor struct{}
Expand All @@ -48,7 +51,7 @@ type fakeObjectDefaulter struct{}

func (d *fakeObjectDefaulter) Default(in runtime.Object) {}

func NewTestFieldManager(t *testing.T) *fieldmanager.FieldManager {
func NewTestFieldManager() *fieldmanager.FieldManager {
gv := schema.GroupVersion{
Group: "apps",
Version: "v1",
Expand All @@ -63,13 +66,13 @@ func NewTestFieldManager(t *testing.T) *fieldmanager.FieldManager {
}

func TestFieldManagerCreation(t *testing.T) {
if NewTestFieldManager(t) == nil {
if NewTestFieldManager() == nil {
t.Fatal("failed to create FieldManager")
}
}

func TestApplyStripsFields(t *testing.T) {
f := NewTestFieldManager(t)
f := NewTestFieldManager()

obj := &corev1.Pod{}

Expand Down Expand Up @@ -114,7 +117,7 @@ func TestApplyStripsFields(t *testing.T) {
}

func TestVersionCheck(t *testing.T) {
f := NewTestFieldManager(t)
f := NewTestFieldManager()

obj := &corev1.Pod{}

Expand Down Expand Up @@ -147,7 +150,7 @@ func TestVersionCheck(t *testing.T) {
}

func TestApplyDoesNotStripLabels(t *testing.T) {
f := NewTestFieldManager(t)
f := NewTestFieldManager()

obj := &corev1.Pod{}

Expand All @@ -173,3 +176,266 @@ func TestApplyDoesNotStripLabels(t *testing.T) {
t.Fatalf("labels shouldn't get stripped on apply: %v", m)
}
}

func BenchmarkApplyNewObject(b *testing.B) {
f := NewTestFieldManager()

obj := &corev1.Pod{}

b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, err := f.Apply(obj, []byte(`{
"apiVersion": "apps/v1",
"kind": "Pod",
"metadata": {
"name": "b",
"namespace": "b",
"creationTimestamp": "2016-05-19T09:59:00Z",
},
"map": {
"fieldA": 1,
"fieldB": 1,
"fieldC": 1,
"fieldD": 1,
"fieldE": 1,
"fieldF": 1,
"fieldG": 1,
"fieldH": 1,
"fieldI": 1,
"fieldJ": 1,
"fieldK": 1,
"fieldL": 1,
"fieldM": 1,
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"value": true
},
},
},
},
},
}
}`), "fieldmanager_test", false)
if err != nil {
b.Fatal(err)
}
}
}

func BenchmarkUpdateNewObject(b *testing.B) {
f := NewTestFieldManager()

oldObj := &corev1.Pod{}
y := `{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "b",
"namespace": "b",
"creationTimestamp": "2016-05-19T09:59:00Z",
},
"map": {
"fieldA": 1,
"fieldB": 1,
"fieldC": 1,
"fieldD": 1,
"fieldE": 1,
"fieldF": 1,
"fieldG": 1,
"fieldH": 1,
"fieldI": 1,
"fieldJ": 1,
"fieldK": 1,
"fieldL": 1,
"fieldM": 1,
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"value": true
},
},
},
},
},
},
}`
newObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(y), &newObj.Object); err != nil {
b.Fatalf("Failed to parse yaml object: %v", err)
}

b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, err := f.Update(oldObj, newObj, "fieldmanager_test")
if err != nil {
b.Fatal(err)
}
}
}

func BenchmarkRepeatedUpdate(b *testing.B) {
f := NewTestFieldManager()

var oldObj runtime.Object
oldObj = &unstructured.Unstructured{Object: map[string]interface{}{}}
y1 := `{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "b",
"namespace": "b",
"creationTimestamp": "2016-05-19T09:59:00Z",
},
"map": {
"fieldA": 1,
"fieldB": 1,
"fieldC": 1,
"fieldD": 1,
"fieldE": 1,
"fieldF": 1,
"fieldG": 1,
"fieldH": 1,
"fieldI": 1,
"fieldJ": 1,
"fieldK": 1,
"fieldL": 1,
"fieldM": 1,
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"value": true
},
},
},
},
},
},
}`
obj1 := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(y1), &obj1.Object); err != nil {
b.Fatalf("Failed to parse yaml object: %v", err)
}
y2 := `{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "b",
"namespace": "b",
"creationTimestamp": "2016-05-19T09:59:00Z",
},
"map": {
"fieldA": 1,
"fieldB": 1,
"fieldC": 1,
"fieldD": 1,
"fieldE": 1,
"fieldF": 1,
"fieldG": 1,
"fieldH": 1,
"fieldI": 1,
"fieldJ": 1,
"fieldK": 1,
"fieldL": 1,
"fieldM": 1,
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"value": false
},
},
},
},
},
},
}`
obj2 := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(y2), &obj2.Object); err != nil {
b.Fatalf("Failed to parse yaml object: %v", err)
}
y3 := `{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "b",
"namespace": "b",
"creationTimestamp": "2016-05-19T09:59:00Z",
},
"map": {
"fieldA": 1,
"fieldB": 1,
"fieldC": 1,
"fieldD": 1,
"fieldE": 1,
"fieldF": 1,
"fieldG": 1,
"fieldH": 1,
"fieldI": 1,
"fieldJ": 1,
"fieldK": 1,
"fieldL": 1,
"fieldM": 1,
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"fieldN": {
"value": true
},
},
},
},
},
"fieldO": 1,
"fieldP": 1,
"fieldQ": 1,
"fieldR": 1,
"fieldS": 1,
},
}`
obj3 := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal([]byte(y3), &obj3.Object); err != nil {
b.Fatalf("Failed to parse yaml object: %v", err)
}

objs := []*unstructured.Unstructured{obj1, obj2, obj3}

var err error
oldObj, err = f.Update(oldObj, objs[0], "fieldmanager_0")
if err != nil {
b.Fatal(err)
}

oldObj, err = f.Update(oldObj, objs[1], "fieldmanager_1")
if err != nil {
b.Fatal(err)
}

oldObj, err = f.Update(oldObj, objs[2], "fieldmanager_2")
if err != nil {
b.Fatal(err)
}

b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
oldObj, err = f.Update(oldObj, objs[n%3], fmt.Sprintf("fieldmanager_%d", n%3))
if err != nil {
b.Fatal(err)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ go_test(
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library",
"//vendor/sigs.k8s.io/structured-merge-diff/fieldpath:go_default_library",
"//vendor/sigs.k8s.io/structured-merge-diff/merge:go_default_library",
"//vendor/sigs.k8s.io/structured-merge-diff/typed:go_default_library",
"//vendor/sigs.k8s.io/structured-merge-diff/value:go_default_library",
"//vendor/sigs.k8s.io/yaml:go_default_library",
],
)
Expand Down
Loading

0 comments on commit e2b21c8

Please sign in to comment.