k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/kubelet/cm/dra/claiminfo_test.go (about) 1 /* 2 Copyright 2024 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 dra 18 19 import ( 20 "errors" 21 "fmt" 22 "path" 23 "reflect" 24 "sort" 25 "testing" 26 27 "github.com/stretchr/testify/assert" 28 resourcev1alpha2 "k8s.io/api/resource/v1alpha2" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 "k8s.io/apimachinery/pkg/types" 31 "k8s.io/apimachinery/pkg/util/sets" 32 "k8s.io/kubernetes/pkg/kubelet/cm/dra/state" 33 kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" 34 ) 35 36 // ClaimInfo test cases 37 38 func TestNewClaimInfoFromClaim(t *testing.T) { 39 namespace := "test-namespace" 40 className := "test-class" 41 driverName := "test-plugin" 42 claimUID := types.UID("claim-uid") 43 claimName := "test-claim" 44 45 for _, test := range []struct { 46 description string 47 claim *resourcev1alpha2.ResourceClaim 48 expectedResult *ClaimInfo 49 }{ 50 { 51 description: "successfully created object", 52 claim: &resourcev1alpha2.ResourceClaim{ 53 ObjectMeta: metav1.ObjectMeta{ 54 UID: claimUID, 55 Name: claimName, 56 Namespace: namespace, 57 }, 58 Status: resourcev1alpha2.ResourceClaimStatus{ 59 DriverName: driverName, 60 Allocation: &resourcev1alpha2.AllocationResult{ 61 ResourceHandles: []resourcev1alpha2.ResourceHandle{}, 62 }, 63 }, 64 Spec: resourcev1alpha2.ResourceClaimSpec{ 65 ResourceClassName: className, 66 }, 67 }, 68 expectedResult: &ClaimInfo{ 69 ClaimInfoState: state.ClaimInfoState{ 70 DriverName: driverName, 71 ClassName: className, 72 ClaimUID: claimUID, 73 ClaimName: claimName, 74 Namespace: claimName, 75 PodUIDs: sets.New[string](), 76 ResourceHandles: []resourcev1alpha2.ResourceHandle{ 77 {}, 78 }, 79 CDIDevices: make(map[string][]string), 80 }, 81 }, 82 }, 83 { 84 description: "successfully created object with empty allocation", 85 claim: &resourcev1alpha2.ResourceClaim{ 86 ObjectMeta: metav1.ObjectMeta{ 87 UID: claimUID, 88 Name: claimName, 89 Namespace: namespace, 90 }, 91 Status: resourcev1alpha2.ResourceClaimStatus{ 92 DriverName: driverName, 93 Allocation: &resourcev1alpha2.AllocationResult{}, 94 }, 95 Spec: resourcev1alpha2.ResourceClaimSpec{ 96 ResourceClassName: className, 97 }, 98 }, 99 expectedResult: &ClaimInfo{ 100 ClaimInfoState: state.ClaimInfoState{ 101 DriverName: driverName, 102 ClassName: className, 103 ClaimUID: claimUID, 104 ClaimName: claimName, 105 Namespace: claimName, 106 PodUIDs: sets.New[string](), 107 ResourceHandles: []resourcev1alpha2.ResourceHandle{ 108 {}, 109 }, 110 CDIDevices: make(map[string][]string), 111 }, 112 }, 113 }, 114 } { 115 t.Run(test.description, func(t *testing.T) { 116 result := newClaimInfoFromClaim(test.claim) 117 if reflect.DeepEqual(result, test.expectedResult) { 118 t.Errorf("Expected %v, but got %v", test.expectedResult, result) 119 } 120 }) 121 } 122 } 123 124 func TestNewClaimInfoFromState(t *testing.T) { 125 for _, test := range []struct { 126 description string 127 state *state.ClaimInfoState 128 expectedResult *ClaimInfo 129 }{ 130 { 131 description: "successfully created object", 132 state: &state.ClaimInfoState{ 133 DriverName: "test-driver", 134 ClassName: "test-class", 135 ClaimUID: "test-uid", 136 ClaimName: "test-claim", 137 Namespace: "test-namespace", 138 PodUIDs: sets.New[string]("test-pod-uid"), 139 ResourceHandles: []resourcev1alpha2.ResourceHandle{}, 140 CDIDevices: map[string][]string{}, 141 }, 142 }, 143 } { 144 t.Run(test.description, func(t *testing.T) { 145 result := newClaimInfoFromState(test.state) 146 if reflect.DeepEqual(result, test.expectedResult) { 147 t.Errorf("Expected %v, but got %v", test.expectedResult, result) 148 } 149 }) 150 } 151 } 152 153 func TestClaimInfoSetCDIDevices(t *testing.T) { 154 claimUID := types.UID("claim-uid") 155 pluginName := "test-plugin" 156 device := "vendor.com/device=device1" 157 annotationName := fmt.Sprintf("cdi.k8s.io/%s_%s", pluginName, claimUID) 158 for _, test := range []struct { 159 description string 160 claimInfo *ClaimInfo 161 devices []string 162 expectedCDIDevices map[string][]string 163 expectedAnnotations map[string][]kubecontainer.Annotation 164 wantErr bool 165 }{ 166 { 167 description: "successfully add one device", 168 claimInfo: &ClaimInfo{ 169 ClaimInfoState: state.ClaimInfoState{ 170 DriverName: pluginName, 171 ClaimUID: claimUID, 172 }, 173 }, 174 devices: []string{device}, 175 expectedCDIDevices: map[string][]string{ 176 pluginName: {device}, 177 }, 178 expectedAnnotations: map[string][]kubecontainer.Annotation{ 179 pluginName: { 180 { 181 Name: annotationName, 182 Value: device, 183 }, 184 }, 185 }, 186 }, 187 { 188 description: "empty list of devices", 189 claimInfo: &ClaimInfo{ 190 ClaimInfoState: state.ClaimInfoState{ 191 DriverName: pluginName, 192 ClaimUID: claimUID, 193 }, 194 }, 195 devices: []string{}, 196 expectedCDIDevices: map[string][]string{pluginName: {}}, 197 expectedAnnotations: map[string][]kubecontainer.Annotation{pluginName: nil}, 198 }, 199 { 200 description: "incorrect device format", 201 claimInfo: &ClaimInfo{ 202 ClaimInfoState: state.ClaimInfoState{ 203 DriverName: pluginName, 204 ClaimUID: claimUID, 205 }, 206 }, 207 devices: []string{"incorrect"}, 208 wantErr: true, 209 }, 210 } { 211 t.Run(test.description, func(t *testing.T) { 212 err := test.claimInfo.setCDIDevices(pluginName, test.devices) 213 if test.wantErr { 214 assert.Error(t, err) 215 return 216 } 217 assert.NoError(t, err) 218 assert.Equal(t, test.expectedCDIDevices, test.claimInfo.CDIDevices) 219 assert.Equal(t, test.expectedAnnotations, test.claimInfo.annotations) 220 }) 221 } 222 } 223 224 func TestClaimInfoAnnotationsAsList(t *testing.T) { 225 for _, test := range []struct { 226 description string 227 claimInfo *ClaimInfo 228 expectedResult []kubecontainer.Annotation 229 }{ 230 { 231 description: "empty annotations", 232 claimInfo: &ClaimInfo{ 233 annotations: map[string][]kubecontainer.Annotation{}, 234 }, 235 }, 236 { 237 description: "nil annotations", 238 claimInfo: &ClaimInfo{}, 239 }, 240 { 241 description: "valid annotations", 242 claimInfo: &ClaimInfo{ 243 annotations: map[string][]kubecontainer.Annotation{ 244 "test-plugin1": { 245 { 246 Name: "cdi.k8s.io/test-plugin1_claim-uid1", 247 Value: "vendor.com/device=device1", 248 }, 249 { 250 Name: "cdi.k8s.io/test-plugin1_claim-uid2", 251 Value: "vendor.com/device=device2", 252 }, 253 }, 254 "test-plugin2": { 255 { 256 Name: "cdi.k8s.io/test-plugin2_claim-uid1", 257 Value: "vendor.com/device=device1", 258 }, 259 { 260 Name: "cdi.k8s.io/test-plugin2_claim-uid2", 261 Value: "vendor.com/device=device2", 262 }, 263 }, 264 }, 265 }, 266 expectedResult: []kubecontainer.Annotation{ 267 { 268 Name: "cdi.k8s.io/test-plugin1_claim-uid1", 269 Value: "vendor.com/device=device1", 270 }, 271 { 272 Name: "cdi.k8s.io/test-plugin1_claim-uid2", 273 Value: "vendor.com/device=device2", 274 }, 275 { 276 Name: "cdi.k8s.io/test-plugin2_claim-uid1", 277 Value: "vendor.com/device=device1", 278 }, 279 { 280 Name: "cdi.k8s.io/test-plugin2_claim-uid2", 281 Value: "vendor.com/device=device2", 282 }, 283 }, 284 }, 285 } { 286 t.Run(test.description, func(t *testing.T) { 287 result := test.claimInfo.annotationsAsList() 288 sort.Slice(result, func(i, j int) bool { 289 return result[i].Name < result[j].Name 290 }) 291 assert.Equal(t, test.expectedResult, result) 292 }) 293 } 294 } 295 296 func TestClaimInfoCDIdevicesAsList(t *testing.T) { 297 for _, test := range []struct { 298 description string 299 claimInfo *ClaimInfo 300 expectedResult []kubecontainer.CDIDevice 301 }{ 302 { 303 description: "empty CDI devices", 304 claimInfo: &ClaimInfo{ 305 ClaimInfoState: state.ClaimInfoState{ 306 CDIDevices: map[string][]string{}, 307 }, 308 }, 309 }, 310 { 311 description: "nil CDI devices", 312 claimInfo: &ClaimInfo{}, 313 }, 314 { 315 description: "valid CDI devices", 316 claimInfo: &ClaimInfo{ 317 ClaimInfoState: state.ClaimInfoState{ 318 CDIDevices: map[string][]string{ 319 "test-plugin1": { 320 "vendor.com/device=device1", 321 "vendor.com/device=device2", 322 }, 323 "test-plugin2": { 324 "vendor.com/device=device1", 325 "vendor.com/device=device2", 326 }, 327 }, 328 }, 329 }, 330 expectedResult: []kubecontainer.CDIDevice{ 331 { 332 Name: "vendor.com/device=device1", 333 }, 334 { 335 Name: "vendor.com/device=device1", 336 }, 337 { 338 Name: "vendor.com/device=device2", 339 }, 340 { 341 Name: "vendor.com/device=device2", 342 }, 343 }, 344 }, 345 } { 346 t.Run(test.description, func(t *testing.T) { 347 result := test.claimInfo.cdiDevicesAsList() 348 sort.Slice(result, func(i, j int) bool { 349 return result[i].Name < result[j].Name 350 }) 351 assert.Equal(t, test.expectedResult, result) 352 }) 353 } 354 } 355 func TestClaimInfoAddPodReference(t *testing.T) { 356 podUID := types.UID("pod-uid") 357 for _, test := range []struct { 358 description string 359 claimInfo *ClaimInfo 360 expectedLen int 361 }{ 362 { 363 description: "successfully add pod reference", 364 claimInfo: &ClaimInfo{ 365 ClaimInfoState: state.ClaimInfoState{ 366 PodUIDs: sets.New[string](), 367 }, 368 }, 369 expectedLen: 1, 370 }, 371 { 372 description: "duplicate pod reference", 373 claimInfo: &ClaimInfo{ 374 ClaimInfoState: state.ClaimInfoState{ 375 PodUIDs: sets.New[string](string(podUID)), 376 }, 377 }, 378 expectedLen: 1, 379 }, 380 { 381 description: "duplicate pod reference", 382 claimInfo: &ClaimInfo{ 383 ClaimInfoState: state.ClaimInfoState{ 384 PodUIDs: sets.New[string]("pod-uid1"), 385 }, 386 }, 387 expectedLen: 2, 388 }, 389 } { 390 t.Run(test.description, func(t *testing.T) { 391 test.claimInfo.addPodReference(podUID) 392 assert.True(t, test.claimInfo.hasPodReference(podUID)) 393 assert.Len(t, test.claimInfo.PodUIDs, test.expectedLen) 394 }) 395 } 396 } 397 398 func TestClaimInfoHasPodReference(t *testing.T) { 399 podUID := types.UID("pod-uid") 400 for _, test := range []struct { 401 description string 402 claimInfo *ClaimInfo 403 expectedResult bool 404 }{ 405 { 406 description: "claim doesn't reference pod", 407 claimInfo: &ClaimInfo{ 408 ClaimInfoState: state.ClaimInfoState{ 409 PodUIDs: sets.New[string](), 410 }, 411 }, 412 }, 413 { 414 description: "claim references pod", 415 claimInfo: &ClaimInfo{ 416 ClaimInfoState: state.ClaimInfoState{ 417 PodUIDs: sets.New[string](string(podUID)), 418 }, 419 }, 420 expectedResult: true, 421 }, 422 { 423 description: "empty claim info", 424 claimInfo: &ClaimInfo{}, 425 }, 426 } { 427 t.Run(test.description, func(t *testing.T) { 428 assert.Equal(t, test.claimInfo.hasPodReference(podUID), test.expectedResult) 429 }) 430 } 431 } 432 433 func TestClaimInfoDeletePodReference(t *testing.T) { 434 podUID := types.UID("pod-uid") 435 for _, test := range []struct { 436 description string 437 claimInfo *ClaimInfo 438 }{ 439 { 440 description: "claim doesn't reference pod", 441 claimInfo: &ClaimInfo{ 442 ClaimInfoState: state.ClaimInfoState{ 443 PodUIDs: sets.New[string](), 444 }, 445 }, 446 }, 447 { 448 description: "claim references pod", 449 claimInfo: &ClaimInfo{ 450 ClaimInfoState: state.ClaimInfoState{ 451 PodUIDs: sets.New[string](string(podUID)), 452 }, 453 }, 454 }, 455 { 456 description: "empty claim info", 457 claimInfo: &ClaimInfo{}, 458 }, 459 } { 460 t.Run(test.description, func(t *testing.T) { 461 test.claimInfo.deletePodReference(podUID) 462 assert.False(t, test.claimInfo.hasPodReference(podUID)) 463 }) 464 } 465 } 466 467 func TestClaimInfoSetPrepared(t *testing.T) { 468 for _, test := range []struct { 469 description string 470 claimInfo *ClaimInfo 471 }{ 472 { 473 description: "claim info is not prepared", 474 claimInfo: &ClaimInfo{ 475 prepared: false, 476 }, 477 }, 478 { 479 description: "claim info is prepared", 480 claimInfo: &ClaimInfo{ 481 prepared: true, 482 }, 483 }, 484 { 485 description: "empty claim info", 486 claimInfo: &ClaimInfo{}, 487 }, 488 } { 489 t.Run(test.description, func(t *testing.T) { 490 test.claimInfo.setPrepared() 491 assert.Equal(t, test.claimInfo.isPrepared(), true) 492 }) 493 } 494 } 495 496 func TestClaimInfoIsPrepared(t *testing.T) { 497 for _, test := range []struct { 498 description string 499 claimInfo *ClaimInfo 500 expectedResult bool 501 }{ 502 { 503 description: "claim info is not prepared", 504 claimInfo: &ClaimInfo{ 505 prepared: false, 506 }, 507 expectedResult: false, 508 }, 509 { 510 description: "claim info is prepared", 511 claimInfo: &ClaimInfo{ 512 prepared: true, 513 }, 514 expectedResult: true, 515 }, 516 { 517 description: "empty claim info", 518 claimInfo: &ClaimInfo{}, 519 expectedResult: false, 520 }, 521 } { 522 t.Run(test.description, func(t *testing.T) { 523 assert.Equal(t, test.claimInfo.isPrepared(), test.expectedResult) 524 }) 525 } 526 } 527 528 // claimInfoCache test cases 529 func TestNewClaimInfoCache(t *testing.T) { 530 for _, test := range []struct { 531 description string 532 stateDir string 533 checkpointName string 534 wantErr bool 535 }{ 536 { 537 description: "successfully created cache", 538 stateDir: t.TempDir(), 539 checkpointName: "test-checkpoint", 540 }, 541 { 542 description: "empty parameters", 543 wantErr: true, 544 }, 545 { 546 description: "empty checkpoint name", 547 stateDir: t.TempDir(), 548 wantErr: true, 549 }, 550 { 551 description: "incorrect checkpoint name", 552 stateDir: path.Join(t.TempDir(), "incorrect checkpoint"), 553 wantErr: true, 554 }, 555 } { 556 t.Run(test.description, func(t *testing.T) { 557 result, err := newClaimInfoCache(test.stateDir, test.checkpointName) 558 if test.wantErr { 559 assert.Error(t, err) 560 return 561 } 562 assert.NoError(t, err) 563 assert.NotNil(t, result) 564 }) 565 } 566 } 567 568 func TestClaimInfoCacheWithLock(t *testing.T) { 569 for _, test := range []struct { 570 description string 571 funcGen func(cache *claimInfoCache) func() error 572 wantErr bool 573 }{ 574 { 575 description: "cache is locked inside a function", 576 funcGen: func(cache *claimInfoCache) func() error { 577 return func() error { 578 if cache.RWMutex.TryLock() { 579 return errors.New("Lock succeeded") 580 } 581 return nil 582 } 583 }, 584 }, 585 { 586 description: "cache is Rlocked inside a function", 587 funcGen: func(cache *claimInfoCache) func() error { 588 return func() error { 589 if cache.RWMutex.TryRLock() { 590 return errors.New("RLock succeeded") 591 } 592 return nil 593 } 594 }, 595 }, 596 { 597 description: "successfully called function", 598 funcGen: func(cache *claimInfoCache) func() error { 599 return func() error { 600 return nil 601 } 602 }, 603 }, 604 { 605 description: "erroring function", 606 funcGen: func(cache *claimInfoCache) func() error { 607 return func() error { 608 return errors.New("test error") 609 } 610 }, 611 wantErr: true, 612 }, 613 } { 614 t.Run(test.description, func(t *testing.T) { 615 cache, err := newClaimInfoCache(t.TempDir(), "test-checkpoint") 616 assert.NoError(t, err) 617 assert.NotNil(t, cache) 618 err = cache.withLock(test.funcGen(cache)) 619 if test.wantErr { 620 assert.Error(t, err) 621 return 622 } 623 assert.NoError(t, err) 624 }) 625 } 626 } 627 628 func TestClaimInfoCacheWithRLock(t *testing.T) { 629 for _, test := range []struct { 630 description string 631 funcGen func(cache *claimInfoCache) func() error 632 wantErr bool 633 }{ 634 { 635 description: "RLock-ed cache allows another RLock", 636 funcGen: func(cache *claimInfoCache) func() error { 637 return func() error { 638 if !cache.RWMutex.TryRLock() { 639 return errors.New("RLock failed") 640 } 641 return nil 642 } 643 }, 644 }, 645 { 646 description: "cache is locked inside a function", 647 funcGen: func(cache *claimInfoCache) func() error { 648 return func() error { 649 if cache.RWMutex.TryLock() { 650 return errors.New("Lock succeeded") 651 } 652 return nil 653 } 654 }, 655 }, 656 { 657 description: "successfully called function", 658 funcGen: func(cache *claimInfoCache) func() error { 659 return func() error { 660 return nil 661 } 662 }, 663 }, 664 { 665 description: "erroring function", 666 funcGen: func(cache *claimInfoCache) func() error { 667 return func() error { 668 return errors.New("test error") 669 } 670 }, 671 wantErr: true, 672 }, 673 } { 674 t.Run(test.description, func(t *testing.T) { 675 cache, err := newClaimInfoCache(t.TempDir(), "test-checkpoint") 676 assert.NoError(t, err) 677 assert.NotNil(t, cache) 678 err = cache.withRLock(test.funcGen(cache)) 679 if test.wantErr { 680 assert.Error(t, err) 681 return 682 } 683 assert.NoError(t, err) 684 }) 685 } 686 } 687 688 func TestClaimInfoCacheAdd(t *testing.T) { 689 for _, test := range []struct { 690 description string 691 claimInfo *ClaimInfo 692 }{ 693 { 694 description: "claimInfo successfully added", 695 claimInfo: &ClaimInfo{ 696 ClaimInfoState: state.ClaimInfoState{ 697 ClaimName: "test-claim", 698 Namespace: "test-namespace", 699 }, 700 }, 701 }, 702 } { 703 t.Run(test.description, func(t *testing.T) { 704 cache, err := newClaimInfoCache(t.TempDir(), "test-checkpoint") 705 assert.NoError(t, err) 706 assert.NotNil(t, cache) 707 cache.add(test.claimInfo) 708 assert.True(t, cache.contains(test.claimInfo.ClaimName, test.claimInfo.Namespace)) 709 }) 710 } 711 } 712 713 func TestClaimInfoCacheContains(t *testing.T) { 714 claimName := "test-claim" 715 namespace := "test-namespace" 716 for _, test := range []struct { 717 description string 718 claimInfo *ClaimInfo 719 claimInfoCache *claimInfoCache 720 expectedResult bool 721 }{ 722 { 723 description: "cache hit", 724 claimInfoCache: &claimInfoCache{ 725 claimInfo: map[string]*ClaimInfo{ 726 namespace + "/" + claimName: { 727 ClaimInfoState: state.ClaimInfoState{ 728 ClaimName: claimName, 729 Namespace: namespace, 730 }, 731 }, 732 }, 733 }, 734 claimInfo: &ClaimInfo{ 735 ClaimInfoState: state.ClaimInfoState{ 736 ClaimName: claimName, 737 Namespace: namespace, 738 }, 739 }, 740 expectedResult: true, 741 }, 742 { 743 description: "cache miss", 744 claimInfoCache: &claimInfoCache{}, 745 claimInfo: &ClaimInfo{ 746 ClaimInfoState: state.ClaimInfoState{ 747 ClaimName: claimName, 748 Namespace: namespace, 749 }, 750 }, 751 }, 752 { 753 description: "cache miss: empty cache and empty claim info", 754 claimInfoCache: &claimInfoCache{}, 755 claimInfo: &ClaimInfo{ 756 ClaimInfoState: state.ClaimInfoState{}, 757 }, 758 }, 759 } { 760 t.Run(test.description, func(t *testing.T) { 761 assert.Equal(t, test.expectedResult, test.claimInfoCache.contains(test.claimInfo.ClaimName, test.claimInfo.Namespace)) 762 }) 763 } 764 } 765 766 func TestClaimInfoCacheGet(t *testing.T) { 767 claimName := "test-claim" 768 namespace := "test-namespace" 769 for _, test := range []struct { 770 description string 771 claimInfoCache *claimInfoCache 772 expectedNil bool 773 expectedExists bool 774 }{ 775 { 776 description: "cache hit", 777 claimInfoCache: &claimInfoCache{ 778 claimInfo: map[string]*ClaimInfo{ 779 namespace + "/" + claimName: { 780 ClaimInfoState: state.ClaimInfoState{ 781 ClaimName: claimName, 782 Namespace: namespace, 783 }, 784 }, 785 }, 786 }, 787 expectedExists: true, 788 }, 789 { 790 description: "cache miss", 791 claimInfoCache: &claimInfoCache{}, 792 expectedNil: true, 793 }, 794 } { 795 t.Run(test.description, func(t *testing.T) { 796 result, exists := test.claimInfoCache.get(claimName, namespace) 797 assert.Equal(t, test.expectedExists, exists) 798 assert.Equal(t, test.expectedNil, result == nil) 799 }) 800 } 801 } 802 803 func TestClaimInfoCacheDelete(t *testing.T) { 804 claimName := "test-claim" 805 namespace := "test-namespace" 806 for _, test := range []struct { 807 description string 808 claimInfoCache *claimInfoCache 809 }{ 810 { 811 description: "item in cache", 812 claimInfoCache: &claimInfoCache{ 813 claimInfo: map[string]*ClaimInfo{ 814 claimName + namespace: { 815 ClaimInfoState: state.ClaimInfoState{ 816 ClaimName: claimName, 817 Namespace: namespace, 818 }, 819 }, 820 }, 821 }, 822 }, 823 { 824 description: "item not in cache", 825 claimInfoCache: &claimInfoCache{}, 826 }, 827 } { 828 t.Run(test.description, func(t *testing.T) { 829 test.claimInfoCache.delete(claimName, namespace) 830 assert.False(t, test.claimInfoCache.contains(claimName, namespace)) 831 }) 832 } 833 } 834 835 func TestClaimInfoCacheHasPodReference(t *testing.T) { 836 claimName := "test-claim" 837 namespace := "test-namespace" 838 uid := types.UID("test-uid") 839 for _, test := range []struct { 840 description string 841 claimInfoCache *claimInfoCache 842 expectedResult bool 843 }{ 844 { 845 description: "uid is referenced", 846 claimInfoCache: &claimInfoCache{ 847 claimInfo: map[string]*ClaimInfo{ 848 claimName + namespace: { 849 ClaimInfoState: state.ClaimInfoState{ 850 ClaimName: claimName, 851 Namespace: namespace, 852 PodUIDs: sets.New[string](string(uid)), 853 }, 854 }, 855 }, 856 }, 857 expectedResult: true, 858 }, 859 { 860 description: "uid is not referenced", 861 claimInfoCache: &claimInfoCache{}, 862 }, 863 } { 864 t.Run(test.description, func(t *testing.T) { 865 assert.Equal(t, test.expectedResult, test.claimInfoCache.hasPodReference(uid)) 866 }) 867 } 868 } 869 870 func TestSyncToCheckpoint(t *testing.T) { 871 for _, test := range []struct { 872 description string 873 stateDir string 874 checkpointName string 875 wantErr bool 876 }{ 877 { 878 description: "successfully checkpointed cache", 879 stateDir: t.TempDir(), 880 checkpointName: "test-checkpoint", 881 }, 882 } { 883 t.Run(test.description, func(t *testing.T) { 884 cache, err := newClaimInfoCache(test.stateDir, test.checkpointName) 885 assert.NoError(t, err) 886 err = cache.syncToCheckpoint() 887 if test.wantErr { 888 assert.Error(t, err) 889 return 890 } 891 assert.NoError(t, err) 892 }) 893 } 894 }