1
16
17 package noderesources
18
19 import (
20 "testing"
21
22 v1 "k8s.io/api/core/v1"
23 "k8s.io/apimachinery/pkg/api/resource"
24
25 "k8s.io/kubernetes/pkg/scheduler/util"
26 )
27
28 func TestResourceAllocationScorerCalculateRequests(t *testing.T) {
29 const oneMi = 1048576
30 tests := []struct {
31 name string
32 pod v1.Pod
33 expected map[v1.ResourceName]int64
34 }{
35 {
36 name: "overhead only",
37 pod: v1.Pod{
38 Spec: v1.PodSpec{
39 Overhead: v1.ResourceList{
40 v1.ResourceCPU: resource.MustParse("1"),
41 v1.ResourceMemory: resource.MustParse("1Mi"),
42 },
43 },
44 },
45 expected: map[v1.ResourceName]int64{
46 v1.ResourceCPU: 1000,
47 v1.ResourceMemory: oneMi,
48 },
49 },
50 {
51 name: "1x requestless container",
52 pod: v1.Pod{
53 Spec: v1.PodSpec{
54 Containers: []v1.Container{
55 {},
56 },
57 },
58 },
59 expected: map[v1.ResourceName]int64{
60 v1.ResourceCPU: util.DefaultMilliCPURequest,
61 v1.ResourceMemory: util.DefaultMemoryRequest,
62 },
63 },
64 {
65 name: "2x requestless container",
66 pod: v1.Pod{
67 Spec: v1.PodSpec{
68 Containers: []v1.Container{
69 {}, {},
70 },
71 },
72 },
73
74 expected: map[v1.ResourceName]int64{
75 v1.ResourceCPU: 2 * util.DefaultMilliCPURequest,
76 v1.ResourceMemory: 2 * util.DefaultMemoryRequest,
77 },
78 },
79 {
80 name: "request container + requestless container",
81 pod: v1.Pod{
82 Spec: v1.PodSpec{
83 Containers: []v1.Container{
84 {
85 Resources: v1.ResourceRequirements{
86 Requests: v1.ResourceList{
87 v1.ResourceCPU: resource.MustParse("1"),
88 v1.ResourceMemory: resource.MustParse("1Mi"),
89 },
90 },
91 },
92 {},
93 },
94 },
95 },
96 expected: map[v1.ResourceName]int64{
97 v1.ResourceCPU: 1000 + util.DefaultMilliCPURequest,
98 v1.ResourceMemory: oneMi + util.DefaultMemoryRequest,
99 },
100 },
101 {
102 name: "container + requestless container + overhead",
103 pod: v1.Pod{
104 Spec: v1.PodSpec{
105 Overhead: v1.ResourceList{
106 v1.ResourceCPU: resource.MustParse("1"),
107 v1.ResourceMemory: resource.MustParse("1Mi"),
108 },
109 Containers: []v1.Container{
110 {
111 Resources: v1.ResourceRequirements{
112 Requests: v1.ResourceList{
113 v1.ResourceCPU: resource.MustParse("1"),
114 v1.ResourceMemory: resource.MustParse("1Mi"),
115 },
116 },
117 },
118 {},
119 },
120 },
121 },
122 expected: map[v1.ResourceName]int64{
123 v1.ResourceCPU: 2000 + util.DefaultMilliCPURequest,
124 v1.ResourceMemory: 2*oneMi + util.DefaultMemoryRequest,
125 },
126 },
127 {
128 name: "init container + container + requestless container + overhead",
129 pod: v1.Pod{
130 Spec: v1.PodSpec{
131 Overhead: v1.ResourceList{
132 v1.ResourceCPU: resource.MustParse("1"),
133 v1.ResourceMemory: resource.MustParse("1Mi"),
134 },
135 InitContainers: []v1.Container{
136 {
137 Resources: v1.ResourceRequirements{
138 Requests: v1.ResourceList{
139 v1.ResourceCPU: resource.MustParse("3"),
140 },
141 },
142 },
143 },
144 Containers: []v1.Container{
145 {
146 Resources: v1.ResourceRequirements{
147 Requests: v1.ResourceList{
148 v1.ResourceCPU: resource.MustParse("1"),
149 v1.ResourceMemory: resource.MustParse("1Mi"),
150 },
151 },
152 },
153 {},
154 },
155 },
156 },
157 expected: map[v1.ResourceName]int64{
158 v1.ResourceCPU: 4000,
159 v1.ResourceMemory: 2*oneMi + util.DefaultMemoryRequest,
160 },
161 },
162 {
163 name: "requestless init container + small init container + small container ",
164 pod: v1.Pod{
165 Spec: v1.PodSpec{
166 InitContainers: []v1.Container{
167 {},
168 {
169 Resources: v1.ResourceRequirements{
170 Requests: v1.ResourceList{
171 v1.ResourceCPU: resource.MustParse("1m"),
172 v1.ResourceMemory: resource.MustParse("1"),
173 },
174 },
175 },
176 },
177 Containers: []v1.Container{
178 {
179 Resources: v1.ResourceRequirements{
180 Requests: v1.ResourceList{
181 v1.ResourceCPU: resource.MustParse("3m"),
182 v1.ResourceMemory: resource.MustParse("3"),
183 },
184 },
185 },
186 },
187 },
188 },
189 expected: map[v1.ResourceName]int64{
190 v1.ResourceCPU: util.DefaultMilliCPURequest,
191 v1.ResourceMemory: util.DefaultMemoryRequest,
192 },
193 },
194 {
195 name: "requestless init container + small init container + small container + requestless container ",
196 pod: v1.Pod{
197 Spec: v1.PodSpec{
198 InitContainers: []v1.Container{
199 {},
200 {
201 Resources: v1.ResourceRequirements{
202 Requests: v1.ResourceList{
203 v1.ResourceCPU: resource.MustParse("1m"),
204 v1.ResourceMemory: resource.MustParse("1"),
205 },
206 },
207 },
208 },
209 Containers: []v1.Container{
210 {
211 Resources: v1.ResourceRequirements{
212 Requests: v1.ResourceList{
213 v1.ResourceCPU: resource.MustParse("3m"),
214 v1.ResourceMemory: resource.MustParse("3"),
215 },
216 },
217 },
218 {},
219 },
220 },
221 },
222 expected: map[v1.ResourceName]int64{
223 v1.ResourceCPU: 3 + util.DefaultMilliCPURequest,
224 v1.ResourceMemory: 3 + util.DefaultMemoryRequest,
225 },
226 },
227 }
228
229 for _, tc := range tests {
230 t.Run(tc.name, func(t *testing.T) {
231 var scorer resourceAllocationScorer
232 for n, exp := range tc.expected {
233 got := scorer.calculatePodResourceRequest(&tc.pod, n)
234 if got != exp {
235 t.Errorf("expected %s = %d, got %d", n, exp, got)
236 }
237 }
238 })
239 }
240 }
241
View as plain text