1
16
17 package helper
18
19 import (
20 "testing"
21
22 "k8s.io/apimachinery/pkg/api/resource"
23 "k8s.io/kubernetes/pkg/apis/core"
24 )
25
26 func TestSemantic(t *testing.T) {
27 table := []struct {
28 a, b interface{}
29 shouldEqual bool
30 }{
31 {resource.MustParse("0"), resource.Quantity{}, true},
32 {resource.Quantity{}, resource.MustParse("0"), true},
33 {resource.Quantity{}, resource.MustParse("1m"), false},
34 {
35 resource.NewQuantity(5, resource.BinarySI),
36 resource.NewQuantity(5, resource.DecimalSI),
37 true,
38 },
39 {resource.MustParse("2m"), resource.MustParse("1m"), false},
40 }
41
42 for index, item := range table {
43 if e, a := item.shouldEqual, Semantic.DeepEqual(item.a, item.b); e != a {
44 t.Errorf("case[%d], expected %v, got %v.", index, e, a)
45 }
46 }
47 }
48
49 func TestIsStandardResource(t *testing.T) {
50 testCases := []struct {
51 input string
52 output bool
53 }{
54 {"cpu", true},
55 {"memory", true},
56 {"disk", false},
57 {"blah", false},
58 {"x.y.z", false},
59 {"hugepages-2Mi", true},
60 {"requests.hugepages-2Mi", true},
61 }
62 for i, tc := range testCases {
63 if IsStandardResourceName(core.ResourceName(tc.input)) != tc.output {
64 t.Errorf("case[%d], input: %s, expected: %t, got: %t", i, tc.input, tc.output, !tc.output)
65 }
66 }
67 }
68
69 func TestIsStandardContainerResource(t *testing.T) {
70 testCases := []struct {
71 input string
72 output bool
73 }{
74 {"cpu", true},
75 {"memory", true},
76 {"disk", false},
77 {"hugepages-2Mi", true},
78 }
79 for i, tc := range testCases {
80 if IsStandardContainerResourceName(core.ResourceName(tc.input)) != tc.output {
81 t.Errorf("case[%d], input: %s, expected: %t, got: %t", i, tc.input, tc.output, !tc.output)
82 }
83 }
84 }
85
86 func TestGetAccessModesFromString(t *testing.T) {
87 modes := GetAccessModesFromString("ROX")
88 if !ContainsAccessMode(modes, core.ReadOnlyMany) {
89 t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
90 }
91
92 modes = GetAccessModesFromString("ROX,RWX")
93 if !ContainsAccessMode(modes, core.ReadOnlyMany) {
94 t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
95 }
96 if !ContainsAccessMode(modes, core.ReadWriteMany) {
97 t.Errorf("Expected mode %s, but got %+v", core.ReadWriteMany, modes)
98 }
99
100 modes = GetAccessModesFromString("RWO,ROX,RWX")
101 if !ContainsAccessMode(modes, core.ReadWriteOnce) {
102 t.Errorf("Expected mode %s, but got %+v", core.ReadWriteOnce, modes)
103 }
104 if !ContainsAccessMode(modes, core.ReadOnlyMany) {
105 t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
106 }
107 if !ContainsAccessMode(modes, core.ReadWriteMany) {
108 t.Errorf("Expected mode %s, but got %+v", core.ReadWriteMany, modes)
109 }
110
111 modes = GetAccessModesFromString("RWO,ROX,RWX,RWOP")
112 if !ContainsAccessMode(modes, core.ReadWriteOnce) {
113 t.Errorf("Expected mode %s, but got %+v", core.ReadWriteOnce, modes)
114 }
115 if !ContainsAccessMode(modes, core.ReadOnlyMany) {
116 t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
117 }
118 if !ContainsAccessMode(modes, core.ReadWriteMany) {
119 t.Errorf("Expected mode %s, but got %+v", core.ReadWriteMany, modes)
120 }
121 if !ContainsAccessMode(modes, core.ReadWriteOncePod) {
122 t.Errorf("Expected mode %s, but got %+v", core.ReadWriteOncePod, modes)
123 }
124 }
125
126 func TestRemoveDuplicateAccessModes(t *testing.T) {
127 modes := []core.PersistentVolumeAccessMode{
128 core.ReadWriteOnce, core.ReadOnlyMany, core.ReadOnlyMany, core.ReadOnlyMany,
129 }
130 modes = removeDuplicateAccessModes(modes)
131 if len(modes) != 2 {
132 t.Errorf("Expected 2 distinct modes in set but found %v", len(modes))
133 }
134 }
135
136 func TestIsHugePageResourceName(t *testing.T) {
137 testCases := []struct {
138 name core.ResourceName
139 result bool
140 }{
141 {
142 name: core.ResourceName("hugepages-2Mi"),
143 result: true,
144 },
145 {
146 name: core.ResourceName("hugepages-1Gi"),
147 result: true,
148 },
149 {
150 name: core.ResourceName("cpu"),
151 result: false,
152 },
153 {
154 name: core.ResourceName("memory"),
155 result: false,
156 },
157 }
158 for _, testCase := range testCases {
159 if testCase.result != IsHugePageResourceName(testCase.name) {
160 t.Errorf("resource: %v expected result: %v", testCase.name, testCase.result)
161 }
162 }
163 }
164
165 func TestIsHugePageResourceValueDivisible(t *testing.T) {
166 testCases := []struct {
167 name core.ResourceName
168 quantity resource.Quantity
169 result bool
170 }{
171 {
172 name: core.ResourceName("hugepages-2Mi"),
173 quantity: resource.MustParse("4Mi"),
174 result: true,
175 },
176 {
177 name: core.ResourceName("hugepages-2Mi"),
178 quantity: resource.MustParse("5Mi"),
179 result: false,
180 },
181 {
182 name: core.ResourceName("hugepages-1Gi"),
183 quantity: resource.MustParse("2Gi"),
184 result: true,
185 },
186 {
187 name: core.ResourceName("hugepages-1Gi"),
188 quantity: resource.MustParse("2.1Gi"),
189 result: false,
190 },
191 {
192 name: core.ResourceName("hugepages-1Mi"),
193 quantity: resource.MustParse("2.1Mi"),
194 result: false,
195 },
196 {
197 name: core.ResourceName("hugepages-64Ki"),
198 quantity: resource.MustParse("128Ki"),
199 result: true,
200 },
201 {
202 name: core.ResourceName("hugepages-"),
203 quantity: resource.MustParse("128Ki"),
204 result: false,
205 },
206 {
207 name: core.ResourceName("hugepages"),
208 quantity: resource.MustParse("128Ki"),
209 result: false,
210 },
211 }
212 for _, testCase := range testCases {
213 if testCase.result != IsHugePageResourceValueDivisible(testCase.name, testCase.quantity) {
214 t.Errorf("resource: %v storage:%v expected result: %v", testCase.name, testCase.quantity, testCase.result)
215 }
216 }
217 }
218
219 func TestHugePageResourceName(t *testing.T) {
220 testCases := []struct {
221 pageSize resource.Quantity
222 name core.ResourceName
223 }{
224 {
225 pageSize: resource.MustParse("2Mi"),
226 name: core.ResourceName("hugepages-2Mi"),
227 },
228 {
229 pageSize: resource.MustParse("1Gi"),
230 name: core.ResourceName("hugepages-1Gi"),
231 },
232 {
233
234 pageSize: *resource.NewQuantity(int64(2097152), resource.BinarySI),
235 name: core.ResourceName("hugepages-2Mi"),
236 },
237 }
238 for _, testCase := range testCases {
239 if result := HugePageResourceName(testCase.pageSize); result != testCase.name {
240 t.Errorf("pageSize: %v, expected: %v, but got: %v", testCase.pageSize.String(), testCase.name, result.String())
241 }
242 }
243 }
244
245 func TestHugePageSizeFromResourceName(t *testing.T) {
246 testCases := []struct {
247 name core.ResourceName
248 expectErr bool
249 pageSize resource.Quantity
250 }{
251 {
252 name: core.ResourceName("hugepages-2Mi"),
253 pageSize: resource.MustParse("2Mi"),
254 expectErr: false,
255 },
256 {
257 name: core.ResourceName("hugepages-1Gi"),
258 pageSize: resource.MustParse("1Gi"),
259 expectErr: false,
260 },
261 {
262 name: core.ResourceName("hugepages-bad"),
263 expectErr: true,
264 },
265 }
266 for _, testCase := range testCases {
267 value, err := HugePageSizeFromResourceName(testCase.name)
268 if testCase.expectErr && err == nil {
269 t.Errorf("Expected an error for %v", testCase.name)
270 } else if !testCase.expectErr && err != nil {
271 t.Errorf("Unexpected error for %v, got %v", testCase.name, err)
272 } else if testCase.pageSize.Value() != value.Value() {
273 t.Errorf("Unexpected pageSize for resource %v got %v", testCase.name, value.String())
274 }
275 }
276 }
277
278 func TestIsOvercommitAllowed(t *testing.T) {
279 testCases := []struct {
280 name core.ResourceName
281 allowed bool
282 }{
283 {
284 name: core.ResourceCPU,
285 allowed: true,
286 },
287 {
288 name: core.ResourceMemory,
289 allowed: true,
290 },
291 {
292 name: HugePageResourceName(resource.MustParse("2Mi")),
293 allowed: false,
294 },
295 }
296 for _, testCase := range testCases {
297 if testCase.allowed != IsOvercommitAllowed(testCase.name) {
298 t.Errorf("Unexpected result for %v", testCase.name)
299 }
300 }
301 }
302
303 func TestIsServiceIPSet(t *testing.T) {
304 testCases := []struct {
305 input core.ServiceSpec
306 output bool
307 name string
308 }{
309 {
310 name: "nil cluster ip",
311 input: core.ServiceSpec{
312 ClusterIPs: nil,
313 },
314
315 output: false,
316 },
317 {
318 name: "headless service",
319 input: core.ServiceSpec{
320 ClusterIP: "None",
321 ClusterIPs: []string{"None"},
322 },
323 output: false,
324 },
325
326 {
327 name: "one ipv4",
328 input: core.ServiceSpec{
329 ClusterIP: "1.2.3.4",
330 ClusterIPs: []string{"1.2.3.4"},
331 },
332 output: true,
333 },
334 {
335 name: "one ipv6",
336 input: core.ServiceSpec{
337 ClusterIP: "2001::1",
338 ClusterIPs: []string{"2001::1"},
339 },
340 output: true,
341 },
342 {
343 name: "v4, v6",
344 input: core.ServiceSpec{
345 ClusterIP: "1.2.3.4",
346 ClusterIPs: []string{"1.2.3.4", "2001::1"},
347 },
348 output: true,
349 },
350 {
351 name: "v6, v4",
352 input: core.ServiceSpec{
353 ClusterIP: "2001::1",
354 ClusterIPs: []string{"2001::1", "1.2.3.4"},
355 },
356
357 output: true,
358 },
359 }
360
361 for _, tc := range testCases {
362 t.Run(tc.name, func(t *testing.T) {
363 s := core.Service{
364 Spec: tc.input,
365 }
366 if IsServiceIPSet(&s) != tc.output {
367 t.Errorf("case, input: %v, expected: %v, got: %v", tc.input, tc.output, !tc.output)
368 }
369 })
370 }
371 }
372
View as plain text