Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌱 Refactor Lease controller test cases. #435

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion pkg/registration/spoke/lease/lease_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type managedClusterLeaseController struct {
clusterName string
hubClusterLister clusterv1listers.ManagedClusterLister
lastLeaseDurationSeconds int32
leaseUpdater *leaseUpdater
leaseUpdater leaseUpdaterInterface
}

// NewManagedClusterLeaseController creates a new managed cluster lease controller on the managed cluster.
Expand Down Expand Up @@ -85,6 +85,11 @@ func (c *managedClusterLeaseController) sync(ctx context.Context, syncCtx factor
return nil
}

type leaseUpdaterInterface interface {
start(ctx context.Context, leaseDuration time.Duration)
stop()
}

// leaseUpdater periodically updates the lease of a managed cluster
type leaseUpdater struct {
hubClient clientset.Interface
Expand Down
171 changes: 125 additions & 46 deletions pkg/registration/spoke/lease/lease_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import (
"time"

"github.com/openshift/library-go/pkg/operator/events/eventstesting"
coordinationv1 "k8s.io/api/coordination/v1"
"k8s.io/apimachinery/pkg/runtime"
kubefake "k8s.io/client-go/kubernetes/fake"
clienttesting "k8s.io/client-go/testing"

clusterfake "open-cluster-management.io/api/client/cluster/clientset/versioned/fake"
clusterinformers "open-cluster-management.io/api/client/cluster/informers/externalversions"
Expand All @@ -18,37 +16,76 @@ import (
testinghelpers "open-cluster-management.io/ocm/pkg/registration/helpers/testing"
)

func TestLeaseUpdate(t *testing.T) {
func TestSync(t *testing.T) {
cases := []struct {
name string
clusters []runtime.Object
validateActions func(t *testing.T, actions []clienttesting.Action)
needToStartUpdateBefore bool
expectedErr string
name string
clusters []runtime.Object
controllerlastLeaseDurationSeconds int32
expectSyncErr string
validateActions func(fakeLeaseUpdater *fakeLeaseUpdater)
}{
{
name: "start lease update routine",
clusters: []runtime.Object{testinghelpers.NewAcceptedManagedCluster()},
validateActions: func(t *testing.T, actions []clienttesting.Action) {
testingcommon.AssertUpdateActions(t, actions)
leaseObj := actions[1].(clienttesting.UpdateActionImpl).Object
lastLeaseObj := actions[len(actions)-1].(clienttesting.UpdateActionImpl).Object
testinghelpers.AssertLeaseUpdated(t, leaseObj.(*coordinationv1.Lease), lastLeaseObj.(*coordinationv1.Lease))
name: "start lease update routine",
clusters: []runtime.Object{testinghelpers.NewAcceptedManagedCluster()},
controllerlastLeaseDurationSeconds: testinghelpers.TestLeaseDurationSeconds,
validateActions: func(fakeLeaseUpdater *fakeLeaseUpdater) {
// start method should be called
if !fakeLeaseUpdater.startCalled {
t.Error("start method should be called")
}
// stop method should not be called
if fakeLeaseUpdater.stopCalled {
t.Error("stop method should not be called")
}
},
},
{
name: "delete a managed cluster after lease update routine is started",
clusters: []runtime.Object{},
needToStartUpdateBefore: true,
validateActions: testingcommon.AssertNoMoreUpdates,
expectedErr: "unable to get managed cluster \"testmanagedcluster\" from hub: " +
name: "the managed cluster can not be found",
clusters: []runtime.Object{},
controllerlastLeaseDurationSeconds: testinghelpers.TestLeaseDurationSeconds,
expectSyncErr: "unable to get managed cluster \"testmanagedcluster\" from hub: " +
"managedcluster.cluster.open-cluster-management.io \"testmanagedcluster\" not found",
validateActions: func(fakeLeaseUpdater *fakeLeaseUpdater) {
// start method should not be called
if fakeLeaseUpdater.startCalled {
t.Error("start method should not be called")
}
// stop method should be called
if !fakeLeaseUpdater.stopCalled {
t.Error("stop method should be called")
}
},
},
{
name: "unaccept a managed cluster",
clusters: []runtime.Object{testinghelpers.NewManagedCluster()},
controllerlastLeaseDurationSeconds: testinghelpers.TestLeaseDurationSeconds,
validateActions: func(fakeLeaseUpdater *fakeLeaseUpdater) {
// start method should not be called
if fakeLeaseUpdater.startCalled {
t.Error("start method should not be called")
}
// stop method should be called
if !fakeLeaseUpdater.stopCalled {
t.Error("stop method should be called")
}
},
},
{
name: "unaccept a managed cluster after lease update routine is started",
clusters: []runtime.Object{testinghelpers.NewManagedCluster()},
needToStartUpdateBefore: true,
validateActions: testingcommon.AssertNoMoreUpdates,
name: "update the lease duration",
clusters: []runtime.Object{testinghelpers.NewAcceptedManagedCluster()},
controllerlastLeaseDurationSeconds: testinghelpers.TestLeaseDurationSeconds + 1,
validateActions: func(fakeLeaseUpdater *fakeLeaseUpdater) {
// first stop the old lease update routine, and then start a new lease update routine
// stop method should be called
if !fakeLeaseUpdater.stopCalled {
t.Error("stop method should be called eventually")
}
// start method should be called
if !fakeLeaseUpdater.startCalled {
t.Error("start method should not called eventually")
}
},
},
}

Expand All @@ -63,32 +100,74 @@ func TestLeaseUpdate(t *testing.T) {
}
}

hubClient := kubefake.NewSimpleClientset(testinghelpers.NewManagedClusterLease("managed-cluster-lease", time.Now()))

leaseUpdater := &leaseUpdater{
hubClient: hubClient,
clusterName: testinghelpers.TestManagedClusterName,
leaseName: "managed-cluster-lease",
recorder: eventstesting.NewTestingEventRecorder(t),
}

if c.needToStartUpdateBefore {
leaseUpdater.start(context.TODO(), time.Duration(testinghelpers.TestLeaseDurationSeconds)*time.Second)
// wait a few milliseconds to start the lease update routine
time.Sleep(500 * time.Millisecond)
}

ctrl := &managedClusterLeaseController{
clusterName: testinghelpers.TestManagedClusterName,
hubClusterLister: clusterInformerFactory.Cluster().V1().ManagedClusters().Lister(),
leaseUpdater: leaseUpdater,
clusterName: testinghelpers.TestManagedClusterName,
hubClusterLister: clusterInformerFactory.Cluster().V1().ManagedClusters().Lister(),
leaseUpdater: &fakeLeaseUpdater{},
lastLeaseDurationSeconds: c.controllerlastLeaseDurationSeconds,
}

syncErr := ctrl.sync(context.TODO(), testingcommon.NewFakeSyncContext(t, ""))
testingcommon.AssertError(t, syncErr, c.expectedErr)
testingcommon.AssertError(t, syncErr, c.expectSyncErr)

// wait one cycle (1 ~ 1.25s)
time.Sleep(2000 * time.Millisecond)
c.validateActions(t, hubClient.Actions())
if c.validateActions != nil {
c.validateActions(ctrl.leaseUpdater.(*fakeLeaseUpdater))
}
})
}
}

