k8s.io/kubernetes@v1.29.3/pkg/kubelet/cm/topologymanager/bitmask/bitmask_test.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 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 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package bitmask 18 19 import ( 20 "reflect" 21 "testing" 22 ) 23 24 func TestNewEmptyiBitMask(t *testing.T) { 25 tcases := []struct { 26 name string 27 expectedMask string 28 }{ 29 { 30 name: "New empty BitMask", 31 expectedMask: "00", 32 }, 33 } 34 for _, tc := range tcases { 35 bm := NewEmptyBitMask() 36 if bm.String() != tc.expectedMask { 37 t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, bm) 38 } 39 } 40 } 41 42 func TestNewBitMask(t *testing.T) { 43 tcases := []struct { 44 name string 45 bits []int 46 expectedMask string 47 }{ 48 { 49 name: "New BitMask with bit 0 set", 50 bits: []int{0}, 51 expectedMask: "01", 52 }, 53 { 54 name: "New BitMask with bit 1 set", 55 bits: []int{1}, 56 expectedMask: "10", 57 }, 58 { 59 name: "New BitMask with bit 0 and bit 1 set", 60 bits: []int{0, 1}, 61 expectedMask: "11", 62 }, 63 } 64 for _, tc := range tcases { 65 mask, _ := NewBitMask(tc.bits...) 66 if mask.String() != tc.expectedMask { 67 t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, mask) 68 } 69 } 70 } 71 72 func TestAdd(t *testing.T) { 73 tcases := []struct { 74 name string 75 bits []int 76 expectedMask string 77 }{ 78 { 79 name: "Add BitMask with bit 0 set", 80 bits: []int{0}, 81 expectedMask: "01", 82 }, 83 { 84 name: "Add BitMask with bit 1 set", 85 bits: []int{1}, 86 expectedMask: "10", 87 }, 88 { 89 name: "Add BitMask with bits 0 and 1 set", 90 bits: []int{0, 1}, 91 expectedMask: "11", 92 }, 93 { 94 name: "Add BitMask with bits outside range 0-63", 95 bits: []int{-1, 64}, 96 expectedMask: "00", 97 }, 98 } 99 for _, tc := range tcases { 100 mask, _ := NewBitMask() 101 mask.Add(tc.bits...) 102 if mask.String() != tc.expectedMask { 103 t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, mask) 104 } 105 } 106 } 107 108 func TestRemove(t *testing.T) { 109 tcases := []struct { 110 name string 111 bitsSet []int 112 bitsRemove []int 113 expectedMask string 114 }{ 115 { 116 name: "Set bit 0. Remove bit 0", 117 bitsSet: []int{0}, 118 bitsRemove: []int{0}, 119 expectedMask: "00", 120 }, 121 { 122 name: "Set bits 0 and 1. Remove bit 1", 123 bitsSet: []int{0, 1}, 124 bitsRemove: []int{1}, 125 expectedMask: "01", 126 }, 127 { 128 name: "Set bits 0 and 1. Remove bits 0 and 1", 129 bitsSet: []int{0, 1}, 130 bitsRemove: []int{0, 1}, 131 expectedMask: "00", 132 }, 133 { 134 name: "Set bit 0. Attempt to remove bits outside range 0-63", 135 bitsSet: []int{0}, 136 bitsRemove: []int{-1, 64}, 137 expectedMask: "01", 138 }, 139 } 140 for _, tc := range tcases { 141 mask, _ := NewBitMask(tc.bitsSet...) 142 mask.Remove(tc.bitsRemove...) 143 if mask.String() != tc.expectedMask { 144 t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, mask) 145 } 146 } 147 } 148 149 func TestAnd(t *testing.T) { 150 tcases := []struct { 151 name string 152 masks [][]int 153 andMask string 154 }{ 155 { 156 name: "Mask 11 AND mask 11", 157 masks: [][]int{{0, 1}, {0, 1}}, 158 andMask: "11", 159 }, 160 { 161 name: "Mask 11 AND mask 10", 162 masks: [][]int{{0, 1}, {1}}, 163 andMask: "10", 164 }, 165 { 166 name: "Mask 01 AND mask 11", 167 masks: [][]int{{0}, {0, 1}}, 168 andMask: "01", 169 }, 170 { 171 name: "Mask 11 AND mask 11 AND mask 10", 172 masks: [][]int{{0, 1}, {0, 1}, {1}}, 173 andMask: "10", 174 }, 175 { 176 name: "Mask 01 AND mask 01 AND mask 10 AND mask 11", 177 masks: [][]int{{0}, {0}, {1}, {0, 1}}, 178 andMask: "00", 179 }, 180 { 181 name: "Mask 1111 AND mask 1110 AND mask 1100 AND mask 1000", 182 masks: [][]int{{0, 1, 2, 3}, {1, 2, 3}, {2, 3}, {3}}, 183 andMask: "1000", 184 }, 185 } 186 for _, tc := range tcases { 187 var bitMasks []BitMask 188 for i := range tc.masks { 189 bitMask, _ := NewBitMask(tc.masks[i]...) 190 bitMasks = append(bitMasks, bitMask) 191 } 192 resultMask := And(bitMasks[0], bitMasks...) 193 if resultMask.String() != string(tc.andMask) { 194 t.Errorf("Expected mask to be %v, got %v", tc.andMask, resultMask) 195 } 196 197 } 198 } 199 200 func TestOr(t *testing.T) { 201 tcases := []struct { 202 name string 203 masks [][]int 204 orMask string 205 }{ 206 { 207 name: "Mask 01 OR mask 00", 208 masks: [][]int{{0}, {}}, 209 orMask: "01", 210 }, 211 { 212 name: "Mask 10 OR mask 10", 213 masks: [][]int{{1}, {1}}, 214 orMask: "10", 215 }, 216 { 217 name: "Mask 01 OR mask 10", 218 masks: [][]int{{0}, {1}}, 219 orMask: "11", 220 }, 221 { 222 name: "Mask 11 OR mask 11", 223 masks: [][]int{{0, 1}, {0, 1}}, 224 orMask: "11", 225 }, 226 { 227 name: "Mask 01 OR mask 10 OR mask 11", 228 masks: [][]int{{0}, {1}, {0, 1}}, 229 orMask: "11", 230 }, 231 { 232 name: "Mask 1000 OR mask 0100 OR mask 0010 OR mask 0001", 233 masks: [][]int{{3}, {2}, {1}, {0}}, 234 orMask: "1111", 235 }, 236 } 237 for _, tc := range tcases { 238 var bitMasks []BitMask 239 for i := range tc.masks { 240 bitMask, _ := NewBitMask(tc.masks[i]...) 241 bitMasks = append(bitMasks, bitMask) 242 } 243 resultMask := Or(bitMasks[0], bitMasks...) 244 if resultMask.String() != string(tc.orMask) { 245 t.Errorf("Expected mask to be %v, got %v", tc.orMask, resultMask) 246 } 247 } 248 } 249 250 func TestClear(t *testing.T) { 251 tcases := []struct { 252 name string 253 mask []int 254 clearedMask string 255 }{ 256 { 257 name: "Clear mask 01", 258 mask: []int{0}, 259 clearedMask: "00", 260 }, 261 { 262 name: "Clear mask 10", 263 mask: []int{1}, 264 clearedMask: "00", 265 }, 266 { 267 name: "Clear mask 11", 268 mask: []int{0, 1}, 269 clearedMask: "00", 270 }, 271 } 272 for _, tc := range tcases { 273 mask, _ := NewBitMask(tc.mask...) 274 mask.Clear() 275 if mask.String() != string(tc.clearedMask) { 276 t.Errorf("Expected mask to be %v, got %v", tc.clearedMask, mask) 277 } 278 } 279 } 280 281 func TestFill(t *testing.T) { 282 tcases := []struct { 283 name string 284 mask []int 285 filledMask string 286 }{ 287 { 288 name: "Fill empty mask", 289 mask: nil, 290 filledMask: "1111111111111111111111111111111111111111111111111111111111111111", 291 }, 292 { 293 name: "Fill mask 10", 294 mask: []int{0}, 295 filledMask: "1111111111111111111111111111111111111111111111111111111111111111", 296 }, 297 { 298 name: "Fill mask 11", 299 mask: []int{0, 1}, 300 filledMask: "1111111111111111111111111111111111111111111111111111111111111111", 301 }, 302 } 303 for _, tc := range tcases { 304 mask, _ := NewBitMask(tc.mask...) 305 mask.Fill() 306 if mask.String() != string(tc.filledMask) { 307 t.Errorf("Expected mask to be %v, got %v", tc.filledMask, mask) 308 } 309 } 310 } 311 312 func TestIsEmpty(t *testing.T) { 313 tcases := []struct { 314 name string 315 mask []int 316 expectedEmpty bool 317 }{ 318 { 319 name: "Check if mask 00 is empty", 320 mask: nil, 321 expectedEmpty: true, 322 }, 323 { 324 name: "Check if mask 01 is empty", 325 mask: []int{0}, 326 expectedEmpty: false, 327 }, 328 { 329 name: "Check if mask 11 is empty", 330 mask: []int{0, 1}, 331 expectedEmpty: false, 332 }, 333 } 334 for _, tc := range tcases { 335 mask, _ := NewBitMask(tc.mask...) 336 empty := mask.IsEmpty() 337 if empty != tc.expectedEmpty { 338 t.Errorf("Expected value to be %v, got %v", tc.expectedEmpty, empty) 339 } 340 } 341 } 342 343 func TestIsSet(t *testing.T) { 344 tcases := []struct { 345 name string 346 mask []int 347 checkBit int 348 expectedSet bool 349 }{ 350 { 351 name: "Check if bit 0 in mask 00 is set", 352 mask: nil, 353 checkBit: 0, 354 expectedSet: false, 355 }, 356 { 357 name: "Check if bit 0 in mask 01 is set", 358 mask: []int{0}, 359 checkBit: 0, 360 expectedSet: true, 361 }, 362 { 363 name: "Check if bit 1 in mask 11 is set", 364 mask: []int{0, 1}, 365 checkBit: 1, 366 expectedSet: true, 367 }, 368 { 369 name: "Check if bit outside range 0-63 is set", 370 mask: []int{0, 1}, 371 checkBit: 64, 372 expectedSet: false, 373 }, 374 } 375 for _, tc := range tcases { 376 mask, _ := NewBitMask(tc.mask...) 377 set := mask.IsSet(tc.checkBit) 378 if set != tc.expectedSet { 379 t.Errorf("Expected value to be %v, got %v", tc.expectedSet, set) 380 } 381 } 382 } 383 384 func TestAnySet(t *testing.T) { 385 tcases := []struct { 386 name string 387 mask []int 388 checkBits []int 389 expectedSet bool 390 }{ 391 { 392 name: "Check if any bits from 11 in mask 00 is set", 393 mask: nil, 394 checkBits: []int{0, 1}, 395 expectedSet: false, 396 }, 397 { 398 name: "Check if any bits from 11 in mask 01 is set", 399 mask: []int{0}, 400 checkBits: []int{0, 1}, 401 expectedSet: true, 402 }, 403 { 404 name: "Check if any bits from 11 in mask 11 is set", 405 mask: []int{0, 1}, 406 checkBits: []int{0, 1}, 407 expectedSet: true, 408 }, 409 { 410 name: "Check if any bit outside range 0-63 is set", 411 mask: []int{0, 1}, 412 checkBits: []int{64, 65}, 413 expectedSet: false, 414 }, 415 { 416 name: "Check if any bits from 1001 in mask 0110 is set", 417 mask: []int{1, 2}, 418 checkBits: []int{0, 3}, 419 expectedSet: false, 420 }, 421 } 422 for _, tc := range tcases { 423 mask, _ := NewBitMask(tc.mask...) 424 set := mask.AnySet(tc.checkBits) 425 if set != tc.expectedSet { 426 t.Errorf("Expected value to be %v, got %v", tc.expectedSet, set) 427 } 428 } 429 } 430 431 func TestIsEqual(t *testing.T) { 432 tcases := []struct { 433 name string 434 firstMask []int 435 secondMask []int 436 expectedEqual bool 437 }{ 438 { 439 name: "Check if mask 00 equals mask 00", 440 firstMask: nil, 441 secondMask: nil, 442 expectedEqual: true, 443 }, 444 { 445 name: "Check if mask 00 equals mask 01", 446 firstMask: nil, 447 secondMask: []int{0}, 448 expectedEqual: false, 449 }, 450 { 451 name: "Check if mask 01 equals mask 01", 452 firstMask: []int{0}, 453 secondMask: []int{0}, 454 expectedEqual: true, 455 }, 456 { 457 name: "Check if mask 01 equals mask 10", 458 firstMask: []int{0}, 459 secondMask: []int{1}, 460 expectedEqual: false, 461 }, 462 { 463 name: "Check if mask 11 equals mask 11", 464 firstMask: []int{0, 1}, 465 secondMask: []int{0, 1}, 466 expectedEqual: true, 467 }, 468 } 469 for _, tc := range tcases { 470 firstMask, _ := NewBitMask(tc.firstMask...) 471 secondMask, _ := NewBitMask(tc.secondMask...) 472 isEqual := firstMask.IsEqual(secondMask) 473 if isEqual != tc.expectedEqual { 474 t.Errorf("Expected mask to be %v, got %v", tc.expectedEqual, isEqual) 475 } 476 } 477 } 478 479 func TestCount(t *testing.T) { 480 tcases := []struct { 481 name string 482 bits []int 483 expectedCount int 484 }{ 485 { 486 name: "Count number of bits set in mask 00", 487 bits: nil, 488 expectedCount: 0, 489 }, 490 { 491 name: "Count number of bits set in mask 01", 492 bits: []int{0}, 493 expectedCount: 1, 494 }, 495 { 496 name: "Count number of bits set in mask 11", 497 bits: []int{0, 1}, 498 expectedCount: 2, 499 }, 500 } 501 for _, tc := range tcases { 502 mask, _ := NewBitMask(tc.bits...) 503 count := mask.Count() 504 if count != tc.expectedCount { 505 t.Errorf("Expected value to be %v, got %v", tc.expectedCount, count) 506 } 507 } 508 } 509 510 func TestGetBits(t *testing.T) { 511 tcases := []struct { 512 name string 513 bits []int 514 expectedBits []int 515 }{ 516 { 517 name: "Get bits of mask 00", 518 bits: nil, 519 expectedBits: nil, 520 }, 521 { 522 name: "Get bits of mask 01", 523 bits: []int{0}, 524 expectedBits: []int{0}, 525 }, 526 { 527 name: "Get bits of mask 11", 528 bits: []int{0, 1}, 529 expectedBits: []int{0, 1}, 530 }, 531 } 532 for _, tc := range tcases { 533 mask, _ := NewBitMask(tc.bits...) 534 bits := mask.GetBits() 535 if !reflect.DeepEqual(bits, tc.expectedBits) { 536 t.Errorf("Expected value to be %v, got %v", tc.expectedBits, bits) 537 } 538 } 539 } 540 541 func TestIsNarrowerThan(t *testing.T) { 542 tcases := []struct { 543 name string 544 firstMask []int 545 secondMask []int 546 expectedFirstNarrower bool 547 }{ 548 { 549 name: "Check narrowness of masks with unequal bits set 1/2", 550 firstMask: []int{0}, 551 secondMask: []int{0, 1}, 552 expectedFirstNarrower: true, 553 }, 554 { 555 name: "Check narrowness of masks with unequal bits set 2/2", 556 firstMask: []int{0, 1}, 557 secondMask: []int{0}, 558 expectedFirstNarrower: false, 559 }, 560 { 561 name: "Check narrowness of masks with equal bits set 1/2", 562 firstMask: []int{0}, 563 secondMask: []int{1}, 564 expectedFirstNarrower: true, 565 }, 566 { 567 name: "Check narrowness of masks with equal bits set 2/2", 568 firstMask: []int{1}, 569 secondMask: []int{0}, 570 expectedFirstNarrower: false, 571 }, 572 } 573 for _, tc := range tcases { 574 firstMask, _ := NewBitMask(tc.firstMask...) 575 secondMask, _ := NewBitMask(tc.secondMask...) 576 expectedFirstNarrower := firstMask.IsNarrowerThan(secondMask) 577 if expectedFirstNarrower != tc.expectedFirstNarrower { 578 t.Errorf("Expected value to be %v, got %v", tc.expectedFirstNarrower, expectedFirstNarrower) 579 } 580 } 581 } 582 583 func TestIterateBitMasks(t *testing.T) { 584 tcases := []struct { 585 name string 586 numbits int 587 }{ 588 { 589 name: "1 bit", 590 numbits: 1, 591 }, 592 { 593 name: "2 bits", 594 numbits: 2, 595 }, 596 { 597 name: "4 bits", 598 numbits: 4, 599 }, 600 { 601 name: "8 bits", 602 numbits: 8, 603 }, 604 { 605 name: "16 bits", 606 numbits: 16, 607 }, 608 } 609 for _, tc := range tcases { 610 // Generate a list of bits from tc.numbits. 611 var bits []int 612 for i := 0; i < tc.numbits; i++ { 613 bits = append(bits, i) 614 } 615 616 // Calculate the expected number of masks. Since we always have masks 617 // with bits from 0..n, this is just (2^n - 1) since we want 1 mask 618 // represented by each integer between 1 and 2^n-1. 619 expectedNumMasks := (1 << uint(tc.numbits)) - 1 620 621 // Iterate all masks and count them. 622 numMasks := 0 623 IterateBitMasks(bits, func(BitMask) { 624 numMasks++ 625 }) 626 627 // Compare the number of masks generated to the expected amount. 628 if expectedNumMasks != numMasks { 629 t.Errorf("Expected to iterate %v masks, got %v", expectedNumMasks, numMasks) 630 } 631 } 632 } 633 634 func TestIsLessThan(t *testing.T) { 635 tcases := []struct { 636 name string 637 firstMask []int 638 secondMask []int 639 expectedFirstLower bool 640 }{ 641 { 642 name: "Check which value is lower of masks with equal bits set 1/1", 643 firstMask: []int{0}, 644 secondMask: []int{0}, 645 expectedFirstLower: false, 646 }, 647 { 648 name: "Check which value is lower of masks with unequal bits set 2/1", 649 firstMask: []int{1}, 650 secondMask: []int{0}, 651 expectedFirstLower: false, 652 }, 653 { 654 name: "Check which value is lower of masks with unequal bits set 1/2", 655 firstMask: []int{0}, 656 secondMask: []int{1}, 657 expectedFirstLower: true, 658 }, 659 } 660 for _, tc := range tcases { 661 firstMask, _ := NewBitMask(tc.firstMask...) 662 secondMask, _ := NewBitMask(tc.secondMask...) 663 expectedFirstLower := firstMask.IsLessThan(secondMask) 664 if expectedFirstLower != tc.expectedFirstLower { 665 t.Errorf("Expected value to be %v, got %v", tc.expectedFirstLower, expectedFirstLower) 666 } 667 } 668 } 669 670 func TestIsGreaterThan(t *testing.T) { 671 tcases := []struct { 672 name string 673 firstMask []int 674 secondMask []int 675 expectedFirstGreater bool 676 }{ 677 { 678 name: "Check which value is greater of masks with equal bits set 1/1", 679 firstMask: []int{0}, 680 secondMask: []int{0}, 681 expectedFirstGreater: false, 682 }, 683 { 684 name: "Check which value is greater of masks with unequal bits set 2/1", 685 firstMask: []int{1}, 686 secondMask: []int{0}, 687 expectedFirstGreater: true, 688 }, 689 { 690 name: "Check which value is greater of masks with unequal bits set 1/2", 691 firstMask: []int{0}, 692 secondMask: []int{1}, 693 expectedFirstGreater: false, 694 }, 695 } 696 for _, tc := range tcases { 697 firstMask, _ := NewBitMask(tc.firstMask...) 698 secondMask, _ := NewBitMask(tc.secondMask...) 699 expectedFirstGreater := firstMask.IsGreaterThan(secondMask) 700 if expectedFirstGreater != tc.expectedFirstGreater { 701 t.Errorf("Expected value to be %v, got %v", tc.expectedFirstGreater, expectedFirstGreater) 702 } 703 } 704 }