helpers_linux_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. // +build linux
  2. /*
  3. Copyright 2015 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. */
  14. package cm
  15. import (
  16. "reflect"
  17. "strconv"
  18. "testing"
  19. "time"
  20. "k8s.io/api/core/v1"
  21. "k8s.io/apimachinery/pkg/api/resource"
  22. utilfeature "k8s.io/apiserver/pkg/util/feature"
  23. featuregatetesting "k8s.io/component-base/featuregate/testing"
  24. pkgfeatures "k8s.io/kubernetes/pkg/features"
  25. )
  26. // getResourceList returns a ResourceList with the
  27. // specified cpu and memory resource values
  28. func getResourceList(cpu, memory string) v1.ResourceList {
  29. res := v1.ResourceList{}
  30. if cpu != "" {
  31. res[v1.ResourceCPU] = resource.MustParse(cpu)
  32. }
  33. if memory != "" {
  34. res[v1.ResourceMemory] = resource.MustParse(memory)
  35. }
  36. return res
  37. }
  38. // getResourceRequirements returns a ResourceRequirements object
  39. func getResourceRequirements(requests, limits v1.ResourceList) v1.ResourceRequirements {
  40. res := v1.ResourceRequirements{}
  41. res.Requests = requests
  42. res.Limits = limits
  43. return res
  44. }
  45. func TestResourceConfigForPod(t *testing.T) {
  46. defaultQuotaPeriod := uint64(100 * time.Millisecond / time.Microsecond)
  47. tunedQuotaPeriod := uint64(5 * time.Millisecond / time.Microsecond)
  48. minShares := uint64(MinShares)
  49. burstableShares := MilliCPUToShares(100)
  50. memoryQuantity := resource.MustParse("200Mi")
  51. burstableMemory := memoryQuantity.Value()
  52. burstablePartialShares := MilliCPUToShares(200)
  53. burstableQuota := MilliCPUToQuota(200, int64(defaultQuotaPeriod))
  54. guaranteedShares := MilliCPUToShares(100)
  55. guaranteedQuota := MilliCPUToQuota(100, int64(defaultQuotaPeriod))
  56. guaranteedTunedQuota := MilliCPUToQuota(100, int64(tunedQuotaPeriod))
  57. memoryQuantity = resource.MustParse("100Mi")
  58. cpuNoLimit := int64(-1)
  59. guaranteedMemory := memoryQuantity.Value()
  60. testCases := map[string]struct {
  61. pod *v1.Pod
  62. expected *ResourceConfig
  63. enforceCPULimits bool
  64. quotaPeriod uint64
  65. }{
  66. "besteffort": {
  67. pod: &v1.Pod{
  68. Spec: v1.PodSpec{
  69. Containers: []v1.Container{
  70. {
  71. Resources: getResourceRequirements(getResourceList("", ""), getResourceList("", "")),
  72. },
  73. },
  74. },
  75. },
  76. enforceCPULimits: true,
  77. quotaPeriod: defaultQuotaPeriod,
  78. expected: &ResourceConfig{CpuShares: &minShares},
  79. },
  80. "burstable-no-limits": {
  81. pod: &v1.Pod{
  82. Spec: v1.PodSpec{
  83. Containers: []v1.Container{
  84. {
  85. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("", "")),
  86. },
  87. },
  88. },
  89. },
  90. enforceCPULimits: true,
  91. quotaPeriod: defaultQuotaPeriod,
  92. expected: &ResourceConfig{CpuShares: &burstableShares},
  93. },
  94. "burstable-with-limits": {
  95. pod: &v1.Pod{
  96. Spec: v1.PodSpec{
  97. Containers: []v1.Container{
  98. {
  99. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  100. },
  101. },
  102. },
  103. },
  104. enforceCPULimits: true,
  105. quotaPeriod: defaultQuotaPeriod,
  106. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &burstableQuota, CpuPeriod: &defaultQuotaPeriod, Memory: &burstableMemory},
  107. },
  108. "burstable-with-limits-no-cpu-enforcement": {
  109. pod: &v1.Pod{
  110. Spec: v1.PodSpec{
  111. Containers: []v1.Container{
  112. {
  113. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  114. },
  115. },
  116. },
  117. },
  118. enforceCPULimits: false,
  119. quotaPeriod: defaultQuotaPeriod,
  120. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &cpuNoLimit, CpuPeriod: &defaultQuotaPeriod, Memory: &burstableMemory},
  121. },
  122. "burstable-partial-limits": {
  123. pod: &v1.Pod{
  124. Spec: v1.PodSpec{
  125. Containers: []v1.Container{
  126. {
  127. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  128. },
  129. {
  130. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("", "")),
  131. },
  132. },
  133. },
  134. },
  135. enforceCPULimits: true,
  136. quotaPeriod: defaultQuotaPeriod,
  137. expected: &ResourceConfig{CpuShares: &burstablePartialShares},
  138. },
  139. "burstable-with-limits-with-tuned-quota": {
  140. pod: &v1.Pod{
  141. Spec: v1.PodSpec{
  142. Containers: []v1.Container{
  143. {
  144. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  145. },
  146. },
  147. },
  148. },
  149. enforceCPULimits: true,
  150. quotaPeriod: tunedQuotaPeriod,
  151. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &burstableQuota, CpuPeriod: &tunedQuotaPeriod, Memory: &burstableMemory},
  152. },
  153. "burstable-with-limits-no-cpu-enforcement-with-tuned-quota": {
  154. pod: &v1.Pod{
  155. Spec: v1.PodSpec{
  156. Containers: []v1.Container{
  157. {
  158. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  159. },
  160. },
  161. },
  162. },
  163. enforceCPULimits: false,
  164. quotaPeriod: tunedQuotaPeriod,
  165. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &cpuNoLimit, CpuPeriod: &tunedQuotaPeriod, Memory: &burstableMemory},
  166. },
  167. "burstable-partial-limits-with-tuned-quota": {
  168. pod: &v1.Pod{
  169. Spec: v1.PodSpec{
  170. Containers: []v1.Container{
  171. {
  172. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  173. },
  174. {
  175. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("", "")),
  176. },
  177. },
  178. },
  179. },
  180. enforceCPULimits: true,
  181. quotaPeriod: tunedQuotaPeriod,
  182. expected: &ResourceConfig{CpuShares: &burstablePartialShares},
  183. },
  184. "guaranteed": {
  185. pod: &v1.Pod{
  186. Spec: v1.PodSpec{
  187. Containers: []v1.Container{
  188. {
  189. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  190. },
  191. },
  192. },
  193. },
  194. enforceCPULimits: true,
  195. quotaPeriod: defaultQuotaPeriod,
  196. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &guaranteedQuota, CpuPeriod: &defaultQuotaPeriod, Memory: &guaranteedMemory},
  197. },
  198. "guaranteed-no-cpu-enforcement": {
  199. pod: &v1.Pod{
  200. Spec: v1.PodSpec{
  201. Containers: []v1.Container{
  202. {
  203. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  204. },
  205. },
  206. },
  207. },
  208. enforceCPULimits: false,
  209. quotaPeriod: defaultQuotaPeriod,
  210. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &cpuNoLimit, CpuPeriod: &defaultQuotaPeriod, Memory: &guaranteedMemory},
  211. },
  212. "guaranteed-with-tuned-quota": {
  213. pod: &v1.Pod{
  214. Spec: v1.PodSpec{
  215. Containers: []v1.Container{
  216. {
  217. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  218. },
  219. },
  220. },
  221. },
  222. enforceCPULimits: true,
  223. quotaPeriod: tunedQuotaPeriod,
  224. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &guaranteedTunedQuota, CpuPeriod: &tunedQuotaPeriod, Memory: &guaranteedMemory},
  225. },
  226. "guaranteed-no-cpu-enforcement-with-tuned-quota": {
  227. pod: &v1.Pod{
  228. Spec: v1.PodSpec{
  229. Containers: []v1.Container{
  230. {
  231. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  232. },
  233. },
  234. },
  235. },
  236. enforceCPULimits: false,
  237. quotaPeriod: tunedQuotaPeriod,
  238. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &cpuNoLimit, CpuPeriod: &tunedQuotaPeriod, Memory: &guaranteedMemory},
  239. },
  240. }
  241. for testName, testCase := range testCases {
  242. actual := ResourceConfigForPod(testCase.pod, testCase.enforceCPULimits, testCase.quotaPeriod)
  243. if !reflect.DeepEqual(actual.CpuPeriod, testCase.expected.CpuPeriod) {
  244. t.Errorf("unexpected result, test: %v, cpu period not as expected", testName)
  245. }
  246. if !reflect.DeepEqual(actual.CpuQuota, testCase.expected.CpuQuota) {
  247. t.Errorf("unexpected result, test: %v, cpu quota not as expected", testName)
  248. }
  249. if !reflect.DeepEqual(actual.CpuShares, testCase.expected.CpuShares) {
  250. t.Errorf("unexpected result, test: %v, cpu shares not as expected", testName)
  251. }
  252. if !reflect.DeepEqual(actual.Memory, testCase.expected.Memory) {
  253. t.Errorf("unexpected result, test: %v, memory not as expected", testName)
  254. }
  255. }
  256. }
  257. func TestResourceConfigForPodWithCustomCPUCFSQuotaPeriod(t *testing.T) {
  258. defaultQuotaPeriod := uint64(100 * time.Millisecond / time.Microsecond)
  259. tunedQuotaPeriod := uint64(5 * time.Millisecond / time.Microsecond)
  260. tunedQuota := int64(1 * time.Millisecond / time.Microsecond)
  261. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.CPUCFSQuotaPeriod, true)()
  262. minShares := uint64(MinShares)
  263. burstableShares := MilliCPUToShares(100)
  264. memoryQuantity := resource.MustParse("200Mi")
  265. burstableMemory := memoryQuantity.Value()
  266. burstablePartialShares := MilliCPUToShares(200)
  267. burstableQuota := MilliCPUToQuota(200, int64(defaultQuotaPeriod))
  268. guaranteedShares := MilliCPUToShares(100)
  269. guaranteedQuota := MilliCPUToQuota(100, int64(defaultQuotaPeriod))
  270. guaranteedTunedQuota := MilliCPUToQuota(100, int64(tunedQuotaPeriod))
  271. memoryQuantity = resource.MustParse("100Mi")
  272. cpuNoLimit := int64(-1)
  273. guaranteedMemory := memoryQuantity.Value()
  274. testCases := map[string]struct {
  275. pod *v1.Pod
  276. expected *ResourceConfig
  277. enforceCPULimits bool
  278. quotaPeriod uint64
  279. }{
  280. "besteffort": {
  281. pod: &v1.Pod{
  282. Spec: v1.PodSpec{
  283. Containers: []v1.Container{
  284. {
  285. Resources: getResourceRequirements(getResourceList("", ""), getResourceList("", "")),
  286. },
  287. },
  288. },
  289. },
  290. enforceCPULimits: true,
  291. quotaPeriod: defaultQuotaPeriod,
  292. expected: &ResourceConfig{CpuShares: &minShares},
  293. },
  294. "burstable-no-limits": {
  295. pod: &v1.Pod{
  296. Spec: v1.PodSpec{
  297. Containers: []v1.Container{
  298. {
  299. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("", "")),
  300. },
  301. },
  302. },
  303. },
  304. enforceCPULimits: true,
  305. quotaPeriod: defaultQuotaPeriod,
  306. expected: &ResourceConfig{CpuShares: &burstableShares},
  307. },
  308. "burstable-with-limits": {
  309. pod: &v1.Pod{
  310. Spec: v1.PodSpec{
  311. Containers: []v1.Container{
  312. {
  313. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  314. },
  315. },
  316. },
  317. },
  318. enforceCPULimits: true,
  319. quotaPeriod: defaultQuotaPeriod,
  320. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &burstableQuota, CpuPeriod: &defaultQuotaPeriod, Memory: &burstableMemory},
  321. },
  322. "burstable-with-limits-no-cpu-enforcement": {
  323. pod: &v1.Pod{
  324. Spec: v1.PodSpec{
  325. Containers: []v1.Container{
  326. {
  327. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  328. },
  329. },
  330. },
  331. },
  332. enforceCPULimits: false,
  333. quotaPeriod: defaultQuotaPeriod,
  334. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &cpuNoLimit, CpuPeriod: &defaultQuotaPeriod, Memory: &burstableMemory},
  335. },
  336. "burstable-partial-limits": {
  337. pod: &v1.Pod{
  338. Spec: v1.PodSpec{
  339. Containers: []v1.Container{
  340. {
  341. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  342. },
  343. {
  344. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("", "")),
  345. },
  346. },
  347. },
  348. },
  349. enforceCPULimits: true,
  350. quotaPeriod: defaultQuotaPeriod,
  351. expected: &ResourceConfig{CpuShares: &burstablePartialShares},
  352. },
  353. "burstable-with-limits-with-tuned-quota": {
  354. pod: &v1.Pod{
  355. Spec: v1.PodSpec{
  356. Containers: []v1.Container{
  357. {
  358. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  359. },
  360. },
  361. },
  362. },
  363. enforceCPULimits: true,
  364. quotaPeriod: tunedQuotaPeriod,
  365. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &tunedQuota, CpuPeriod: &tunedQuotaPeriod, Memory: &burstableMemory},
  366. },
  367. "burstable-with-limits-no-cpu-enforcement-with-tuned-quota": {
  368. pod: &v1.Pod{
  369. Spec: v1.PodSpec{
  370. Containers: []v1.Container{
  371. {
  372. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  373. },
  374. },
  375. },
  376. },
  377. enforceCPULimits: false,
  378. quotaPeriod: tunedQuotaPeriod,
  379. expected: &ResourceConfig{CpuShares: &burstableShares, CpuQuota: &cpuNoLimit, CpuPeriod: &tunedQuotaPeriod, Memory: &burstableMemory},
  380. },
  381. "burstable-partial-limits-with-tuned-quota": {
  382. pod: &v1.Pod{
  383. Spec: v1.PodSpec{
  384. Containers: []v1.Container{
  385. {
  386. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("200m", "200Mi")),
  387. },
  388. {
  389. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("", "")),
  390. },
  391. },
  392. },
  393. },
  394. enforceCPULimits: true,
  395. quotaPeriod: tunedQuotaPeriod,
  396. expected: &ResourceConfig{CpuShares: &burstablePartialShares},
  397. },
  398. "guaranteed": {
  399. pod: &v1.Pod{
  400. Spec: v1.PodSpec{
  401. Containers: []v1.Container{
  402. {
  403. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  404. },
  405. },
  406. },
  407. },
  408. enforceCPULimits: true,
  409. quotaPeriod: defaultQuotaPeriod,
  410. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &guaranteedQuota, CpuPeriod: &defaultQuotaPeriod, Memory: &guaranteedMemory},
  411. },
  412. "guaranteed-no-cpu-enforcement": {
  413. pod: &v1.Pod{
  414. Spec: v1.PodSpec{
  415. Containers: []v1.Container{
  416. {
  417. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  418. },
  419. },
  420. },
  421. },
  422. enforceCPULimits: false,
  423. quotaPeriod: defaultQuotaPeriod,
  424. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &cpuNoLimit, CpuPeriod: &defaultQuotaPeriod, Memory: &guaranteedMemory},
  425. },
  426. "guaranteed-with-tuned-quota": {
  427. pod: &v1.Pod{
  428. Spec: v1.PodSpec{
  429. Containers: []v1.Container{
  430. {
  431. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  432. },
  433. },
  434. },
  435. },
  436. enforceCPULimits: true,
  437. quotaPeriod: tunedQuotaPeriod,
  438. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &guaranteedTunedQuota, CpuPeriod: &tunedQuotaPeriod, Memory: &guaranteedMemory},
  439. },
  440. "guaranteed-no-cpu-enforcement-with-tuned-quota": {
  441. pod: &v1.Pod{
  442. Spec: v1.PodSpec{
  443. Containers: []v1.Container{
  444. {
  445. Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
  446. },
  447. },
  448. },
  449. },
  450. enforceCPULimits: false,
  451. quotaPeriod: tunedQuotaPeriod,
  452. expected: &ResourceConfig{CpuShares: &guaranteedShares, CpuQuota: &cpuNoLimit, CpuPeriod: &tunedQuotaPeriod, Memory: &guaranteedMemory},
  453. },
  454. }
  455. for testName, testCase := range testCases {
  456. actual := ResourceConfigForPod(testCase.pod, testCase.enforceCPULimits, testCase.quotaPeriod)
  457. if !reflect.DeepEqual(actual.CpuPeriod, testCase.expected.CpuPeriod) {
  458. t.Errorf("unexpected result, test: %v, cpu period not as expected", testName)
  459. }
  460. if !reflect.DeepEqual(actual.CpuQuota, testCase.expected.CpuQuota) {
  461. t.Errorf("unexpected result, test: %v, cpu quota not as expected", testName)
  462. }
  463. if !reflect.DeepEqual(actual.CpuShares, testCase.expected.CpuShares) {
  464. t.Errorf("unexpected result, test: %v, cpu shares not as expected", testName)
  465. }
  466. if !reflect.DeepEqual(actual.Memory, testCase.expected.Memory) {
  467. t.Errorf("unexpected result, test: %v, memory not as expected", testName)
  468. }
  469. }
  470. }
  471. func TestMilliCPUToQuota(t *testing.T) {
  472. testCases := []struct {
  473. input int64
  474. quota int64
  475. period uint64
  476. }{
  477. {
  478. input: int64(0),
  479. quota: int64(0),
  480. period: uint64(0),
  481. },
  482. {
  483. input: int64(5),
  484. quota: int64(1000),
  485. period: uint64(100000),
  486. },
  487. {
  488. input: int64(9),
  489. quota: int64(1000),
  490. period: uint64(100000),
  491. },
  492. {
  493. input: int64(10),
  494. quota: int64(1000),
  495. period: uint64(100000),
  496. },
  497. {
  498. input: int64(200),
  499. quota: int64(20000),
  500. period: uint64(100000),
  501. },
  502. {
  503. input: int64(500),
  504. quota: int64(50000),
  505. period: uint64(100000),
  506. },
  507. {
  508. input: int64(1000),
  509. quota: int64(100000),
  510. period: uint64(100000),
  511. },
  512. {
  513. input: int64(1500),
  514. quota: int64(150000),
  515. period: uint64(100000),
  516. },
  517. }
  518. for _, testCase := range testCases {
  519. quota := MilliCPUToQuota(testCase.input, int64(testCase.period))
  520. if quota != testCase.quota {
  521. t.Errorf("Input %v and %v, expected quota %v, but got quota %v", testCase.input, testCase.period, testCase.quota, quota)
  522. }
  523. }
  524. }
  525. func TestHugePageLimits(t *testing.T) {
  526. Mi := int64(1024 * 1024)
  527. type inputStruct struct {
  528. key string
  529. input string
  530. }
  531. testCases := []struct {
  532. name string
  533. inputs []inputStruct
  534. expected map[int64]int64
  535. }{
  536. {
  537. name: "no valid hugepages",
  538. inputs: []inputStruct{
  539. {
  540. key: "2Mi",
  541. input: "128",
  542. },
  543. },
  544. expected: map[int64]int64{},
  545. },
  546. {
  547. name: "2Mi only",
  548. inputs: []inputStruct{
  549. {
  550. key: v1.ResourceHugePagesPrefix + "2Mi",
  551. input: "128",
  552. },
  553. },
  554. expected: map[int64]int64{2 * Mi: 128},
  555. },
  556. {
  557. name: "2Mi and 4Mi",
  558. inputs: []inputStruct{
  559. {
  560. key: v1.ResourceHugePagesPrefix + "2Mi",
  561. input: "128",
  562. },
  563. {
  564. key: v1.ResourceHugePagesPrefix + strconv.FormatInt(2*Mi, 10),
  565. input: "256",
  566. },
  567. {
  568. key: v1.ResourceHugePagesPrefix + "4Mi",
  569. input: "512",
  570. },
  571. {
  572. key: "4Mi",
  573. input: "1024",
  574. },
  575. },
  576. expected: map[int64]int64{2 * Mi: 384, 4 * Mi: 512},
  577. },
  578. }
  579. for _, testcase := range testCases {
  580. t.Run(testcase.name, func(t *testing.T) {
  581. resourceList := v1.ResourceList{}
  582. for _, input := range testcase.inputs {
  583. value, err := resource.ParseQuantity(input.input)
  584. if err != nil {
  585. t.Fatalf("error in parsing hugepages, value: %s", input.input)
  586. } else {
  587. resourceList[v1.ResourceName(input.key)] = value
  588. }
  589. }
  590. resultValue := HugePageLimits(resourceList)
  591. if !reflect.DeepEqual(testcase.expected, resultValue) {
  592. t.Errorf("unexpected result, expected: %v, actual: %v", testcase.expected, resultValue)
  593. }
  594. })
  595. }
  596. }