1
16
17 package allocator
18
19 import (
20 "testing"
21
22 "k8s.io/apimachinery/pkg/util/sets"
23 )
24
25 func TestAllocate(t *testing.T) {
26 testCases := []struct {
27 name string
28 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
29 max int
30 reserved int
31 }{
32 {
33 name: "NewAllocationMap",
34 allocator: NewAllocationMapWithOffset,
35 max: 32,
36 reserved: 0,
37 },
38 {
39 name: "NewAllocationMapWithOffset max < 16",
40 allocator: NewAllocationMapWithOffset,
41 max: 8,
42 reserved: 0,
43 },
44 {
45 name: "NewAllocationMapWithOffset max > 16",
46 allocator: NewAllocationMapWithOffset,
47 max: 128,
48 reserved: 16,
49 },
50 {
51 name: "NewAllocationMapWithOffset max > 256",
52 allocator: NewAllocationMapWithOffset,
53 max: 1024,
54 reserved: 64,
55 },
56 {
57 name: "NewAllocationMapWithOffset max value",
58 allocator: NewAllocationMapWithOffset,
59 max: 65535,
60 reserved: 256,
61 },
62 }
63 for _, tc := range testCases {
64 t.Run(tc.name, func(t *testing.T) {
65 m := tc.allocator(tc.max, "test", tc.reserved)
66
67 if _, ok, _ := m.AllocateNext(); !ok {
68 t.Fatalf("unexpected error")
69 }
70 if m.count != 1 {
71 t.Errorf("expect to get %d, but got %d", 1, m.count)
72 }
73 if f := m.Free(); f != tc.max-1 {
74 t.Errorf("expect to get %d, but got %d", tc.max-1, f)
75 }
76 })
77 }
78 }
79
80 func TestAllocateMax(t *testing.T) {
81 testCases := []struct {
82 name string
83 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
84 max int
85 reserved int
86 }{
87 {
88 name: "NewAllocationMap",
89 allocator: NewAllocationMapWithOffset,
90 max: 32,
91 reserved: 0,
92 },
93 {
94 name: "NewAllocationMapWithOffset max < 16",
95 allocator: NewAllocationMapWithOffset,
96 max: 8,
97 reserved: 0,
98 },
99 {
100 name: "NewAllocationMapWithOffset max > 16",
101 allocator: NewAllocationMapWithOffset,
102 max: 128,
103 reserved: 16,
104 },
105 {
106 name: "NewAllocationMapWithOffset max > 256",
107 allocator: NewAllocationMapWithOffset,
108 max: 1024,
109 reserved: 64,
110 },
111 {
112 name: "NewAllocationMapWithOffset max value",
113 allocator: NewAllocationMapWithOffset,
114 max: 65535,
115 reserved: 256,
116 },
117 }
118 for _, tc := range testCases {
119 t.Run(tc.name, func(t *testing.T) {
120 m := tc.allocator(tc.max, "test", tc.reserved)
121 for i := 0; i < tc.max; i++ {
122 if ok, err := m.Allocate(i); !ok || err != nil {
123 t.Fatalf("unexpected error")
124 }
125 }
126 if _, ok, _ := m.AllocateNext(); ok {
127 t.Errorf("unexpected success")
128 }
129
130 if ok, err := m.Allocate(tc.max); ok || err == nil {
131 t.Fatalf("unexpected allocation")
132 }
133
134 if f := m.Free(); f != 0 {
135 t.Errorf("expect to get %d, but got %d", 0, f)
136 }
137 })
138 }
139 }
140
141 func TestAllocateNextMax(t *testing.T) {
142 testCases := []struct {
143 name string
144 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
145 max int
146 reserved int
147 }{
148 {
149 name: "NewAllocationMap",
150 allocator: NewAllocationMapWithOffset,
151 max: 32,
152 reserved: 0,
153 },
154 {
155 name: "NewAllocationMapWithOffset max < 16",
156 allocator: NewAllocationMapWithOffset,
157 max: 8,
158 reserved: 0,
159 },
160 {
161 name: "NewAllocationMapWithOffset max > 16",
162 allocator: NewAllocationMapWithOffset,
163 max: 128,
164 reserved: 16,
165 },
166 {
167 name: "NewAllocationMapWithOffset max > 256",
168 allocator: NewAllocationMapWithOffset,
169 max: 1024,
170 reserved: 64,
171 },
172 {
173 name: "NewAllocationMapWithOffset max value",
174 allocator: NewAllocationMapWithOffset,
175 max: 65535,
176 reserved: 256,
177 },
178 }
179 for _, tc := range testCases {
180 t.Run(tc.name, func(t *testing.T) {
181 m := tc.allocator(tc.max, "test", tc.reserved)
182 for i := 0; i < tc.max; i++ {
183 if _, ok, _ := m.AllocateNext(); !ok {
184 t.Fatalf("unexpected error")
185 }
186 }
187 if _, ok, _ := m.AllocateNext(); ok {
188 t.Errorf("unexpected success")
189 }
190 if f := m.Free(); f != 0 {
191 t.Errorf("expect to get %d, but got %d", 0, f)
192 }
193 })
194 }
195 }
196 func TestAllocateError(t *testing.T) {
197 testCases := []struct {
198 name string
199 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
200 max int
201 reserved int
202 }{
203 {
204 name: "NewAllocationMap",
205 allocator: NewAllocationMapWithOffset,
206 max: 32,
207 reserved: 0,
208 },
209 {
210 name: "NewAllocationMapWithOffset max < 16",
211 allocator: NewAllocationMapWithOffset,
212 max: 8,
213 reserved: 0,
214 },
215 {
216 name: "NewAllocationMapWithOffset max > 16",
217 allocator: NewAllocationMapWithOffset,
218 max: 128,
219 reserved: 16,
220 },
221 {
222 name: "NewAllocationMapWithOffset max > 256",
223 allocator: NewAllocationMapWithOffset,
224 max: 1024,
225 reserved: 64,
226 },
227 {
228 name: "NewAllocationMapWithOffset max value",
229 allocator: NewAllocationMapWithOffset,
230 max: 65535,
231 reserved: 256,
232 },
233 }
234 for _, tc := range testCases {
235 t.Run(tc.name, func(t *testing.T) {
236 m := tc.allocator(tc.max, "test", tc.reserved)
237 if ok, _ := m.Allocate(3); !ok {
238 t.Errorf("error allocate offset %v", 3)
239 }
240 if ok, _ := m.Allocate(3); ok {
241 t.Errorf("unexpected success")
242 }
243 })
244 }
245 }
246
247 func TestRelease(t *testing.T) {
248 testCases := []struct {
249 name string
250 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
251 max int
252 reserved int
253 }{
254 {
255 name: "NewAllocationMap",
256 allocator: NewAllocationMapWithOffset,
257 max: 32,
258 reserved: 0,
259 },
260 {
261 name: "NewAllocationMapWithOffset max < 16",
262 allocator: NewAllocationMapWithOffset,
263 max: 8,
264 reserved: 0,
265 },
266 {
267 name: "NewAllocationMapWithOffset max > 16",
268 allocator: NewAllocationMapWithOffset,
269 max: 128,
270 reserved: 16,
271 },
272 {
273 name: "NewAllocationMapWithOffset max > 256",
274 allocator: NewAllocationMapWithOffset,
275 max: 1024,
276 reserved: 64,
277 },
278 {
279 name: "NewAllocationMapWithOffset max value",
280 allocator: NewAllocationMapWithOffset,
281 max: 65535,
282 reserved: 256,
283 },
284 }
285 for _, tc := range testCases {
286 t.Run(tc.name, func(t *testing.T) {
287 m := tc.allocator(tc.max, "test", tc.reserved)
288 offset := 3
289 if ok, _ := m.Allocate(offset); !ok {
290 t.Errorf("error allocate offset %v", offset)
291 }
292
293 if !m.Has(offset) {
294 t.Errorf("expect offset %v allocated", offset)
295 }
296
297 if err := m.Release(offset); err != nil {
298 t.Errorf("unexpected error: %v", err)
299 }
300
301 if m.Has(offset) {
302 t.Errorf("expect offset %v not allocated", offset)
303 }
304 })
305 }
306
307 }
308
309 func TestForEach(t *testing.T) {
310 testCases := []struct {
311 name string
312 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
313 max int
314 reserved int
315 }{
316 {
317 name: "NewAllocationMap",
318 allocator: NewAllocationMapWithOffset,
319 max: 32,
320 reserved: 0,
321 },
322 {
323 name: "NewAllocationMapWithOffset max < 16",
324 allocator: NewAllocationMapWithOffset,
325 max: 8,
326 reserved: 0,
327 },
328 {
329 name: "NewAllocationMapWithOffset max > 16",
330 allocator: NewAllocationMapWithOffset,
331 max: 128,
332 reserved: 16,
333 },
334 {
335 name: "NewAllocationMapWithOffset max > 256",
336 allocator: NewAllocationMapWithOffset,
337 max: 1024,
338 reserved: 64,
339 },
340 {
341 name: "NewAllocationMapWithOffset max value",
342 allocator: NewAllocationMapWithOffset,
343 max: 65535,
344 reserved: 256,
345 },
346 }
347 for _, tc := range testCases {
348 t.Run(tc.name, func(t *testing.T) {
349 subTests := []sets.Int{
350 sets.NewInt(),
351 sets.NewInt(0),
352 sets.NewInt(0, 2, 5),
353 sets.NewInt(0, 1, 2, 3, 4, 5, 6, 7),
354 }
355
356 for i, ts := range subTests {
357 m := tc.allocator(tc.max, "test", tc.reserved)
358 for offset := range ts {
359 if ok, _ := m.Allocate(offset); !ok {
360 t.Errorf("[%d] error allocate offset %v", i, offset)
361 }
362 if !m.Has(offset) {
363 t.Errorf("[%d] expect offset %v allocated", i, offset)
364 }
365 }
366 calls := sets.NewInt()
367 m.ForEach(func(i int) {
368 calls.Insert(i)
369 })
370 if len(calls) != len(ts) {
371 t.Errorf("[%d] expected %d calls, got %d", i, len(ts), len(calls))
372 }
373 if !calls.Equal(ts) {
374 t.Errorf("[%d] expected calls to equal testcase: %v vs %v", i, calls.List(), ts.List())
375 }
376 }
377 })
378 }
379 }
380
381 func TestSnapshotAndRestore(t *testing.T) {
382 testCases := []struct {
383 name string
384 allocator func(max int, rangeSpec string, reserved int) *AllocationBitmap
385 max int
386 reserved int
387 }{
388 {
389 name: "NewAllocationMap",
390 allocator: NewAllocationMapWithOffset,
391 max: 32,
392 reserved: 0,
393 },
394 {
395 name: "NewAllocationMapWithOffset max < 16",
396 allocator: NewAllocationMapWithOffset,
397 max: 8,
398 reserved: 0,
399 },
400 {
401 name: "NewAllocationMapWithOffset max > 16",
402 allocator: NewAllocationMapWithOffset,
403 max: 128,
404 reserved: 16,
405 },
406 {
407 name: "NewAllocationMapWithOffset max > 256",
408 allocator: NewAllocationMapWithOffset,
409 max: 1024,
410 reserved: 64,
411 },
412 {
413 name: "NewAllocationMapWithOffset max value",
414 allocator: NewAllocationMapWithOffset,
415 max: 65535,
416 reserved: 256,
417 },
418 }
419 for _, tc := range testCases {
420 t.Run(tc.name, func(t *testing.T) {
421 m := tc.allocator(tc.max, "test", tc.reserved)
422 offset := 3
423 if ok, _ := m.Allocate(offset); !ok {
424 t.Errorf("error allocate offset %v", offset)
425 }
426 spec, bytes := m.Snapshot()
427
428 m2 := tc.allocator(10, "test", tc.reserved)
429 err := m2.Restore(spec, bytes)
430 if err != nil {
431 t.Errorf("unexpected error: %v", err)
432 }
433
434 if m2.count != 1 {
435 t.Errorf("expect count to %d, but got %d", 0, m.count)
436 }
437 if !m2.Has(offset) {
438 t.Errorf("expect offset %v allocated", offset)
439 }
440 })
441 }
442
443 }
444
445
446 func TestAllocateMax_BitmapReserved(t *testing.T) {
447 max := 128
448 dynamicOffset := 16
449
450
451 allocated := 0
452
453 m := NewAllocationMapWithOffset(max, "test", dynamicOffset)
454 for i := 0; i < max-dynamicOffset; i++ {
455 if _, ok, _ := m.AllocateNext(); !ok {
456 t.Fatalf("unexpected error")
457 }
458 allocated++
459 }
460
461 if f := m.Free(); f != dynamicOffset {
462 t.Errorf("expect to get %d, but got %d", dynamicOffset-1, f)
463 }
464
465 for i := 0; i < dynamicOffset; i++ {
466 if m.Has(i) {
467 t.Errorf("unexpected allocated value %d", i)
468 }
469 }
470
471 if _, ok, _ := m.AllocateNext(); !ok {
472 t.Fatalf("unexpected error")
473 }
474 allocated++
475 if allocated != m.count {
476 t.Errorf("expect to get %d, but got %d", allocated, m.count)
477 }
478
479 if m.count != max-dynamicOffset+1 {
480 t.Errorf("expect to get %d, but got %d", max-dynamicOffset+1, m.count)
481 }
482 if f := m.Free(); f != max-allocated {
483 t.Errorf("expect to get %d, but got %d", max-allocated, f)
484 }
485 }
486
487 func TestPreAllocateReservedFull_BitmapReserved(t *testing.T) {
488 max := 128
489 dynamicOffset := 16
490
491 allocated := 0
492 m := NewAllocationMapWithOffset(max, "test", dynamicOffset)
493
494 for i := dynamicOffset; i < max; i++ {
495 if ok, _ := m.Allocate(i); !ok {
496 t.Errorf("error allocate i %v", i)
497 } else {
498 allocated++
499 }
500 }
501
502 for i := 0; i < dynamicOffset-1; i++ {
503 if ok, _ := m.Allocate(i); !ok {
504 t.Errorf("error allocate i %v", i)
505 } else {
506 allocated++
507 }
508 }
509
510
511 if f := m.Free(); f != 1 {
512 t.Errorf("expect to get %d, but got %d", 1, f)
513 }
514
515 count := 0
516 for i := 0; i < dynamicOffset; i++ {
517 if !m.Has(i) {
518 count++
519 }
520 }
521 if count != 1 {
522 t.Errorf("expected one remaining free value, got %d", count)
523 }
524
525 if _, ok, _ := m.AllocateNext(); !ok {
526 t.Errorf("unexpected allocation error")
527 } else {
528 allocated++
529 }
530 if f := m.Free(); f != 0 {
531 t.Errorf("expect to get %d, but got %d", max-1, f)
532 }
533
534 if _, ok, _ := m.AllocateNext(); ok {
535 t.Errorf("unexpected success")
536 }
537 if m.count != allocated {
538 t.Errorf("expect to get %d, but got %d", max, m.count)
539 }
540 if f := m.Free(); f != 0 {
541 t.Errorf("expect to get %d, but got %d", max-1, f)
542 }
543 }
544
545 func TestAllocateUniqueness(t *testing.T) {
546 max := 128
547 dynamicOffset := 16
548 uniqueAllocated := map[int]bool{}
549 m := NewAllocationMapWithOffset(max, "test", dynamicOffset)
550
551
552 for i := 0; i < max; i++ {
553 alloc, ok, _ := m.AllocateNext()
554 if !ok {
555 t.Fatalf("unexpected error")
556 }
557 if _, ok := uniqueAllocated[alloc]; ok {
558 t.Fatalf("unexpected allocated value %d", alloc)
559 } else {
560 uniqueAllocated[alloc] = true
561 }
562 }
563
564 if max != len(uniqueAllocated) {
565 t.Errorf("expect to get %d, but got %d", max, len(uniqueAllocated))
566 }
567 }
568
View as plain text