mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			215 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2016 The Kubernetes Authors.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package api_test
 | |
| 
 | |
| import (
 | |
| 	"math/rand"
 | |
| 	"reflect"
 | |
| 	"sort"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/google/gofuzz"
 | |
| 
 | |
| 	apitesting "k8s.io/apimachinery/pkg/api/testing"
 | |
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | |
| 	"k8s.io/apimachinery/pkg/runtime"
 | |
| 	"k8s.io/apimachinery/pkg/runtime/schema"
 | |
| 	"k8s.io/apimachinery/pkg/util/diff"
 | |
| 	"k8s.io/kubernetes/pkg/api"
 | |
| 	apiv1 "k8s.io/kubernetes/pkg/api/v1"
 | |
| 	batchv2alpha1 "k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
 | |
| 	extensionsv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
 | |
| )
 | |
| 
 | |
| type orderedGroupVersionKinds []schema.GroupVersionKind
 | |
| 
 | |
| func (o orderedGroupVersionKinds) Len() int      { return len(o) }
 | |
| func (o orderedGroupVersionKinds) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
 | |
| func (o orderedGroupVersionKinds) Less(i, j int) bool {
 | |
| 	return o[i].String() < o[j].String()
 | |
| }
 | |
| 
 | |
| func TestVerifyDefaulting(t *testing.T) {
 | |
| 	job := &batchv2alpha1.JobTemplate{}
 | |
| 	batchv2alpha1.SetObjectDefaults_JobTemplate(job)
 | |
| 	if job.Template.Spec.Template.Spec.DNSPolicy != apiv1.DNSClusterFirst {
 | |
| 		t.Errorf("unexpected defaulting: %#v", job)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // TODO: add a reflexive test that verifies that all SetDefaults functions are registered
 | |
| func TestDefaulting(t *testing.T) {
 | |
| 	// these are the known types with defaulters - you must add to this list if you add a top level defaulter
 | |
| 	typesWithDefaulting := map[schema.GroupVersionKind]struct{}{
 | |
| 		{Group: "", Version: "v1", Kind: "ConfigMap"}:                                             {},
 | |
| 		{Group: "", Version: "v1", Kind: "ConfigMapList"}:                                         {},
 | |
| 		{Group: "", Version: "v1", Kind: "Endpoints"}:                                             {},
 | |
| 		{Group: "", Version: "v1", Kind: "EndpointsList"}:                                         {},
 | |
| 		{Group: "", Version: "v1", Kind: "Namespace"}:                                             {},
 | |
| 		{Group: "", Version: "v1", Kind: "NamespaceList"}:                                         {},
 | |
| 		{Group: "", Version: "v1", Kind: "Node"}:                                                  {},
 | |
| 		{Group: "", Version: "v1", Kind: "NodeList"}:                                              {},
 | |
| 		{Group: "", Version: "v1", Kind: "PersistentVolume"}:                                      {},
 | |
| 		{Group: "", Version: "v1", Kind: "PersistentVolumeList"}:                                  {},
 | |
| 		{Group: "", Version: "v1", Kind: "PersistentVolumeClaim"}:                                 {},
 | |
| 		{Group: "", Version: "v1", Kind: "PersistentVolumeClaimList"}:                             {},
 | |
| 		{Group: "", Version: "v1", Kind: "PodAttachOptions"}:                                      {},
 | |
| 		{Group: "", Version: "v1", Kind: "PodExecOptions"}:                                        {},
 | |
| 		{Group: "", Version: "v1", Kind: "Pod"}:                                                   {},
 | |
| 		{Group: "", Version: "v1", Kind: "PodList"}:                                               {},
 | |
| 		{Group: "", Version: "v1", Kind: "PodTemplate"}:                                           {},
 | |
| 		{Group: "", Version: "v1", Kind: "PodTemplateList"}:                                       {},
 | |
| 		{Group: "", Version: "v1", Kind: "ReplicationController"}:                                 {},
 | |
| 		{Group: "", Version: "v1", Kind: "ReplicationControllerList"}:                             {},
 | |
| 		{Group: "", Version: "v1", Kind: "Secret"}:                                                {},
 | |
| 		{Group: "", Version: "v1", Kind: "SecretList"}:                                            {},
 | |
| 		{Group: "", Version: "v1", Kind: "Service"}:                                               {},
 | |
| 		{Group: "", Version: "v1", Kind: "ServiceList"}:                                           {},
 | |
| 		{Group: "apps", Version: "v1beta1", Kind: "StatefulSet"}:                                  {},
 | |
| 		{Group: "apps", Version: "v1beta1", Kind: "StatefulSetList"}:                              {},
 | |
| 		{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"}:                    {},
 | |
| 		{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscalerList"}:                {},
 | |
| 		{Group: "autoscaling", Version: "v2alpha1", Kind: "HorizontalPodAutoscaler"}:              {},
 | |
| 		{Group: "autoscaling", Version: "v2alpha1", Kind: "HorizontalPodAutoscalerList"}:          {},
 | |
| 		{Group: "batch", Version: "v1", Kind: "Job"}:                                              {},
 | |
| 		{Group: "batch", Version: "v1", Kind: "JobList"}:                                          {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "CronJob"}:                                    {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "CronJobList"}:                                {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "Job"}:                                        {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "JobList"}:                                    {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "JobTemplate"}:                                {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"}:                               {},
 | |
| 		{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJobList"}:                           {},
 | |
| 		{Group: "certificates.k8s.io", Version: "v1beta1", Kind: "CertificateSigningRequest"}:     {},
 | |
| 		{Group: "certificates.k8s.io", Version: "v1beta1", Kind: "CertificateSigningRequestList"}: {},
 | |
| 		{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeProxyConfiguration"}:           {},
 | |
| 		{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeSchedulerConfiguration"}:       {},
 | |
| 		{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeletConfiguration"}:             {},
 | |
| 		{Group: "kubeadm.k8s.io", Version: "v1alpha1", Kind: "MasterConfiguration"}:               {},
 | |
| 		// This object contains only int fields which currently breaks the defaulting test because
 | |
| 		// it's pretty stupid. Once we add non integer fields, we should uncomment this.
 | |
| 		// {Group: "kubeadm.k8s.io", Version: "v1alpha1", Kind: "NodeConfiguration"}:                 {},
 | |
| 		{Group: "extensions", Version: "v1beta1", Kind: "DaemonSet"}:                              {},
 | |
| 		{Group: "extensions", Version: "v1beta1", Kind: "DaemonSetList"}:                          {},
 | |
| 		{Group: "extensions", Version: "v1beta1", Kind: "Deployment"}:                             {},
 | |
| 		{Group: "extensions", Version: "v1beta1", Kind: "DeploymentList"}:                         {},
 | |
| 		{Group: "apps", Version: "v1beta1", Kind: "Deployment"}:                                   {},
 | |
| 		{Group: "apps", Version: "v1beta1", Kind: "DeploymentList"}:                               {},
 | |
| 		{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSet"}:                             {},
 | |
| 		{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSetList"}:                         {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "ClusterRoleBinding"}:     {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "ClusterRoleBindingList"}: {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "RoleBinding"}:            {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "RoleBindingList"}:        {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "ClusterRoleBinding"}:      {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "ClusterRoleBindingList"}:  {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "RoleBinding"}:             {},
 | |
| 		{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "RoleBindingList"}:         {},
 | |
| 		{Group: "settings.k8s.io", Version: "v1alpha1", Kind: "PodPreset"}:                        {},
 | |
| 		{Group: "settings.k8s.io", Version: "v1alpha1", Kind: "PodPresetList"}:                    {},
 | |
| 	}
 | |
| 
 | |
| 	f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
 | |
| 	f.Funcs(
 | |
| 		func(s *runtime.RawExtension, c fuzz.Continue) {},
 | |
| 		func(s *metav1.LabelSelector, c fuzz.Continue) {
 | |
| 			c.FuzzNoCustom(s)
 | |
| 			s.MatchExpressions = nil // need to fuzz this specially
 | |
| 		},
 | |
| 		func(s *apiv1.ListOptions, c fuzz.Continue) {
 | |
| 			c.FuzzNoCustom(s)
 | |
| 			s.LabelSelector = "" // need to fuzz requirement strings specially
 | |
| 			s.FieldSelector = "" // need to fuzz requirement strings specially
 | |
| 		},
 | |
| 		func(s *extensionsv1beta1.ScaleStatus, c fuzz.Continue) {
 | |
| 			c.FuzzNoCustom(s)
 | |
| 			s.TargetSelector = "" // need to fuzz requirement strings specially
 | |
| 		},
 | |
| 	)
 | |
| 
 | |
| 	scheme := api.Scheme
 | |
| 	var testTypes orderedGroupVersionKinds
 | |
| 	for gvk := range scheme.AllKnownTypes() {
 | |
| 		if gvk.Version == runtime.APIVersionInternal {
 | |
| 			continue
 | |
| 		}
 | |
| 		testTypes = append(testTypes, gvk)
 | |
| 	}
 | |
| 	sort.Sort(testTypes)
 | |
| 
 | |
| 	for _, gvk := range testTypes {
 | |
| 		_, expectedChanged := typesWithDefaulting[gvk]
 | |
| 		iter := 0
 | |
| 		changedOnce := false
 | |
| 		for {
 | |
| 			if iter > *apitesting.FuzzIters {
 | |
| 				if !expectedChanged || changedOnce {
 | |
| 					break
 | |
| 				}
 | |
| 				if iter > 300 {
 | |
| 					t.Errorf("expected %s to trigger defaulting due to fuzzing", gvk)
 | |
| 					break
 | |
| 				}
 | |
| 				// if we expected defaulting, continue looping until the fuzzer gives us one
 | |
| 				// at worst, we will timeout
 | |
| 			}
 | |
| 			iter++
 | |
| 
 | |
| 			src, err := scheme.New(gvk)
 | |
| 			if err != nil {
 | |
| 				t.Fatal(err)
 | |
| 			}
 | |
| 			f.Fuzz(src)
 | |
| 
 | |
| 			src.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
 | |
| 
 | |
| 			original, err := scheme.DeepCopy(src)
 | |
| 			if err != nil {
 | |
| 				t.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			// get internal
 | |
| 			withDefaults, _ := scheme.DeepCopy(src)
 | |
| 			scheme.Default(withDefaults.(runtime.Object))
 | |
| 
 | |
| 			if !reflect.DeepEqual(original, withDefaults) {
 | |
| 				changedOnce = true
 | |
| 				if !expectedChanged {
 | |
| 					t.Errorf("{Group: \"%s\", Version: \"%s\", Kind: \"%s\"} did not expect defaults to be set - update expected or check defaulter registering: %s", gvk.Group, gvk.Version, gvk.Kind, diff.ObjectReflectDiff(original, withDefaults))
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func BenchmarkPodDefaulting(b *testing.B) {
 | |
| 	f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
 | |
| 	items := make([]apiv1.Pod, 100)
 | |
| 	for i := range items {
 | |
| 		f.Fuzz(&items[i])
 | |
| 	}
 | |
| 
 | |
| 	scheme := api.Scheme
 | |
| 	b.ResetTimer()
 | |
| 	for i := 0; i < b.N; i++ {
 | |
| 		pod := &items[i%len(items)]
 | |
| 
 | |
| 		scheme.Default(pod)
 | |
| 	}
 | |
| 	b.StopTimer()
 | |
| }
 | 
