@@ -17,13 +17,14 @@ limitations under the License.
17
17
package resourceclaim
18
18
19
19
import (
20
- "context"
21
20
"errors"
22
21
"fmt"
23
22
"sort"
24
23
"sync"
25
24
"testing"
25
+ "time"
26
26
27
+ "github.com/onsi/gomega"
27
28
"github.com/stretchr/testify/assert"
28
29
29
30
v1 "k8s.io/api/core/v1"
@@ -38,7 +39,8 @@ import (
38
39
"k8s.io/component-base/metrics/testutil"
39
40
"k8s.io/klog/v2"
40
41
"k8s.io/kubernetes/pkg/controller"
41
- ephemeralvolumemetrics "k8s.io/kubernetes/pkg/controller/resourceclaim/metrics"
42
+ "k8s.io/kubernetes/pkg/controller/resourceclaim/metrics"
43
+ "k8s.io/kubernetes/test/utils/ktesting"
42
44
)
43
45
44
46
var (
79
81
}()
80
82
)
81
83
82
- func init () {
83
- klog .InitFlags (nil )
84
- }
85
-
86
84
func TestSyncHandler (t * testing.T ) {
87
85
tests := []struct {
88
86
name string
@@ -366,8 +364,8 @@ func TestSyncHandler(t *testing.T) {
366
364
for _ , tc := range tests {
367
365
// Run sequentially because of global logging and global metrics.
368
366
t .Run (tc .name , func (t * testing.T ) {
369
- ctx , cancel := context . WithCancel ( context . Background () )
370
- defer cancel ( )
367
+ tCtx := ktesting . Init ( t )
368
+ tCtx = ktesting . WithCancel ( tCtx )
371
369
372
370
var objects []runtime.Object
373
371
for _ , pod := range tc .pods {
@@ -392,19 +390,19 @@ func TestSyncHandler(t *testing.T) {
392
390
claimInformer := informerFactory .Resource ().V1alpha3 ().ResourceClaims ()
393
391
templateInformer := informerFactory .Resource ().V1alpha3 ().ResourceClaimTemplates ()
394
392
395
- ec , err := NewController (klog .FromContext (ctx ), fakeKubeClient , podInformer , claimInformer , templateInformer )
393
+ ec , err := NewController (klog .FromContext (tCtx ), fakeKubeClient , podInformer , claimInformer , templateInformer )
396
394
if err != nil {
397
395
t .Fatalf ("error creating ephemeral controller : %v" , err )
398
396
}
399
397
400
398
// Ensure informers are up-to-date.
401
- informerFactory .Start (ctx .Done ())
399
+ informerFactory .Start (tCtx .Done ())
402
400
stopInformers := func () {
403
- cancel ( )
401
+ tCtx . Cancel ( "stopping informers" )
404
402
informerFactory .Shutdown ()
405
403
}
406
404
defer stopInformers ()
407
- informerFactory .WaitForCacheSync (ctx .Done ())
405
+ informerFactory .WaitForCacheSync (tCtx .Done ())
408
406
409
407
// Add claims that only exist in the mutation cache.
410
408
for _ , claim := range tc .claimsInCache {
@@ -414,27 +412,27 @@ func TestSyncHandler(t *testing.T) {
414
412
// Simulate race: stop informers, add more pods that the controller doesn't know about.
415
413
stopInformers ()
416
414
for _ , pod := range tc .podsLater {
417
- _ , err := fakeKubeClient .CoreV1 ().Pods (pod .Namespace ).Create (ctx , pod , metav1.CreateOptions {})
415
+ _ , err := fakeKubeClient .CoreV1 ().Pods (pod .Namespace ).Create (tCtx , pod , metav1.CreateOptions {})
418
416
if err != nil {
419
417
t .Fatalf ("unexpected error while creating pod: %v" , err )
420
418
}
421
419
}
422
420
423
- err = ec .syncHandler (ctx , tc .key )
421
+ err = ec .syncHandler (tCtx , tc .key )
424
422
if err != nil && ! tc .expectedError {
425
423
t .Fatalf ("unexpected error while running handler: %v" , err )
426
424
}
427
425
if err == nil && tc .expectedError {
428
426
t .Fatalf ("unexpected success" )
429
427
}
430
428
431
- claims , err := fakeKubeClient .ResourceV1alpha3 ().ResourceClaims ("" ).List (ctx , metav1.ListOptions {})
429
+ claims , err := fakeKubeClient .ResourceV1alpha3 ().ResourceClaims ("" ).List (tCtx , metav1.ListOptions {})
432
430
if err != nil {
433
431
t .Fatalf ("unexpected error while listing claims: %v" , err )
434
432
}
435
433
assert .Equal (t , normalizeClaims (tc .expectedClaims ), normalizeClaims (claims .Items ))
436
434
437
- pods , err := fakeKubeClient .CoreV1 ().Pods ("" ).List (ctx , metav1.ListOptions {})
435
+ pods , err := fakeKubeClient .CoreV1 ().Pods ("" ).List (tCtx , metav1.ListOptions {})
438
436
if err != nil {
439
437
t .Fatalf ("unexpected error while listing pods: %v" , err )
440
438
}
@@ -455,6 +453,95 @@ func TestSyncHandler(t *testing.T) {
455
453
}
456
454
}
457
455
456
+ func TestResourceClaimEventHandler (t * testing.T ) {
457
+ tCtx := ktesting .Init (t )
458
+ tCtx = ktesting .WithCancel (tCtx )
459
+
460
+ fakeKubeClient := createTestClient ()
461
+ setupMetrics ()
462
+ informerFactory := informers .NewSharedInformerFactory (fakeKubeClient , controller .NoResyncPeriodFunc ())
463
+ podInformer := informerFactory .Core ().V1 ().Pods ()
464
+ claimInformer := informerFactory .Resource ().V1alpha3 ().ResourceClaims ()
465
+ templateInformer := informerFactory .Resource ().V1alpha3 ().ResourceClaimTemplates ()
466
+ claimClient := fakeKubeClient .ResourceV1alpha3 ().ResourceClaims (testNamespace )
467
+
468
+ _ , err := NewController (tCtx .Logger (), fakeKubeClient , podInformer , claimInformer , templateInformer )
469
+ tCtx .ExpectNoError (err , "creating ephemeral controller" )
470
+
471
+ informerFactory .Start (tCtx .Done ())
472
+ stopInformers := func () {
473
+ tCtx .Cancel ("stopping informers" )
474
+ informerFactory .Shutdown ()
475
+ }
476
+ defer stopInformers ()
477
+
478
+ var em numMetrics
479
+
480
+ _ , err = claimClient .Create (tCtx , testClaim , metav1.CreateOptions {})
481
+ em .claims ++
482
+ ktesting .Step (tCtx , "create claim" , func (tCtx ktesting.TContext ) {
483
+ tCtx .ExpectNoError (err )
484
+ em .Eventually (tCtx )
485
+ })
486
+
487
+ modifiedClaim := testClaim .DeepCopy ()
488
+ modifiedClaim .Labels = map [string ]string {"foo" : "bar" }
489
+ _ , err = claimClient .Update (tCtx , modifiedClaim , metav1.UpdateOptions {})
490
+ ktesting .Step (tCtx , "modify claim" , func (tCtx ktesting.TContext ) {
491
+ tCtx .ExpectNoError (err )
492
+ em .Consistently (tCtx )
493
+ })
494
+
495
+ _ , err = claimClient .Update (tCtx , testClaimAllocated , metav1.UpdateOptions {})
496
+ em .allocated ++
497
+ ktesting .Step (tCtx , "allocate claim" , func (tCtx ktesting.TContext ) {
498
+ tCtx .ExpectNoError (err )
499
+ em .Eventually (tCtx )
500
+ })
501
+
502
+ modifiedClaim = testClaimAllocated .DeepCopy ()
503
+ modifiedClaim .Labels = map [string ]string {"foo" : "bar2" }
504
+ _ , err = claimClient .Update (tCtx , modifiedClaim , metav1.UpdateOptions {})
505
+ ktesting .Step (tCtx , "modify claim" , func (tCtx ktesting.TContext ) {
506
+ tCtx .ExpectNoError (err )
507
+ em .Consistently (tCtx )
508
+ })
509
+
510
+ otherClaimAllocated := testClaimAllocated .DeepCopy ()
511
+ otherClaimAllocated .Name += "2"
512
+ _ , err = claimClient .Create (tCtx , otherClaimAllocated , metav1.CreateOptions {})
513
+ em .claims ++
514
+ em .allocated ++
515
+ ktesting .Step (tCtx , "create allocated claim" , func (tCtx ktesting.TContext ) {
516
+ tCtx .ExpectNoError (err )
517
+ em .Eventually (tCtx )
518
+ })
519
+
520
+ _ , err = claimClient .Update (tCtx , testClaim , metav1.UpdateOptions {})
521
+ em .allocated --
522
+ ktesting .Step (tCtx , "deallocate claim" , func (tCtx ktesting.TContext ) {
523
+ tCtx .ExpectNoError (err )
524
+ em .Eventually (tCtx )
525
+ })
526
+
527
+ err = claimClient .Delete (tCtx , testClaim .Name , metav1.DeleteOptions {})
528
+ em .claims --
529
+ ktesting .Step (tCtx , "delete deallocated claim" , func (tCtx ktesting.TContext ) {
530
+ tCtx .ExpectNoError (err )
531
+ em .Eventually (tCtx )
532
+ })
533
+
534
+ err = claimClient .Delete (tCtx , otherClaimAllocated .Name , metav1.DeleteOptions {})
535
+ em .claims --
536
+ em .allocated --
537
+ ktesting .Step (tCtx , "delete allocated claim" , func (tCtx ktesting.TContext ) {
538
+ tCtx .ExpectNoError (err )
539
+ em .Eventually (tCtx )
540
+ })
541
+
542
+ em .Consistently (tCtx )
543
+ }
544
+
458
545
func makeClaim (name , namespace , classname string , owner * metav1.OwnerReference ) * resourceapi.ResourceClaim {
459
546
claim := & resourceapi.ResourceClaim {
460
547
ObjectMeta : metav1.ObjectMeta {Name : name , Namespace : namespace },
@@ -596,6 +683,34 @@ func createResourceClaimReactor() func(action k8stesting.Action) (handled bool,
596
683
597
684
// Metrics helpers
598
685
686
+ type numMetrics struct {
687
+ claims float64
688
+ allocated float64
689
+ }
690
+
691
+ func getNumMetric () (em numMetrics , err error ) {
692
+ em .claims , err = testutil .GetGaugeMetricValue (metrics .NumResourceClaims )
693
+ if err != nil {
694
+ return
695
+ }
696
+ em .allocated , err = testutil .GetGaugeMetricValue (metrics .NumAllocatedResourceClaims )
697
+ return
698
+ }
699
+
700
+ func (em numMetrics ) Eventually (tCtx ktesting.TContext ) {
701
+ g := gomega .NewWithT (tCtx )
702
+ tCtx .Helper ()
703
+
704
+ g .Eventually (getNumMetric ).WithTimeout (5 * time .Second ).Should (gomega .Equal (em ))
705
+ }
706
+
707
+ func (em numMetrics ) Consistently (tCtx ktesting.TContext ) {
708
+ g := gomega .NewWithT (tCtx )
709
+ tCtx .Helper ()
710
+
711
+ g .Consistently (getNumMetric ).WithTimeout (time .Second ).Should (gomega .Equal (em ))
712
+ }
713
+
599
714
type expectedMetrics struct {
600
715
numCreated int
601
716
numFailures int
@@ -604,12 +719,12 @@ type expectedMetrics struct {
604
719
func expectMetrics (t * testing.T , em expectedMetrics ) {
605
720
t .Helper ()
606
721
607
- actualCreated , err := testutil .GetCounterMetricValue (ephemeralvolumemetrics .ResourceClaimCreateAttempts )
722
+ actualCreated , err := testutil .GetCounterMetricValue (metrics .ResourceClaimCreateAttempts )
608
723
handleErr (t , err , "ResourceClaimCreate" )
609
724
if actualCreated != float64 (em .numCreated ) {
610
725
t .Errorf ("Expected claims to be created %d, got %v" , em .numCreated , actualCreated )
611
726
}
612
- actualConflicts , err := testutil .GetCounterMetricValue (ephemeralvolumemetrics .ResourceClaimCreateFailures )
727
+ actualConflicts , err := testutil .GetCounterMetricValue (metrics .ResourceClaimCreateFailures )
613
728
handleErr (t , err , "ResourceClaimCreate/Conflict" )
614
729
if actualConflicts != float64 (em .numFailures ) {
615
730
t .Errorf ("Expected claims to have conflicts %d, got %v" , em .numFailures , actualConflicts )
@@ -623,7 +738,9 @@ func handleErr(t *testing.T, err error, metricName string) {
623
738
}
624
739
625
740
func setupMetrics () {
626
- ephemeralvolumemetrics .RegisterMetrics ()
627
- ephemeralvolumemetrics .ResourceClaimCreateAttempts .Reset ()
628
- ephemeralvolumemetrics .ResourceClaimCreateFailures .Reset ()
741
+ metrics .RegisterMetrics ()
742
+ metrics .ResourceClaimCreateAttempts .Reset ()
743
+ metrics .ResourceClaimCreateFailures .Reset ()
744
+ metrics .NumResourceClaims .Set (0 )
745
+ metrics .NumAllocatedResourceClaims .Set (0 )
629
746
}
0 commit comments