...

Source file src/k8s.io/kubernetes/plugin/pkg/admission/priority/admission_test.go

Documentation: k8s.io/kubernetes/plugin/pkg/admission/priority

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package priority
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"k8s.io/klog/v2"
    24  
    25  	schedulingv1 "k8s.io/api/scheduling/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apiserver/pkg/admission"
    28  	admissiontesting "k8s.io/apiserver/pkg/admission/testing"
    29  	"k8s.io/apiserver/pkg/authentication/user"
    30  	"k8s.io/client-go/informers"
    31  	api "k8s.io/kubernetes/pkg/apis/core"
    32  	"k8s.io/kubernetes/pkg/apis/scheduling"
    33  	v1 "k8s.io/kubernetes/pkg/apis/scheduling/v1"
    34  	"k8s.io/kubernetes/pkg/controller"
    35  )
    36  
    37  func addPriorityClasses(ctrl *Plugin, priorityClasses []*scheduling.PriorityClass) error {
    38  	informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
    39  	ctrl.SetExternalKubeInformerFactory(informerFactory)
    40  	// First add the existing classes to the cache.
    41  	for _, c := range priorityClasses {
    42  		s := &schedulingv1.PriorityClass{}
    43  		if err := v1.Convert_scheduling_PriorityClass_To_v1_PriorityClass(c, s, nil); err != nil {
    44  			return err
    45  		}
    46  		informerFactory.Scheduling().V1().PriorityClasses().Informer().GetStore().Add(s)
    47  	}
    48  	return nil
    49  }
    50  
    51  var (
    52  	preemptNever         = api.PreemptNever
    53  	preemptLowerPriority = api.PreemptLowerPriority
    54  )
    55  
    56  var defaultClass1 = &scheduling.PriorityClass{
    57  	TypeMeta: metav1.TypeMeta{
    58  		Kind: "PriorityClass",
    59  	},
    60  	ObjectMeta: metav1.ObjectMeta{
    61  		Name: "default1",
    62  	},
    63  	Value:         1000,
    64  	GlobalDefault: true,
    65  }
    66  
    67  var defaultClass2 = &scheduling.PriorityClass{
    68  	TypeMeta: metav1.TypeMeta{
    69  		Kind: "PriorityClass",
    70  	},
    71  	ObjectMeta: metav1.ObjectMeta{
    72  		Name: "default2",
    73  	},
    74  	Value:         2000,
    75  	GlobalDefault: true,
    76  }
    77  
    78  var nondefaultClass1 = &scheduling.PriorityClass{
    79  	TypeMeta: metav1.TypeMeta{
    80  		Kind: "PriorityClass",
    81  	},
    82  	ObjectMeta: metav1.ObjectMeta{
    83  		Name: "nondefault1",
    84  	},
    85  	Value:       2000,
    86  	Description: "Just a test priority class",
    87  }
    88  
    89  var systemClusterCritical = &scheduling.PriorityClass{
    90  	TypeMeta: metav1.TypeMeta{
    91  		Kind: "PriorityClass",
    92  	},
    93  	ObjectMeta: metav1.ObjectMeta{
    94  		Name: scheduling.SystemClusterCritical,
    95  	},
    96  	Value:         scheduling.SystemCriticalPriority,
    97  	GlobalDefault: true,
    98  }
    99  
   100  var neverPreemptionPolicyClass = &scheduling.PriorityClass{
   101  	TypeMeta: metav1.TypeMeta{
   102  		Kind: "PriorityClass",
   103  	},
   104  	ObjectMeta: metav1.ObjectMeta{
   105  		Name: "nopreemptionpolicy",
   106  	},
   107  	Value:            2000,
   108  	Description:      "Just a test priority class",
   109  	GlobalDefault:    true,
   110  	PreemptionPolicy: &preemptNever,
   111  }
   112  
   113  var preemptionPolicyClass = &scheduling.PriorityClass{
   114  	TypeMeta: metav1.TypeMeta{
   115  		Kind: "PriorityClass",
   116  	},
   117  	ObjectMeta: metav1.ObjectMeta{
   118  		Name: "nopreemptionpolicy",
   119  	},
   120  	Value:            2000,
   121  	Description:      "Just a test priority class",
   122  	GlobalDefault:    true,
   123  	PreemptionPolicy: &preemptLowerPriority,
   124  }
   125  
   126  func TestPriorityClassAdmission(t *testing.T) {
   127  	var systemClass = &scheduling.PriorityClass{
   128  		TypeMeta: metav1.TypeMeta{
   129  			Kind: "PriorityClass",
   130  		},
   131  		ObjectMeta: metav1.ObjectMeta{
   132  			Name: scheduling.SystemPriorityClassPrefix + "test",
   133  		},
   134  		Value:       scheduling.HighestUserDefinablePriority + 1,
   135  		Description: "Name has system critical prefix",
   136  	}
   137  
   138  	tests := []struct {
   139  		name            string
   140  		existingClasses []*scheduling.PriorityClass
   141  		newClass        *scheduling.PriorityClass
   142  		userInfo        user.Info
   143  		operation       admission.Operation
   144  		expectError     bool
   145  	}{
   146  		{
   147  			"create operator with default class",
   148  			[]*scheduling.PriorityClass{},
   149  			defaultClass1,
   150  			nil,
   151  			admission.Create,
   152  			false,
   153  		},
   154  		{
   155  			"create operator with one existing default class",
   156  			[]*scheduling.PriorityClass{defaultClass1},
   157  			defaultClass2,
   158  			nil,
   159  			admission.Create,
   160  			true,
   161  		},
   162  		{
   163  			"create operator with system name and value allowed by admission controller",
   164  			[]*scheduling.PriorityClass{},
   165  			systemClass,
   166  			&user.DefaultInfo{
   167  				Name: user.APIServerUser,
   168  			},
   169  			admission.Create,
   170  			false,
   171  		},
   172  		{
   173  			"update operator with default class",
   174  			[]*scheduling.PriorityClass{},
   175  			defaultClass1,
   176  			nil,
   177  			admission.Update,
   178  			false,
   179  		},
   180  		{
   181  			"update operator with one existing default class",
   182  			[]*scheduling.PriorityClass{defaultClass1},
   183  			defaultClass2,
   184  			nil,
   185  			admission.Update,
   186  			true,
   187  		},
   188  		{
   189  			"update operator with system name and value allowed by admission controller",
   190  			[]*scheduling.PriorityClass{},
   191  			systemClass,
   192  			&user.DefaultInfo{
   193  				Name: user.APIServerUser,
   194  			},
   195  			admission.Update,
   196  			false,
   197  		},
   198  		{
   199  			"update operator with different default classes",
   200  			[]*scheduling.PriorityClass{defaultClass1},
   201  			defaultClass2,
   202  			nil,
   203  			admission.Update,
   204  			true,
   205  		},
   206  		{
   207  			"delete operation with default class",
   208  			[]*scheduling.PriorityClass{},
   209  			defaultClass1,
   210  			nil,
   211  			admission.Delete,
   212  			false,
   213  		},
   214  	}
   215  
   216  	for _, test := range tests {
   217  		klog.V(4).Infof("starting test %q", test.name)
   218  
   219  		ctrl := NewPlugin()
   220  		// Add existing priority classes.
   221  		if err := addPriorityClasses(ctrl, test.existingClasses); err != nil {
   222  			t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
   223  		}
   224  		// Now add the new class.
   225  		attrs := admission.NewAttributesRecord(
   226  			test.newClass,
   227  			nil,
   228  			scheduling.Kind("PriorityClass").WithVersion("version"),
   229  			"",
   230  			"",
   231  			scheduling.Resource("priorityclasses").WithVersion("version"),
   232  			"",
   233  			test.operation,
   234  			&metav1.CreateOptions{},
   235  			false,
   236  			test.userInfo,
   237  		)
   238  		err := ctrl.Validate(context.TODO(), attrs, nil)
   239  		klog.Infof("Got %v", err)
   240  		if err != nil && !test.expectError {
   241  			t.Errorf("Test %q: unexpected error received: %v", test.name, err)
   242  		}
   243  		if err == nil && test.expectError {
   244  			t.Errorf("Test %q: expected error and no error recevied", test.name)
   245  		}
   246  	}
   247  }
   248  
   249  // TestDefaultPriority tests that default priority is resolved correctly.
   250  func TestDefaultPriority(t *testing.T) {
   251  	pcResource := scheduling.Resource("priorityclasses").WithVersion("version")
   252  	pcKind := scheduling.Kind("PriorityClass").WithVersion("version")
   253  	updatedDefaultClass1 := *defaultClass1
   254  	updatedDefaultClass1.GlobalDefault = false
   255  
   256  	tests := []struct {
   257  		name                      string
   258  		classesBefore             []*scheduling.PriorityClass
   259  		classesAfter              []*scheduling.PriorityClass
   260  		attributes                admission.Attributes
   261  		expectedDefaultBefore     int32
   262  		expectedDefaultNameBefore string
   263  		expectedDefaultAfter      int32
   264  		expectedDefaultNameAfter  string
   265  	}{
   266  		{
   267  			name:                      "simple resolution with a default class",
   268  			classesBefore:             []*scheduling.PriorityClass{defaultClass1},
   269  			classesAfter:              []*scheduling.PriorityClass{defaultClass1},
   270  			attributes:                nil,
   271  			expectedDefaultBefore:     defaultClass1.Value,
   272  			expectedDefaultNameBefore: defaultClass1.Name,
   273  			expectedDefaultAfter:      defaultClass1.Value,
   274  			expectedDefaultNameAfter:  defaultClass1.Name,
   275  		},
   276  		{
   277  			name:                      "add a default class",
   278  			classesBefore:             []*scheduling.PriorityClass{nondefaultClass1},
   279  			classesAfter:              []*scheduling.PriorityClass{nondefaultClass1, defaultClass1},
   280  			attributes:                admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, &metav1.CreateOptions{}, false, nil),
   281  			expectedDefaultBefore:     scheduling.DefaultPriorityWhenNoDefaultClassExists,
   282  			expectedDefaultNameBefore: "",
   283  			expectedDefaultAfter:      defaultClass1.Value,
   284  			expectedDefaultNameAfter:  defaultClass1.Name,
   285  		},
   286  		{
   287  			name:                      "multiple default classes resolves to the minimum value among them",
   288  			classesBefore:             []*scheduling.PriorityClass{defaultClass1, defaultClass2},
   289  			classesAfter:              []*scheduling.PriorityClass{defaultClass2},
   290  			attributes:                admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, &metav1.DeleteOptions{}, false, nil),
   291  			expectedDefaultBefore:     defaultClass1.Value,
   292  			expectedDefaultNameBefore: defaultClass1.Name,
   293  			expectedDefaultAfter:      defaultClass2.Value,
   294  			expectedDefaultNameAfter:  defaultClass2.Name,
   295  		},
   296  		{
   297  			name:                      "delete default priority class",
   298  			classesBefore:             []*scheduling.PriorityClass{defaultClass1},
   299  			classesAfter:              []*scheduling.PriorityClass{},
   300  			attributes:                admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, &metav1.DeleteOptions{}, false, nil),
   301  			expectedDefaultBefore:     defaultClass1.Value,
   302  			expectedDefaultNameBefore: defaultClass1.Name,
   303  			expectedDefaultAfter:      scheduling.DefaultPriorityWhenNoDefaultClassExists,
   304  			expectedDefaultNameAfter:  "",
   305  		},
   306  		{
   307  			name:                      "update default class and remove its global default",
   308  			classesBefore:             []*scheduling.PriorityClass{defaultClass1},
   309  			classesAfter:              []*scheduling.PriorityClass{&updatedDefaultClass1},
   310  			attributes:                admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, &metav1.UpdateOptions{}, false, nil),
   311  			expectedDefaultBefore:     defaultClass1.Value,
   312  			expectedDefaultNameBefore: defaultClass1.Name,
   313  			expectedDefaultAfter:      scheduling.DefaultPriorityWhenNoDefaultClassExists,
   314  			expectedDefaultNameAfter:  "",
   315  		},
   316  	}
   317  
   318  	for _, test := range tests {
   319  		klog.V(4).Infof("starting test %q", test.name)
   320  		ctrl := NewPlugin()
   321  		if err := addPriorityClasses(ctrl, test.classesBefore); err != nil {
   322  			t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
   323  		}
   324  		pcName, defaultPriority, _, err := ctrl.getDefaultPriority()
   325  		if err != nil {
   326  			t.Errorf("Test %q: unexpected error while getting default priority: %v", test.name, err)
   327  		}
   328  		if err == nil &&
   329  			(defaultPriority != test.expectedDefaultBefore || pcName != test.expectedDefaultNameBefore) {
   330  			t.Errorf("Test %q: expected default priority %s(%d), but got %s(%d)",
   331  				test.name, test.expectedDefaultNameBefore, test.expectedDefaultBefore, pcName, defaultPriority)
   332  		}
   333  		if test.attributes != nil {
   334  			err := ctrl.Validate(context.TODO(), test.attributes, nil)
   335  			if err != nil {
   336  				t.Errorf("Test %q: unexpected error received: %v", test.name, err)
   337  			}
   338  		}
   339  		if err := addPriorityClasses(ctrl, test.classesAfter); err != nil {
   340  			t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
   341  		}
   342  		pcName, defaultPriority, _, err = ctrl.getDefaultPriority()
   343  		if err != nil {
   344  			t.Errorf("Test %q: unexpected error while getting default priority: %v", test.name, err)
   345  		}
   346  		if err == nil &&
   347  			(defaultPriority != test.expectedDefaultAfter || pcName != test.expectedDefaultNameAfter) {
   348  			t.Errorf("Test %q: expected default priority %s(%d), but got %s(%d)",
   349  				test.name, test.expectedDefaultNameAfter, test.expectedDefaultAfter, pcName, defaultPriority)
   350  		}
   351  	}
   352  }
   353  
   354  var zeroPriority = int32(0)
   355  var intPriority = int32(1000)
   356  
   357  func TestPodAdmission(t *testing.T) {
   358  	containerName := "container"
   359  
   360  	pods := []*api.Pod{
   361  		// pod[0]: Pod with a proper priority class.
   362  		{
   363  			ObjectMeta: metav1.ObjectMeta{
   364  				Name:      "pod-w-priorityclass",
   365  				Namespace: "namespace",
   366  			},
   367  			Spec: api.PodSpec{
   368  				Containers: []api.Container{
   369  					{
   370  						Name: containerName,
   371  					},
   372  				},
   373  				PriorityClassName: "default1",
   374  			},
   375  		},
   376  		// pod[1]: Pod with no priority class
   377  		{
   378  			ObjectMeta: metav1.ObjectMeta{
   379  				Name:      "pod-wo-priorityclass",
   380  				Namespace: "namespace",
   381  			},
   382  			Spec: api.PodSpec{
   383  				Containers: []api.Container{
   384  					{
   385  						Name: containerName,
   386  					},
   387  				},
   388  			},
   389  		},
   390  		// pod[2]: Pod with non-existing priority class
   391  		{
   392  			ObjectMeta: metav1.ObjectMeta{
   393  				Name:      "pod-w-non-existing-priorityclass",
   394  				Namespace: "namespace",
   395  			},
   396  			Spec: api.PodSpec{
   397  				Containers: []api.Container{
   398  					{
   399  						Name: containerName,
   400  					},
   401  				},
   402  				PriorityClassName: "non-existing",
   403  			},
   404  		},
   405  		// pod[3]: Pod with integer value of priority
   406  		{
   407  			ObjectMeta: metav1.ObjectMeta{
   408  				Name:      "pod-w-integer-priority",
   409  				Namespace: "namespace",
   410  			},
   411  			Spec: api.PodSpec{
   412  				Containers: []api.Container{
   413  					{
   414  						Name: containerName,
   415  					},
   416  				},
   417  				PriorityClassName: "default1",
   418  				Priority:          &intPriority,
   419  			},
   420  		},
   421  		// pod[4]: Pod with a system priority class name
   422  		{
   423  			ObjectMeta: metav1.ObjectMeta{
   424  				Name:      "pod-w-system-priority",
   425  				Namespace: metav1.NamespaceSystem,
   426  			},
   427  			Spec: api.PodSpec{
   428  				Containers: []api.Container{
   429  					{
   430  						Name: containerName,
   431  					},
   432  				},
   433  				PriorityClassName: scheduling.SystemClusterCritical,
   434  			},
   435  		},
   436  		// pod[5]: mirror Pod with a system priority class name
   437  		{
   438  			ObjectMeta: metav1.ObjectMeta{
   439  				Name:        "mirror-pod-w-system-priority",
   440  				Namespace:   metav1.NamespaceSystem,
   441  				Annotations: map[string]string{api.MirrorPodAnnotationKey: ""},
   442  			},
   443  			Spec: api.PodSpec{
   444  				Containers: []api.Container{
   445  					{
   446  						Name: containerName,
   447  					},
   448  				},
   449  				PriorityClassName: "system-cluster-critical",
   450  			},
   451  		},
   452  		// pod[6]: mirror Pod with integer value of priority
   453  		{
   454  			ObjectMeta: metav1.ObjectMeta{
   455  				Name:        "mirror-pod-w-integer-priority",
   456  				Namespace:   "namespace",
   457  				Annotations: map[string]string{api.MirrorPodAnnotationKey: ""},
   458  			},
   459  			Spec: api.PodSpec{
   460  				Containers: []api.Container{
   461  					{
   462  						Name: containerName,
   463  					},
   464  				},
   465  				PriorityClassName: "default1",
   466  				Priority:          &intPriority,
   467  			},
   468  		},
   469  		// pod[7]: Pod with a system priority class name in non-system namespace
   470  		{
   471  			ObjectMeta: metav1.ObjectMeta{
   472  				Name:      "pod-w-system-priority-in-nonsystem-namespace",
   473  				Namespace: "non-system-namespace",
   474  			},
   475  			Spec: api.PodSpec{
   476  				Containers: []api.Container{
   477  					{
   478  						Name: containerName,
   479  					},
   480  				},
   481  				PriorityClassName: scheduling.SystemClusterCritical,
   482  			},
   483  		},
   484  		// pod[8]: Pod with a priority value that matches the resolved priority
   485  		{
   486  			ObjectMeta: metav1.ObjectMeta{
   487  				Name:      "pod-w-zero-priority-in-nonsystem-namespace",
   488  				Namespace: "non-system-namespace",
   489  			},
   490  			Spec: api.PodSpec{
   491  				Containers: []api.Container{
   492  					{
   493  						Name: containerName,
   494  					},
   495  				},
   496  				Priority: &zeroPriority,
   497  			},
   498  		},
   499  		// pod[9]: Pod with a priority value that matches the resolved default priority
   500  		{
   501  			ObjectMeta: metav1.ObjectMeta{
   502  				Name:      "pod-w-priority-matching-default-priority",
   503  				Namespace: "non-system-namespace",
   504  			},
   505  			Spec: api.PodSpec{
   506  				Containers: []api.Container{
   507  					{
   508  						Name: containerName,
   509  					},
   510  				},
   511  				Priority: &defaultClass2.Value,
   512  			},
   513  		},
   514  		// pod[10]: Pod with a priority value that matches the resolved priority
   515  		{
   516  			ObjectMeta: metav1.ObjectMeta{
   517  				Name:      "pod-w-priority-matching-resolved-default-priority",
   518  				Namespace: metav1.NamespaceSystem,
   519  			},
   520  			Spec: api.PodSpec{
   521  				Containers: []api.Container{
   522  					{
   523  						Name: containerName,
   524  					},
   525  				},
   526  				PriorityClassName: systemClusterCritical.Name,
   527  				Priority:          &systemClusterCritical.Value,
   528  			},
   529  		},
   530  		// pod[11]: Pod without a preemption policy that matches the resolved preemption policy
   531  		{
   532  			ObjectMeta: metav1.ObjectMeta{
   533  				Name:      "pod-never-preemption-policy-matching-resolved-preemption-policy",
   534  				Namespace: metav1.NamespaceSystem,
   535  			},
   536  			Spec: api.PodSpec{
   537  				Containers: []api.Container{
   538  					{
   539  						Name: containerName,
   540  					},
   541  				},
   542  				PriorityClassName: neverPreemptionPolicyClass.Name,
   543  				Priority:          &neverPreemptionPolicyClass.Value,
   544  				PreemptionPolicy:  nil,
   545  			},
   546  		},
   547  		// pod[12]: Pod with a preemption policy that matches the resolved preemption policy
   548  		{
   549  			ObjectMeta: metav1.ObjectMeta{
   550  				Name:      "pod-preemption-policy-matching-resolved-preemption-policy",
   551  				Namespace: metav1.NamespaceSystem,
   552  			},
   553  			Spec: api.PodSpec{
   554  				Containers: []api.Container{
   555  					{
   556  						Name: containerName,
   557  					},
   558  				},
   559  				PriorityClassName: preemptionPolicyClass.Name,
   560  				Priority:          &preemptionPolicyClass.Value,
   561  				PreemptionPolicy:  &preemptLowerPriority,
   562  			},
   563  		},
   564  		// pod[13]: Pod with a preemption policy that does't match the resolved preemption policy
   565  		{
   566  			ObjectMeta: metav1.ObjectMeta{
   567  				Name:      "pod-preemption-policy-not-matching-resolved-preemption-policy",
   568  				Namespace: metav1.NamespaceSystem,
   569  			},
   570  			Spec: api.PodSpec{
   571  				Containers: []api.Container{
   572  					{
   573  						Name: containerName,
   574  					},
   575  				},
   576  				PriorityClassName: preemptionPolicyClass.Name,
   577  				Priority:          &preemptionPolicyClass.Value,
   578  				PreemptionPolicy:  &preemptNever,
   579  			},
   580  		},
   581  	}
   582  
   583  	tests := []struct {
   584  		name            string
   585  		existingClasses []*scheduling.PriorityClass
   586  		// Admission controller changes pod spec. So, we take an api.Pod instead of
   587  		// *api.Pod to avoid interfering with other tests.
   588  		pod                    api.Pod
   589  		expectedPriority       int32
   590  		expectError            bool
   591  		expectPreemptionPolicy *api.PreemptionPolicy
   592  	}{
   593  		{
   594  			"Pod with priority class",
   595  			[]*scheduling.PriorityClass{defaultClass1, nondefaultClass1},
   596  			*pods[0],
   597  			1000,
   598  			false,
   599  			nil,
   600  		},
   601  
   602  		{
   603  			"Pod without priority class",
   604  			[]*scheduling.PriorityClass{defaultClass1},
   605  			*pods[1],
   606  			1000,
   607  			false,
   608  			nil,
   609  		},
   610  		{
   611  			"pod without priority class and no existing priority class",
   612  			[]*scheduling.PriorityClass{},
   613  			*pods[1],
   614  			scheduling.DefaultPriorityWhenNoDefaultClassExists,
   615  			false,
   616  			nil,
   617  		},
   618  		{
   619  			"pod without priority class and no default class",
   620  			[]*scheduling.PriorityClass{nondefaultClass1},
   621  			*pods[1],
   622  			scheduling.DefaultPriorityWhenNoDefaultClassExists,
   623  			false,
   624  			nil,
   625  		},
   626  		{
   627  			"pod with a system priority class",
   628  			[]*scheduling.PriorityClass{systemClusterCritical},
   629  			*pods[4],
   630  			scheduling.SystemCriticalPriority,
   631  			false,
   632  			nil,
   633  		},
   634  		{
   635  			"Pod with non-existing priority class",
   636  			[]*scheduling.PriorityClass{defaultClass1, nondefaultClass1},
   637  			*pods[2],
   638  			0,
   639  			true,
   640  			nil,
   641  		},
   642  		{
   643  			"pod with integer priority",
   644  			[]*scheduling.PriorityClass{},
   645  			*pods[3],
   646  			0,
   647  			true,
   648  			nil,
   649  		},
   650  		{
   651  			"mirror pod with system priority class",
   652  			[]*scheduling.PriorityClass{systemClusterCritical},
   653  			*pods[5],
   654  			scheduling.SystemCriticalPriority,
   655  			false,
   656  			nil,
   657  		},
   658  		{
   659  			"mirror pod with integer priority",
   660  			[]*scheduling.PriorityClass{},
   661  			*pods[6],
   662  			0,
   663  			true,
   664  			nil,
   665  		},
   666  		{
   667  			"pod with system critical priority in non-system namespace",
   668  			[]*scheduling.PriorityClass{systemClusterCritical},
   669  			*pods[7],
   670  			scheduling.SystemCriticalPriority,
   671  			false,
   672  			nil,
   673  		},
   674  		{
   675  			"pod with priority that matches computed priority",
   676  			[]*scheduling.PriorityClass{nondefaultClass1},
   677  			*pods[8],
   678  			0,
   679  			false,
   680  			nil,
   681  		},
   682  		{
   683  			"pod with priority that matches default priority",
   684  			[]*scheduling.PriorityClass{defaultClass2},
   685  			*pods[9],
   686  			defaultClass2.Value,
   687  			false,
   688  			nil,
   689  		},
   690  		{
   691  			"pod with priority that matches resolved priority",
   692  			[]*scheduling.PriorityClass{systemClusterCritical},
   693  			*pods[10],
   694  			systemClusterCritical.Value,
   695  			false,
   696  			nil,
   697  		},
   698  		{
   699  			"pod with nil preemtpion policy",
   700  			[]*scheduling.PriorityClass{preemptionPolicyClass},
   701  			*pods[11],
   702  			preemptionPolicyClass.Value,
   703  			false,
   704  			nil,
   705  		},
   706  		{
   707  			"pod with preemtpion policy that matches resolved preemtpion policy",
   708  			[]*scheduling.PriorityClass{preemptionPolicyClass},
   709  			*pods[12],
   710  			preemptionPolicyClass.Value,
   711  			false,
   712  			&preemptLowerPriority,
   713  		},
   714  		{
   715  			"pod with preemtpion policy that does't matches resolved preemtpion policy",
   716  			[]*scheduling.PriorityClass{preemptionPolicyClass},
   717  			*pods[13],
   718  			preemptionPolicyClass.Value,
   719  			true,
   720  			&preemptLowerPriority,
   721  		},
   722  	}
   723  
   724  	for _, test := range tests {
   725  		klog.V(4).Infof("starting test %q", test.name)
   726  		ctrl := NewPlugin()
   727  		// Add existing priority classes.
   728  		if err := addPriorityClasses(ctrl, test.existingClasses); err != nil {
   729  			t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
   730  		}
   731  
   732  		// Create pod.
   733  		attrs := admission.NewAttributesRecord(
   734  			&test.pod,
   735  			nil,
   736  			api.Kind("Pod").WithVersion("version"),
   737  			test.pod.ObjectMeta.Namespace,
   738  			"",
   739  			api.Resource("pods").WithVersion("version"),
   740  			"",
   741  			admission.Create,
   742  			&metav1.CreateOptions{},
   743  			false,
   744  			nil,
   745  		)
   746  		err := admissiontesting.WithReinvocationTesting(t, ctrl).Admit(context.TODO(), attrs, nil)
   747  		klog.Infof("Got %v", err)
   748  
   749  		if !test.expectError {
   750  			if err != nil {
   751  				t.Errorf("Test %q: unexpected error received: %v", test.name, err)
   752  			} else if *test.pod.Spec.Priority != test.expectedPriority {
   753  				t.Errorf("Test %q: expected priority is %d, but got %d.", test.name, test.expectedPriority, *test.pod.Spec.Priority)
   754  			} else if test.pod.Spec.PreemptionPolicy != nil && test.expectPreemptionPolicy != nil && *test.pod.Spec.PreemptionPolicy != *test.expectPreemptionPolicy {
   755  				t.Errorf("Test %q: expected preemption policy is %s, but got %s.", test.name, *test.expectPreemptionPolicy, *test.pod.Spec.PreemptionPolicy)
   756  			}
   757  		}
   758  		if err == nil && test.expectError {
   759  			t.Errorf("Test %q: expected error and no error recevied", test.name)
   760  		}
   761  	}
   762  }
   763  

View as plain text