@@ -22,15 +22,20 @@ import (
22
22
"reflect"
23
23
"testing"
24
24
25
+ "github.com/stretchr/testify/assert"
25
26
appsv1 "k8s.io/api/apps/v1"
26
27
corev1 "k8s.io/api/core/v1"
28
+ apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
27
29
"k8s.io/apimachinery/pkg/api/meta"
28
30
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
31
"k8s.io/apimachinery/pkg/runtime"
32
+ "k8s.io/apimachinery/pkg/runtime/schema"
30
33
"k8s.io/apimachinery/pkg/types"
34
+ "k8s.io/apimachinery/pkg/util/uuid"
31
35
fakedynamic "k8s.io/client-go/dynamic/fake"
32
36
"k8s.io/client-go/kubernetes/scheme"
33
37
"k8s.io/client-go/tools/record"
38
+ "k8s.io/utils/ptr"
34
39
controllerruntime "sigs.k8s.io/controller-runtime"
35
40
"sigs.k8s.io/controller-runtime/pkg/client"
36
41
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -39,6 +44,7 @@ import (
39
44
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
40
45
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
41
46
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
47
+ "github.com/karmada-io/karmada/pkg/events"
42
48
testing2 "github.com/karmada-io/karmada/pkg/search/proxy/testing"
43
49
"github.com/karmada-io/karmada/pkg/util"
44
50
"github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager"
@@ -439,3 +445,108 @@ func TestClusterResourceBindingController_newOverridePolicyFunc(t *testing.T) {
439
445
})
440
446
}
441
447
}
448
+
449
+ func TestUpdateClusterBindingDispatchingConditionIfNeeded (t * testing.T ) {
450
+ tests := []struct {
451
+ name string
452
+ binding * workv1alpha2.ClusterResourceBinding
453
+ expectedCondition metav1.Condition
454
+ expectedEventCount int
455
+ expectEventMessage string
456
+ }{
457
+ {
458
+ name : "Binding scheduling is suspended" ,
459
+ binding : newCrb (true , metav1.Condition {}),
460
+ expectedCondition : metav1.Condition {
461
+ Type : workv1alpha2 .Suspended ,
462
+ Status : metav1 .ConditionTrue ,
463
+ },
464
+ expectedEventCount : 1 ,
465
+ expectEventMessage : fmt .Sprintf ("%s %s %s" , corev1 .EventTypeNormal , events .EventReasonBindingScheduling , SuspendedSchedulingConditionMessage ),
466
+ },
467
+ {
468
+ name : "Binding scheduling is not suspended" ,
469
+ binding : newCrb (false , metav1.Condition {
470
+ Type : workv1alpha2 .Suspended ,
471
+ Status : metav1 .ConditionTrue ,
472
+ Reason : SuspendedSchedulingConditionReason ,
473
+ Message : SuspendedSchedulingConditionMessage ,
474
+ }),
475
+ expectedCondition : metav1.Condition {
476
+ Type : workv1alpha2 .Suspended ,
477
+ Status : metav1 .ConditionFalse ,
478
+ },
479
+ expectedEventCount : 1 ,
480
+ expectEventMessage : fmt .Sprintf ("%s %s %s" , corev1 .EventTypeNormal , events .EventReasonBindingScheduling , SchedulingConditionMessage ),
481
+ },
482
+ {
483
+ name : "Condition already matches, no update needed" ,
484
+ binding : newCrb (true , metav1.Condition {
485
+ Type : workv1alpha2 .Suspended ,
486
+ Status : metav1 .ConditionTrue ,
487
+ Reason : SuspendedSchedulingConditionReason ,
488
+ Message : SuspendedSchedulingConditionMessage ,
489
+ }),
490
+ expectedCondition : metav1.Condition {
491
+ Type : workv1alpha2 .Suspended ,
492
+ Status : metav1 .ConditionTrue ,
493
+ },
494
+ },
495
+ }
496
+
497
+ for _ , tt := range tests {
498
+ t .Run (tt .name , func (t * testing.T ) {
499
+ eventRecorder := record .NewFakeRecorder (1 )
500
+ c := newClusterResourceBindingController (tt .binding , eventRecorder )
501
+
502
+ updatedBinding := & workv1alpha2.ClusterResourceBinding {}
503
+ assert .NoError (t , c .Get (context .Background (), types.NamespacedName {Name : tt .binding .Name , Namespace : tt .binding .Namespace }, updatedBinding ))
504
+
505
+ err := updateBindingDispatchingConditionIfNeeded (context .Background (), c .Client , c .EventRecorder , tt .binding , apiextensionsv1 .ClusterScoped )
506
+ if err != nil {
507
+ t .Errorf ("updateBindingDispatchingConditionIfNeeded() returned an error: %v" , err )
508
+ }
509
+
510
+ assert .NoError (t , c .Get (context .Background (), types.NamespacedName {Name : tt .binding .Name , Namespace : tt .binding .Namespace }, updatedBinding ))
511
+ assert .True (t , meta .IsStatusConditionPresentAndEqual (tt .binding .Status .Conditions , tt .expectedCondition .Type , tt .expectedCondition .Status ))
512
+ assert .Equal (t , tt .expectedEventCount , len (eventRecorder .Events ))
513
+ if tt .expectEventMessage != "" {
514
+ e := <- eventRecorder .Events
515
+ assert .Equal (t , tt .expectEventMessage , e )
516
+ }
517
+ })
518
+ }
519
+ }
520
+
521
+ func newClusterResourceBindingController (binding * workv1alpha2.ClusterResourceBinding , eventRecord record.EventRecorder ) ClusterResourceBindingController {
522
+ restMapper := meta .NewDefaultRESTMapper ([]schema.GroupVersion {corev1 .SchemeGroupVersion })
523
+ fakeClient := fake .NewClientBuilder ().WithScheme (gclient .NewSchema ()).WithObjects (binding ).WithStatusSubresource (binding ).WithRESTMapper (restMapper ).Build ()
524
+ return ClusterResourceBindingController {
525
+ Client : fakeClient ,
526
+ EventRecorder : eventRecord ,
527
+ }
528
+ }
529
+
530
+ func newCrb (suspended bool , condition metav1.Condition ) * workv1alpha2.ClusterResourceBinding {
531
+ return & workv1alpha2.ClusterResourceBinding {
532
+ TypeMeta : metav1.TypeMeta {
533
+ Kind : workv1alpha2 .ResourceKindResourceBinding ,
534
+ APIVersion : workv1alpha2 .GroupVersion .Version ,
535
+ },
536
+ ObjectMeta : metav1.ObjectMeta {
537
+ Name : "test-rb" ,
538
+ Namespace : "default" ,
539
+ UID : uuid .NewUUID (),
540
+ },
541
+ Spec : workv1alpha2.ResourceBindingSpec {
542
+ Suspension : & policyv1alpha1.Suspension {
543
+ Scheduling : ptr .To (suspended ),
544
+ },
545
+ },
546
+ Status : workv1alpha2.ResourceBindingStatus {
547
+ Conditions : []metav1.Condition {
548
+ condition ,
549
+ },
550
+ },
551
+ }
552
+ }
0 commit comments