admission_test.go 21 KB

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