k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/plugin/pkg/admission/priority/admission_test.go (about) 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 }