admission_test.go 21 KB

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