Skip to content

Commit 27854f9

Browse files
authored
Merge pull request #939 from hangscer8/add_unit
update unit test
2 parents a52a8f3 + 7902ebf commit 27854f9

File tree

3 files changed

+417
-2
lines changed

3 files changed

+417
-2
lines changed

pkg/controllers/cluster/controller_test.go

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"k8s.io/apimachinery/pkg/runtime"
2222
"k8s.io/apimachinery/pkg/types"
2323
"k8s.io/client-go/rest"
24+
k8stesting "k8s.io/client-go/testing"
2425
"k8s.io/client-go/tools/record"
2526
controllerruntime "sigs.k8s.io/controller-runtime"
2627
"sigs.k8s.io/controller-runtime/pkg/cache"
@@ -44,6 +45,27 @@ import (
4445
"sigs.k8s.io/controller-runtime/pkg/client/fake"
4546
)
4647

48+
func fetchTestingFake(obj interface{ RESTClient() rest.Interface }) *k8stesting.Fake {
49+
// https://stackoverflow.com/questions/69740891/mocking-errors-with-client-go-fake-client
50+
return reflect.Indirect(reflect.ValueOf(obj)).FieldByName("Fake").Interface().(*k8stesting.Fake)
51+
}
52+
53+
func removeReactorFromTestingTake(obj interface{ RESTClient() rest.Interface }, verb, resource string) {
54+
if fakeObj := fetchTestingFake(obj); fakeObj != nil {
55+
newReactionChain := make([]k8stesting.Reactor, 0)
56+
fakeObj.Lock()
57+
defer fakeObj.Unlock()
58+
for i := range fakeObj.ReactionChain {
59+
reaction := fakeObj.ReactionChain[i]
60+
if simpleReaction, ok := reaction.(*k8stesting.SimpleReactor); ok && simpleReaction.Verb == verb && simpleReaction.Resource == resource {
61+
continue // ignore
62+
}
63+
newReactionChain = append(newReactionChain, reaction)
64+
}
65+
fakeObj.ReactionChain = newReactionChain
66+
}
67+
}
68+
4769
func TestCompareClusterCondition(t *testing.T) {
4870
tests := []struct {
4971
name string
@@ -329,11 +351,39 @@ func Test_CleanExcessClusterOps(t *testing.T) {
329351
}
330352
controller.KubeanClusterOpsSet.KubeanV1alpha1().ClusterOperations().Create(context.Background(), clusterOperation, metav1.CreateOptions{})
331353
}
354+
clusterOperationRunning := &clusteroperationv1alpha1.ClusterOperation{
355+
TypeMeta: metav1.TypeMeta{
356+
Kind: "ClusterOperation",
357+
APIVersion: "kubean.io/v1alpha1",
358+
},
359+
ObjectMeta: metav1.ObjectMeta{
360+
Name: "my_kubean_ops_cluster_2_" + "running",
361+
Labels: map[string]string{constants.KubeanClusterLabelKey: "cluster1"},
362+
CreationTimestamp: metav1.Unix(int64(10), 0),
363+
},
364+
}
365+
clusterOperationRunning, _ = controller.KubeanClusterOpsSet.KubeanV1alpha1().ClusterOperations().Create(context.Background(), clusterOperationRunning, metav1.CreateOptions{})
366+
clusterOperationRunning.Status = clusteroperationv1alpha1.Status{
367+
Status: clusteroperationv1alpha1.RunningStatus,
368+
}
369+
controller.KubeanClusterOpsSet.KubeanV1alpha1().ClusterOperations().UpdateStatus(context.Background(), clusterOperationRunning, metav1.UpdateOptions{})
332370
result, _ := controller.CleanExcessClusterOps(exampleCluster, OpsBackupNum)
333371
return result
334372
},
335373
want: true,
336374
},
375+
{
376+
name: "get error",
377+
args: func() bool {
378+
fetchTestingFake(controller.KubeanClusterOpsSet.KubeanV1alpha1()).PrependReactor("list", "clusteroperations", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
379+
return true, nil, fmt.Errorf("this is error")
380+
})
381+
_, err := controller.CleanExcessClusterOps(exampleCluster, 5)
382+
removeReactorFromTestingTake(controller.KubeanClusterOpsSet.KubeanV1alpha1(), "list", "clusteroperations")
383+
return err != nil && err.Error() == "this is error"
384+
},
385+
want: true,
386+
},
337387
}
338388
for _, test := range tests {
339389
t.Run(test.name, func(t *testing.T) {
@@ -410,6 +460,31 @@ func Test_UpdateStatus(t *testing.T) {
410460
},
411461
want: true,
412462
},
463+
{
464+
name: "get one error",
465+
args: func() bool {
466+
exampleCluster := &clusterv1alpha1.Cluster{
467+
TypeMeta: metav1.TypeMeta{
468+
Kind: "Cluster",
469+
APIVersion: "kubean.io/v1alpha1",
470+
},
471+
ObjectMeta: metav1.ObjectMeta{
472+
Name: "cluster1",
473+
},
474+
Spec: clusterv1alpha1.Spec{
475+
HostsConfRef: &apis.ConfigMapRef{NameSpace: "kubean-system", Name: "hosts-a"},
476+
VarsConfRef: &apis.ConfigMapRef{NameSpace: "kubean-system", Name: "vars-a"},
477+
},
478+
}
479+
fetchTestingFake(controller.KubeanClusterOpsSet.KubeanV1alpha1()).PrependReactor("list", "clusteroperations", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
480+
return true, nil, fmt.Errorf("this is error")
481+
})
482+
err := controller.UpdateStatus(exampleCluster)
483+
removeReactorFromTestingTake(controller.KubeanClusterOpsSet.KubeanV1alpha1(), "list", "clusteroperations")
484+
return err != nil && err.Error() == "this is error"
485+
},
486+
want: true,
487+
},
413488
}
414489
for _, test := range tests {
415490
t.Run(test.name, func(t *testing.T) {
@@ -491,6 +566,96 @@ func TestReconcile(t *testing.T) {
491566
},
492567
needRequeue: true,
493568
},
569+
{
570+
name: "CleanExcessClusterOps with error",
571+
args: func() bool {
572+
controller := genController()
573+
exampleCluster := &clusterv1alpha1.Cluster{
574+
TypeMeta: metav1.TypeMeta{
575+
Kind: "Cluster",
576+
APIVersion: "kubean.io/v1alpha1",
577+
},
578+
ObjectMeta: metav1.ObjectMeta{
579+
Name: "cluster1",
580+
},
581+
Spec: clusterv1alpha1.Spec{
582+
HostsConfRef: &apis.ConfigMapRef{NameSpace: "kubean-system", Name: "hosts-a"},
583+
VarsConfRef: &apis.ConfigMapRef{NameSpace: "kubean-system", Name: "vars-a"},
584+
},
585+
}
586+
clusterOps := &clusteroperationv1alpha1.ClusterOperation{
587+
TypeMeta: metav1.TypeMeta{
588+
Kind: "ClusterOperation",
589+
APIVersion: "kubean.io/v1alpha1",
590+
},
591+
ObjectMeta: metav1.ObjectMeta{
592+
Name: "cluster1-ops",
593+
Labels: map[string]string{constants.KubeanClusterLabelKey: exampleCluster.Name},
594+
},
595+
}
596+
controller.Client.Create(context.Background(), clusterOps)
597+
controller.Client.Create(context.Background(), exampleCluster)
598+
controller.KubeanClusterSet.KubeanV1alpha1().Clusters().Create(context.Background(), exampleCluster, metav1.CreateOptions{})
599+
controller.KubeanClusterOpsSet.KubeanV1alpha1().ClusterOperations().Create(context.Background(), clusterOps, metav1.CreateOptions{})
600+
fetchTestingFake(controller.KubeanClusterOpsSet.KubeanV1alpha1()).PrependReactor("list", "clusteroperations", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
601+
return true, nil, fmt.Errorf("this is error")
602+
})
603+
result, _ := controller.Reconcile(context.Background(), controllerruntime.Request{NamespacedName: types.NamespacedName{Name: "cluster1"}})
604+
removeReactorFromTestingTake(controller.KubeanClusterOpsSet.KubeanV1alpha1(), "list", "clusteroperations")
605+
return result.RequeueAfter > 0
606+
},
607+
needRequeue: true,
608+
},
609+
{
610+
name: "CleanExcessClusterOps with true",
611+
args: func() bool {
612+
controller := genController()
613+
exampleCluster := &clusterv1alpha1.Cluster{
614+
TypeMeta: metav1.TypeMeta{
615+
Kind: "Cluster",
616+
APIVersion: "kubean.io/v1alpha1",
617+
},
618+
ObjectMeta: metav1.ObjectMeta{
619+
Name: "cluster1",
620+
},
621+
Spec: clusterv1alpha1.Spec{
622+
HostsConfRef: &apis.ConfigMapRef{NameSpace: "kubean-system", Name: "hosts-a"},
623+
VarsConfRef: &apis.ConfigMapRef{NameSpace: "kubean-system", Name: "vars-a"},
624+
},
625+
}
626+
clusterOps := &clusteroperationv1alpha1.ClusterOperation{
627+
TypeMeta: metav1.TypeMeta{
628+
Kind: "ClusterOperation",
629+
APIVersion: "kubean.io/v1alpha1",
630+
},
631+
ObjectMeta: metav1.ObjectMeta{
632+
Name: "cluster1-ops",
633+
Labels: map[string]string{constants.KubeanClusterLabelKey: exampleCluster.Name},
634+
},
635+
}
636+
controller.Client.Create(context.Background(), clusterOps)
637+
controller.Client.Create(context.Background(), exampleCluster)
638+
controller.KubeanClusterSet.KubeanV1alpha1().Clusters().Create(context.Background(), exampleCluster, metav1.CreateOptions{})
639+
controller.KubeanClusterOpsSet.KubeanV1alpha1().ClusterOperations().Create(context.Background(), clusterOps, metav1.CreateOptions{})
640+
for i := 0; i < 100; i++ {
641+
clusterOperation := &clusteroperationv1alpha1.ClusterOperation{
642+
TypeMeta: metav1.TypeMeta{
643+
Kind: "ClusterOperation",
644+
APIVersion: "kubean.io/v1alpha1",
645+
},
646+
ObjectMeta: metav1.ObjectMeta{
647+
Name: "my_kubean_ops_cluster_2_" + fmt.Sprint(i),
648+
Labels: map[string]string{constants.KubeanClusterLabelKey: "cluster1"},
649+
CreationTimestamp: metav1.Unix(int64(i), 0),
650+
},
651+
}
652+
controller.KubeanClusterOpsSet.KubeanV1alpha1().ClusterOperations().Create(context.Background(), clusterOperation, metav1.CreateOptions{})
653+
}
654+
result, _ := controller.Reconcile(context.Background(), controllerruntime.Request{NamespacedName: types.NamespacedName{Name: "cluster1"}})
655+
return result.RequeueAfter > 0
656+
},
657+
needRequeue: true,
658+
},
494659
}
495660
for _, test := range tests {
496661
t.Run(test.name, func(t *testing.T) {

0 commit comments

Comments
 (0)