From 850a913ea98a070e26cc62cbf95508084e8cc66b Mon Sep 17 00:00:00 2001 From: gongguan Date: Tue, 28 Jul 2020 10:09:37 +0800 Subject: [PATCH] extend ShouldCallHook benchmark to verify performance imporvement --- .../plugin/webhook/generic/webhook_test.go | 166 ++++++++++++++++-- 1 file changed, 156 insertions(+), 10 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook_test.go index f1f553c57ac..26dbefc1991 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook_test.go @@ -348,7 +348,76 @@ func (f fakeNamespaceLister) Get(name string) (*corev1.Namespace, error) { return nil, errors.NewNotFound(corev1.Resource("namespaces"), name) } -func BenchmarkShouldCallHook(b *testing.B) { +func BenchmarkShouldCallHookWithComplexSelector(b *testing.B) { + allScopes := v1.AllScopes + equivalentMatch := v1.Equivalent + + namespace1Labels := map[string]string{"ns": "ns1"} + namespace1 := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + Labels: namespace1Labels, + }, + } + namespaceLister := fakeNamespaceLister{map[string]*corev1.Namespace{"ns": &namespace1}} + + mapper := runtime.NewEquivalentResourceRegistryWithIdentity(func(resource schema.GroupResource) string { + if resource.Resource == "deployments" { + // co-locate deployments in all API groups + return "/deployments" + } + return "" + }) + mapper.RegisterKindFor(schema.GroupVersionResource{"extensions", "v1beta1", "deployments"}, "", schema.GroupVersionKind{"extensions", "v1beta1", "Deployment"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "deployments"}, "", schema.GroupVersionKind{"apps", "v1", "Deployment"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "deployments"}, "", schema.GroupVersionKind{"apps", "v1beta1", "Deployment"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1alpha1", "deployments"}, "", schema.GroupVersionKind{"apps", "v1alpha1", "Deployment"}) + + mapper.RegisterKindFor(schema.GroupVersionResource{"extensions", "v1beta1", "deployments"}, "scale", schema.GroupVersionKind{"extensions", "v1beta1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "deployments"}, "scale", schema.GroupVersionKind{"autoscaling", "v1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "deployments"}, "scale", schema.GroupVersionKind{"apps", "v1beta1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1alpha1", "deployments"}, "scale", schema.GroupVersionKind{"apps", "v1alpha1", "Scale"}) + + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "statefulset"}, "", schema.GroupVersionKind{"apps", "v1", "StatefulSet"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "statefulset"}, "", schema.GroupVersionKind{"apps", "v1beta1", "StatefulSet"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta2", "statefulset"}, "", schema.GroupVersionKind{"apps", "v1beta2", "StatefulSet"}) + + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "statefulset"}, "scale", schema.GroupVersionKind{"apps", "v1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "statefulset"}, "scale", schema.GroupVersionKind{"apps", "v1beta1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1alpha2", "statefulset"}, "scale", schema.GroupVersionKind{"apps", "v1beta2", "Scale"}) + + nsSelector := make(map[string]string) + for i := 0; i < 100; i++ { + nsSelector[fmt.Sprintf("key-%d", i)] = fmt.Sprintf("val-%d", i) + } + + wb := &v1.ValidatingWebhook{ + MatchPolicy: &equivalentMatch, + NamespaceSelector: &metav1.LabelSelector{MatchLabels: nsSelector}, + ObjectSelector: &metav1.LabelSelector{}, + Rules: []v1.RuleWithOperations{ + { + Operations: []v1.OperationType{"*"}, + Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes}, + }, + { + Operations: []v1.OperationType{"*"}, + Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes}, + }, + }, + } + + wbAccessor := webhook.NewValidatingWebhookAccessor("webhook", "webhook-cfg", wb) + attrs := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{"autoscaling", "v1", "Scale"}, "ns", "name", schema.GroupVersionResource{"apps", "v1", "deployments"}, "scale", admission.Create, &metav1.CreateOptions{}, false, nil) + interfaces := &admission.RuntimeObjectInterfaces{EquivalentResourceMapper: mapper} + a := &Webhook{namespaceMatcher: &namespace.Matcher{NamespaceLister: namespaceLister}, objectMatcher: &object.Matcher{}} + + for i := 0; i < b.N; i++ { + a.ShouldCallHook(wbAccessor, attrs, interfaces) + } +} + +func BenchmarkShouldCallHookWithComplexRule(b *testing.B) { allScopes := v1.AllScopes equivalentMatch := v1.Equivalent @@ -390,16 +459,93 @@ func BenchmarkShouldCallHook(b *testing.B) { MatchPolicy: &equivalentMatch, NamespaceSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}}, ObjectSelector: &metav1.LabelSelector{}, - Rules: []v1.RuleWithOperations{ - { - Operations: []v1.OperationType{"*"}, - Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes}, + Rules: []v1.RuleWithOperations{}, + } + + for i := 0; i < 100; i++ { + rule := v1.RuleWithOperations{ + Operations: []v1.OperationType{"*"}, + Rule: v1.Rule{ + APIGroups: []string{fmt.Sprintf("app-%d", i)}, + APIVersions: []string{fmt.Sprintf("v%d", i)}, + Resources: []string{fmt.Sprintf("resource%d", i), fmt.Sprintf("resource%d/scale", i)}, + Scope: &allScopes, }, - { - Operations: []v1.OperationType{"*"}, - Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes}, - }, - }, + } + wb.Rules = append(wb.Rules, rule) + } + + wbAccessor := webhook.NewValidatingWebhookAccessor("webhook", "webhook-cfg", wb) + attrs := admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{"autoscaling", "v1", "Scale"}, "ns", "name", schema.GroupVersionResource{"apps", "v1", "deployments"}, "scale", admission.Create, &metav1.CreateOptions{}, false, nil) + interfaces := &admission.RuntimeObjectInterfaces{EquivalentResourceMapper: mapper} + a := &Webhook{namespaceMatcher: &namespace.Matcher{NamespaceLister: namespaceLister}, objectMatcher: &object.Matcher{}} + + for i := 0; i < b.N; i++ { + a.ShouldCallHook(wbAccessor, attrs, interfaces) + } +} + +func BenchmarkShouldCallHookWithComplexSelectorAndRule(b *testing.B) { + allScopes := v1.AllScopes + equivalentMatch := v1.Equivalent + + namespace1Labels := map[string]string{"ns": "ns1"} + namespace1 := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + Labels: namespace1Labels, + }, + } + namespaceLister := fakeNamespaceLister{map[string]*corev1.Namespace{"ns": &namespace1}} + + mapper := runtime.NewEquivalentResourceRegistryWithIdentity(func(resource schema.GroupResource) string { + if resource.Resource == "deployments" { + // co-locate deployments in all API groups + return "/deployments" + } + return "" + }) + mapper.RegisterKindFor(schema.GroupVersionResource{"extensions", "v1beta1", "deployments"}, "", schema.GroupVersionKind{"extensions", "v1beta1", "Deployment"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "deployments"}, "", schema.GroupVersionKind{"apps", "v1", "Deployment"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "deployments"}, "", schema.GroupVersionKind{"apps", "v1beta1", "Deployment"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1alpha1", "deployments"}, "", schema.GroupVersionKind{"apps", "v1alpha1", "Deployment"}) + + mapper.RegisterKindFor(schema.GroupVersionResource{"extensions", "v1beta1", "deployments"}, "scale", schema.GroupVersionKind{"extensions", "v1beta1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "deployments"}, "scale", schema.GroupVersionKind{"autoscaling", "v1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "deployments"}, "scale", schema.GroupVersionKind{"apps", "v1beta1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1alpha1", "deployments"}, "scale", schema.GroupVersionKind{"apps", "v1alpha1", "Scale"}) + + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "statefulset"}, "", schema.GroupVersionKind{"apps", "v1", "StatefulSet"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "statefulset"}, "", schema.GroupVersionKind{"apps", "v1beta1", "StatefulSet"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta2", "statefulset"}, "", schema.GroupVersionKind{"apps", "v1beta2", "StatefulSet"}) + + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1", "statefulset"}, "scale", schema.GroupVersionKind{"apps", "v1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1beta1", "statefulset"}, "scale", schema.GroupVersionKind{"apps", "v1beta1", "Scale"}) + mapper.RegisterKindFor(schema.GroupVersionResource{"apps", "v1alpha2", "statefulset"}, "scale", schema.GroupVersionKind{"apps", "v1beta2", "Scale"}) + + nsSelector := make(map[string]string) + for i := 0; i < 100; i++ { + nsSelector[fmt.Sprintf("key-%d", i)] = fmt.Sprintf("val-%d", i) + } + + wb := &v1.ValidatingWebhook{ + MatchPolicy: &equivalentMatch, + NamespaceSelector: &metav1.LabelSelector{MatchLabels: nsSelector}, + ObjectSelector: &metav1.LabelSelector{}, + Rules: []v1.RuleWithOperations{}, + } + + for i := 0; i < 100; i++ { + rule := v1.RuleWithOperations{ + Operations: []v1.OperationType{"*"}, + Rule: v1.Rule{ + APIGroups: []string{fmt.Sprintf("app-%d", i)}, + APIVersions: []string{fmt.Sprintf("v%d", i)}, + Resources: []string{fmt.Sprintf("resource%d", i), fmt.Sprintf("resource%d/scale", i)}, + Scope: &allScopes, + }, + } + wb.Rules = append(wb.Rules, rule) } wbAccessor := webhook.NewValidatingWebhookAccessor("webhook", "webhook-cfg", wb)