type fakeLeaseUpdater struct {
startCalled bool
stopCalled bool
}

func (f *fakeLeaseUpdater) start(ctx context.Context, leaseDuration time.Duration) {
f.startCalled = true
}

func (f *fakeLeaseUpdater) stop() {
f.stopCalled = true
}

func TestLeaseUpdater(t *testing.T) {
initRenewTime := time.Now()
hubClient := kubefake.NewSimpleClientset(testinghelpers.NewManagedClusterLease("managed-cluster-lease", initRenewTime))
leaseUpdater := &leaseUpdater{
hubClient: hubClient,
clusterName: testinghelpers.TestManagedClusterName,
leaseName: "managed-cluster-lease",
recorder: eventstesting.NewTestingEventRecorder(t),
}

// start the updater
ctx := context.Background()
leaseUpdater.start(ctx, time.Second*1)

// wait for 3 second, the all actions should be in get,update pairs
time.Sleep(time.Second * 3)
actions := hubClient.Actions()
if len(actions) == 0 {
t.Error("expect at least 1 update actions, but got 0")
return
}
for i := 0; i < len(actions); i += 2 {
if actions[i].GetVerb() != "get" {
t.Errorf("expect get action, but got %s", actions[i].GetVerb())
}
if actions[i+1].GetVerb() != "update" {
t.Errorf("expect update action, but got %s", actions[i+1].GetVerb())
}
}

// stop the updater
leaseUpdater.stop()
actionLen := len(actions)

// wait for 3 second, no new actions should be added
time.Sleep(time.Second * 3)
actions = hubClient.Actions()
if len(actions) != actionLen {
t.Errorf("expect %d actions, but got %d", actionLen, len(actions))
}
}
Loading