helpers_test.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. Copyright 2015 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 resource
  14. import (
  15. "strings"
  16. "testing"
  17. "k8s.io/apimachinery/pkg/api/resource"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/apimachinery/pkg/util/uuid"
  20. api "k8s.io/kubernetes/pkg/apis/core"
  21. )
  22. func TestResourceHelpers(t *testing.T) {
  23. cpuLimit := resource.MustParse("10")
  24. memoryLimit := resource.MustParse("10G")
  25. resourceSpec := api.ResourceRequirements{
  26. Limits: api.ResourceList{
  27. api.ResourceCPU: cpuLimit,
  28. api.ResourceMemory: memoryLimit,
  29. },
  30. }
  31. if res := resourceSpec.Limits.Cpu(); res.Cmp(cpuLimit) != 0 {
  32. t.Errorf("expected cpulimit %v, got %v", cpuLimit, res)
  33. }
  34. if res := resourceSpec.Limits.Memory(); res.Cmp(memoryLimit) != 0 {
  35. t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
  36. }
  37. resourceSpec = api.ResourceRequirements{
  38. Limits: api.ResourceList{
  39. api.ResourceMemory: memoryLimit,
  40. },
  41. }
  42. if res := resourceSpec.Limits.Cpu(); res.Value() != 0 {
  43. t.Errorf("expected cpulimit %v, got %v", 0, res)
  44. }
  45. if res := resourceSpec.Limits.Memory(); res.Cmp(memoryLimit) != 0 {
  46. t.Errorf("expected memorylimit %v, got %v", memoryLimit, res)
  47. }
  48. }
  49. func TestDefaultResourceHelpers(t *testing.T) {
  50. resourceList := api.ResourceList{}
  51. if resourceList.Cpu().Format != resource.DecimalSI {
  52. t.Errorf("expected %v, actual %v", resource.DecimalSI, resourceList.Cpu().Format)
  53. }
  54. if resourceList.Memory().Format != resource.BinarySI {
  55. t.Errorf("expected %v, actual %v", resource.BinarySI, resourceList.Memory().Format)
  56. }
  57. }
  58. func TestPodRequestsAndLimits(t *testing.T) {
  59. tests := []struct {
  60. name string
  61. pod *api.Pod
  62. expectreqs map[api.ResourceName]resource.Quantity
  63. expectlimits map[api.ResourceName]resource.Quantity
  64. }{
  65. {
  66. name: "InitContainers resource < Containers resource",
  67. pod: &api.Pod{
  68. ObjectMeta: metav1.ObjectMeta{
  69. UID: uuid.NewUUID(),
  70. },
  71. Spec: api.PodSpec{
  72. InitContainers: []api.Container{
  73. makeContainer("100m", "200m", "100Mi", "200Mi"),
  74. },
  75. Containers: []api.Container{
  76. makeContainer("100m", "400m", "100Mi", "400Mi"),
  77. makeContainer("100m", "200m", "100Mi", "200Mi"),
  78. },
  79. },
  80. },
  81. expectreqs: map[api.ResourceName]resource.Quantity{
  82. api.ResourceCPU: resource.MustParse("200m"),
  83. api.ResourceMemory: resource.MustParse("200Mi"),
  84. },
  85. expectlimits: map[api.ResourceName]resource.Quantity{
  86. api.ResourceCPU: resource.MustParse("600m"),
  87. api.ResourceMemory: resource.MustParse("600Mi"),
  88. },
  89. },
  90. {
  91. name: "InitContainers resource > Containers resource",
  92. pod: &api.Pod{
  93. ObjectMeta: metav1.ObjectMeta{
  94. UID: uuid.NewUUID(),
  95. },
  96. Spec: api.PodSpec{
  97. InitContainers: []api.Container{
  98. makeContainer("500m", "500m", "500Mi", "500Mi"),
  99. makeContainer("100m", "200m", "100Mi", "200Mi"),
  100. },
  101. Containers: []api.Container{
  102. makeContainer("100m", "200m", "100Mi", "200Mi"),
  103. makeContainer("100m", "200m", "100Mi", "200Mi"),
  104. },
  105. },
  106. },
  107. expectreqs: map[api.ResourceName]resource.Quantity{
  108. api.ResourceCPU: resource.MustParse("500m"),
  109. api.ResourceMemory: resource.MustParse("500Mi"),
  110. },
  111. expectlimits: map[api.ResourceName]resource.Quantity{
  112. api.ResourceCPU: resource.MustParse("500m"),
  113. api.ResourceMemory: resource.MustParse("500Mi"),
  114. },
  115. },
  116. }
  117. for i, test := range tests {
  118. t.Run(test.name, func(t *testing.T) {
  119. requests, limits := PodRequestsAndLimits(test.pod)
  120. for name, quantity := range test.expectreqs {
  121. if value, ok := requests[name]; !ok {
  122. t.Errorf("case[%d]: Error to get value of key=%s from requests result", i, name)
  123. } else if quantity.Cmp(value) != 0 {
  124. t.Errorf("case[%d]: Expected value of key=%s from requests result:%v, Got:%v", i, name, quantity, value)
  125. }
  126. }
  127. for name, quantity := range test.expectlimits {
  128. if value, ok := limits[name]; !ok {
  129. t.Errorf("case[%d]: Error to get value of key=%s from limits result", i, name)
  130. } else if quantity.Cmp(value) != 0 {
  131. t.Errorf("case[%d]: Expected value of key=%s from limits result:%v, Got:%v", i, name, quantity, value)
  132. }
  133. }
  134. })
  135. }
  136. }
  137. func TestExtractContainerResourceValue(t *testing.T) {
  138. testcontainer := &api.Container{
  139. Name: string(uuid.NewUUID()),
  140. Resources: api.ResourceRequirements{
  141. Limits: api.ResourceList{
  142. api.ResourceCPU: resource.MustParse("200m"),
  143. api.ResourceMemory: resource.MustParse("200Mi"),
  144. api.ResourceStorage: resource.MustParse("2G"),
  145. api.ResourceEphemeralStorage: resource.MustParse("2G"),
  146. },
  147. Requests: api.ResourceList{
  148. api.ResourceCPU: resource.MustParse("100m"),
  149. api.ResourceMemory: resource.MustParse("100Mi"),
  150. api.ResourceStorage: resource.MustParse("1G"),
  151. api.ResourceEphemeralStorage: resource.MustParse("300Mi"),
  152. },
  153. },
  154. }
  155. tests := []struct {
  156. name string
  157. filed *api.ResourceFieldSelector
  158. expectresult string
  159. expecterr string
  160. }{
  161. {
  162. name: "get limits cpu",
  163. filed: &api.ResourceFieldSelector{Resource: "limits.cpu", Divisor: resource.MustParse("1m")},
  164. expectresult: "200",
  165. expecterr: "",
  166. },
  167. {
  168. name: "get limits memory",
  169. filed: &api.ResourceFieldSelector{Resource: "limits.memory"},
  170. expectresult: "209715200",
  171. expecterr: "",
  172. },
  173. {
  174. name: "get limits ephemeral-storage",
  175. filed: &api.ResourceFieldSelector{Resource: "limits.ephemeral-storage", Divisor: resource.MustParse("1G")},
  176. expectresult: "2",
  177. expecterr: "",
  178. },
  179. {
  180. name: "get requests cpu",
  181. filed: &api.ResourceFieldSelector{Resource: "requests.cpu", Divisor: resource.MustParse("1m")},
  182. expectresult: "100",
  183. expecterr: "",
  184. },
  185. {
  186. name: "get requests memory",
  187. filed: &api.ResourceFieldSelector{Resource: "requests.memory", Divisor: resource.MustParse("1G")},
  188. expectresult: "1",
  189. expecterr: "",
  190. },
  191. {
  192. name: "get requests ephemeral-storage",
  193. filed: &api.ResourceFieldSelector{Resource: "requests.ephemeral-storage"},
  194. expectresult: "314572800",
  195. expecterr: "",
  196. },
  197. {
  198. name: "get limits storage",
  199. filed: &api.ResourceFieldSelector{Resource: "limits.storage", Divisor: resource.MustParse("1G")},
  200. expectresult: "",
  201. expecterr: "unsupported container resource",
  202. },
  203. }
  204. for i, test := range tests {
  205. t.Run(test.name, func(t *testing.T) {
  206. result, err := ExtractContainerResourceValue(test.filed, testcontainer)
  207. if test.expecterr != "" {
  208. if !strings.Contains(err.Error(), test.expecterr) {
  209. t.Errorf("case[%d]:%s Expected err:%s, Got err:%s", i, test.name, test.expecterr, err.Error())
  210. }
  211. } else if err != nil {
  212. t.Errorf("case[%d]:%s Expected no err, Got err:%s", i, test.name, err.Error())
  213. }
  214. if result != test.expectresult {
  215. t.Errorf("case[%d]:%s Expected result:%s, Got result:%s", i, test.name, test.expectresult, result)
  216. }
  217. })
  218. }
  219. }
  220. func makeContainer(cpuReq, cpuLim, memReq, memLim string) api.Container {
  221. return api.Container{
  222. Name: string(uuid.NewUUID()),
  223. Resources: api.ResourceRequirements{
  224. Limits: api.ResourceList{
  225. api.ResourceCPU: resource.MustParse(cpuLim),
  226. api.ResourceMemory: resource.MustParse(memLim),
  227. },
  228. Requests: api.ResourceList{
  229. api.ResourceCPU: resource.MustParse(cpuReq),
  230. api.ResourceMemory: resource.MustParse(memReq),
  231. },
  232. },
  233. }
  234. }