taint_toleration_test.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. Copyright 2014 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 priorities
  14. import (
  15. "reflect"
  16. "testing"
  17. "k8s.io/api/core/v1"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
  20. schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
  21. )
  22. func nodeWithTaints(nodeName string, taints []v1.Taint) *v1.Node {
  23. return &v1.Node{
  24. ObjectMeta: metav1.ObjectMeta{
  25. Name: nodeName,
  26. },
  27. Spec: v1.NodeSpec{
  28. Taints: taints,
  29. },
  30. }
  31. }
  32. func podWithTolerations(tolerations []v1.Toleration) *v1.Pod {
  33. return &v1.Pod{
  34. Spec: v1.PodSpec{
  35. Tolerations: tolerations,
  36. },
  37. }
  38. }
  39. // This function will create a set of nodes and pods and test the priority
  40. // Nodes with zero,one,two,three,four and hundred taints are created
  41. // Pods with zero,one,two,three,four and hundred tolerations are created
  42. func TestTaintAndToleration(t *testing.T) {
  43. tests := []struct {
  44. pod *v1.Pod
  45. nodes []*v1.Node
  46. expectedList schedulerapi.HostPriorityList
  47. name string
  48. }{
  49. // basic test case
  50. {
  51. name: "node with taints tolerated by the pod, gets a higher score than those node with intolerable taints",
  52. pod: podWithTolerations([]v1.Toleration{{
  53. Key: "foo",
  54. Operator: v1.TolerationOpEqual,
  55. Value: "bar",
  56. Effect: v1.TaintEffectPreferNoSchedule,
  57. }}),
  58. nodes: []*v1.Node{
  59. nodeWithTaints("nodeA", []v1.Taint{{
  60. Key: "foo",
  61. Value: "bar",
  62. Effect: v1.TaintEffectPreferNoSchedule,
  63. }}),
  64. nodeWithTaints("nodeB", []v1.Taint{{
  65. Key: "foo",
  66. Value: "blah",
  67. Effect: v1.TaintEffectPreferNoSchedule,
  68. }}),
  69. },
  70. expectedList: []schedulerapi.HostPriority{
  71. {Host: "nodeA", Score: schedulerapi.MaxPriority},
  72. {Host: "nodeB", Score: 0},
  73. },
  74. },
  75. // the count of taints that are tolerated by pod, does not matter.
  76. {
  77. name: "the nodes that all of their taints are tolerated by the pod, get the same score, no matter how many tolerable taints a node has",
  78. pod: podWithTolerations([]v1.Toleration{
  79. {
  80. Key: "cpu-type",
  81. Operator: v1.TolerationOpEqual,
  82. Value: "arm64",
  83. Effect: v1.TaintEffectPreferNoSchedule,
  84. }, {
  85. Key: "disk-type",
  86. Operator: v1.TolerationOpEqual,
  87. Value: "ssd",
  88. Effect: v1.TaintEffectPreferNoSchedule,
  89. },
  90. }),
  91. nodes: []*v1.Node{
  92. nodeWithTaints("nodeA", []v1.Taint{}),
  93. nodeWithTaints("nodeB", []v1.Taint{
  94. {
  95. Key: "cpu-type",
  96. Value: "arm64",
  97. Effect: v1.TaintEffectPreferNoSchedule,
  98. },
  99. }),
  100. nodeWithTaints("nodeC", []v1.Taint{
  101. {
  102. Key: "cpu-type",
  103. Value: "arm64",
  104. Effect: v1.TaintEffectPreferNoSchedule,
  105. }, {
  106. Key: "disk-type",
  107. Value: "ssd",
  108. Effect: v1.TaintEffectPreferNoSchedule,
  109. },
  110. }),
  111. },
  112. expectedList: []schedulerapi.HostPriority{
  113. {Host: "nodeA", Score: schedulerapi.MaxPriority},
  114. {Host: "nodeB", Score: schedulerapi.MaxPriority},
  115. {Host: "nodeC", Score: schedulerapi.MaxPriority},
  116. },
  117. },
  118. // the count of taints on a node that are not tolerated by pod, matters.
  119. {
  120. name: "the more intolerable taints a node has, the lower score it gets.",
  121. pod: podWithTolerations([]v1.Toleration{{
  122. Key: "foo",
  123. Operator: v1.TolerationOpEqual,
  124. Value: "bar",
  125. Effect: v1.TaintEffectPreferNoSchedule,
  126. }}),
  127. nodes: []*v1.Node{
  128. nodeWithTaints("nodeA", []v1.Taint{}),
  129. nodeWithTaints("nodeB", []v1.Taint{
  130. {
  131. Key: "cpu-type",
  132. Value: "arm64",
  133. Effect: v1.TaintEffectPreferNoSchedule,
  134. },
  135. }),
  136. nodeWithTaints("nodeC", []v1.Taint{
  137. {
  138. Key: "cpu-type",
  139. Value: "arm64",
  140. Effect: v1.TaintEffectPreferNoSchedule,
  141. }, {
  142. Key: "disk-type",
  143. Value: "ssd",
  144. Effect: v1.TaintEffectPreferNoSchedule,
  145. },
  146. }),
  147. },
  148. expectedList: []schedulerapi.HostPriority{
  149. {Host: "nodeA", Score: schedulerapi.MaxPriority},
  150. {Host: "nodeB", Score: 5},
  151. {Host: "nodeC", Score: 0},
  152. },
  153. },
  154. // taints-tolerations priority only takes care about the taints and tolerations that have effect PreferNoSchedule
  155. {
  156. name: "only taints and tolerations that have effect PreferNoSchedule are checked by taints-tolerations priority function",
  157. pod: podWithTolerations([]v1.Toleration{
  158. {
  159. Key: "cpu-type",
  160. Operator: v1.TolerationOpEqual,
  161. Value: "arm64",
  162. Effect: v1.TaintEffectNoSchedule,
  163. }, {
  164. Key: "disk-type",
  165. Operator: v1.TolerationOpEqual,
  166. Value: "ssd",
  167. Effect: v1.TaintEffectNoSchedule,
  168. },
  169. }),
  170. nodes: []*v1.Node{
  171. nodeWithTaints("nodeA", []v1.Taint{}),
  172. nodeWithTaints("nodeB", []v1.Taint{
  173. {
  174. Key: "cpu-type",
  175. Value: "arm64",
  176. Effect: v1.TaintEffectNoSchedule,
  177. },
  178. }),
  179. nodeWithTaints("nodeC", []v1.Taint{
  180. {
  181. Key: "cpu-type",
  182. Value: "arm64",
  183. Effect: v1.TaintEffectPreferNoSchedule,
  184. }, {
  185. Key: "disk-type",
  186. Value: "ssd",
  187. Effect: v1.TaintEffectPreferNoSchedule,
  188. },
  189. }),
  190. },
  191. expectedList: []schedulerapi.HostPriority{
  192. {Host: "nodeA", Score: schedulerapi.MaxPriority},
  193. {Host: "nodeB", Score: schedulerapi.MaxPriority},
  194. {Host: "nodeC", Score: 0},
  195. },
  196. },
  197. {
  198. name: "Default behaviour No taints and tolerations, lands on node with no taints",
  199. //pod without tolerations
  200. pod: podWithTolerations([]v1.Toleration{}),
  201. nodes: []*v1.Node{
  202. //Node without taints
  203. nodeWithTaints("nodeA", []v1.Taint{}),
  204. nodeWithTaints("nodeB", []v1.Taint{
  205. {
  206. Key: "cpu-type",
  207. Value: "arm64",
  208. Effect: v1.TaintEffectPreferNoSchedule,
  209. },
  210. }),
  211. },
  212. expectedList: []schedulerapi.HostPriority{
  213. {Host: "nodeA", Score: schedulerapi.MaxPriority},
  214. {Host: "nodeB", Score: 0},
  215. },
  216. },
  217. }
  218. for _, test := range tests {
  219. t.Run(test.name, func(t *testing.T) {
  220. nodeNameToInfo := schedulernodeinfo.CreateNodeNameToInfoMap(nil, test.nodes)
  221. ttp := priorityFunction(ComputeTaintTolerationPriorityMap, ComputeTaintTolerationPriorityReduce, nil)
  222. list, err := ttp(test.pod, nodeNameToInfo, test.nodes)
  223. if err != nil {
  224. t.Errorf("unexpected error: %v", err)
  225. }
  226. if !reflect.DeepEqual(test.expectedList, list) {
  227. t.Errorf("expected:\n\t%+v,\ngot:\n\t%+v", test.expectedList, list)
  228. }
  229. })
  230. }
  231. }