Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

🏃‍♂️ Add a test to ensure that exactly one control plane machine initializes if there are multiple control plane machines defined #221

Merged
merged 1 commit into from
Sep 22, 2019
Merged
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
157 changes: 115 additions & 42 deletions controllers/kubeadmconfig_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,13 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfKubeadmConfigIsReady(t *
}
result, err := k.Reconcile(request)
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expected to requeue")
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != time.Duration(0) {
t.Fatal("did not expected to requeue after")
t.Fatal("did not expect to requeue after")
}
}

Expand Down Expand Up @@ -182,13 +182,13 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfMachineHasBootstrapData(
}
result, err := k.Reconcile(request)
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expected to requeue")
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != time.Duration(0) {
t.Fatal("did not expected to requeue after")
t.Fatal("did not expect to requeue after")
}
}

Expand Down Expand Up @@ -258,8 +258,8 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueJoiningNodesIfControlPlaneNotI
workerMachine := newWorkerMachine(cluster)
workerJoinConfig := newWorkerJoinKubeadmConfig(workerMachine)

controlPlaneMachine := newControlPlaneMachine(cluster)
controlPlaneJoinConfig := newControlPlaneJoinKubeadmConfig(controlPlaneMachine, "control-plane-join-cfg")
controlPlaneJoinMachine := newControlPlaneMachine(cluster, "control-plane-join-machine")
controlPlaneJoinConfig := newControlPlaneJoinKubeadmConfig(controlPlaneJoinMachine, "control-plane-join-cfg")

testcases := []struct {
name string
Expand Down Expand Up @@ -290,7 +290,7 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueJoiningNodesIfControlPlaneNotI
},
objects: []runtime.Object{
cluster,
controlPlaneMachine,
controlPlaneJoinMachine,
controlPlaneJoinConfig,
},
},
Expand Down Expand Up @@ -324,12 +324,12 @@ func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T)
cluster := newCluster("cluster")
cluster.Status.InfrastructureReady = true

controlPlaneMachine := newControlPlaneMachine(cluster)
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneMachine, "control-plane-init-cfg")
controlPlaneInitMachine := newControlPlaneMachine(cluster, "control-plane-init-machine")
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine, "control-plane-init-cfg")

objects := []runtime.Object{
cluster,
controlPlaneMachine,
controlPlaneInitMachine,
controlPlaneInitConfig,
}
objects = append(objects, createSecrets(t, cluster, controlPlaneInitConfig)...)
Expand All @@ -353,10 +353,10 @@ func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T)
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue != false {
t.Fatal("did not expected to requeue")
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != time.Duration(0) {
t.Fatal("did not expected to requeue after")
t.Fatal("did not expect to requeue after")
}

cfg, err := getKubeadmConfig(myclient, "control-plane-init-cfg")
Expand Down Expand Up @@ -414,10 +414,10 @@ func TestKubeadmConfigReconciler_Reconcile_ErrorIfJoiningControlPlaneHasInvalidC
cluster.Status.InfrastructureReady = true
cluster.Status.ControlPlaneInitialized = true
cluster.Status.APIEndpoints = []clusterv1.APIEndpoint{{Host: "100.105.150.1", Port: 6443}}
controlPlaneMachine := newControlPlaneMachine(cluster)
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneMachine, "control-plane-init-cfg")
controlPlaneInitMachine := newControlPlaneMachine(cluster, "control-plane-init-machine")
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine, "control-plane-init-cfg")

controlPlaneJoinMachine := newControlPlaneMachine(cluster)
controlPlaneJoinMachine := newControlPlaneMachine(cluster, "control-plane-join-machine")
controlPlaneJoinConfig := newControlPlaneJoinKubeadmConfig(controlPlaneJoinMachine, "control-plane-join-cfg")
controlPlaneJoinConfig.Spec.JoinConfiguration.ControlPlane = nil // Makes controlPlaneJoinConfig invalid for a control plane machine

Expand Down Expand Up @@ -453,8 +453,8 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueIfControlPlaneIsMissingAPIEndp
cluster := newCluster("cluster")
cluster.Status.InfrastructureReady = true
cluster.Status.ControlPlaneInitialized = true
controlPlaneMachine := newControlPlaneMachine(cluster)
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneMachine, "control-plane-init-cfg")
controlPlaneInitMachine := newControlPlaneMachine(cluster, "control-plane-init-machine")
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine, "control-plane-init-cfg")

workerMachine := newWorkerMachine(cluster)
workerJoinConfig := newWorkerJoinKubeadmConfig(workerMachine)
Expand Down Expand Up @@ -482,10 +482,10 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueIfControlPlaneIsMissingAPIEndp
}
result, err := k.Reconcile(request)
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expected to requeue")
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != 10*time.Second {
t.Fatal("expected to requeue after 10s")
Expand All @@ -497,20 +497,20 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
cluster.Status.InfrastructureReady = true
cluster.Status.ControlPlaneInitialized = true
cluster.Status.APIEndpoints = []clusterv1.APIEndpoint{{Host: "100.105.150.1", Port: 6443}}
controlPlaneInitMachine := newControlPlaneMachine(cluster)
initConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine, "my-control-plane-init-config")
controlPlaneInitMachine := newControlPlaneMachine(cluster, "control-plane-init-machine")
initConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine, "control-plane-init-config")

workerMachine := newWorkerMachine(cluster)
workerJoinConfig := newWorkerJoinKubeadmConfig(workerMachine)

controlPlaneMachine := newControlPlaneMachine(cluster)
controlPlaneJoinConfig := newControlPlaneJoinKubeadmConfig(controlPlaneMachine, "control-plane-join-cfg")
controlPlaneJoinMachine := newControlPlaneMachine(cluster, "control-plane-join-machine")
controlPlaneJoinConfig := newControlPlaneJoinKubeadmConfig(controlPlaneJoinMachine, "control-plane-join-cfg")

objects := []runtime.Object{
cluster,
workerMachine,
workerJoinConfig,
controlPlaneMachine,
controlPlaneJoinMachine,
controlPlaneJoinConfig,
}
objects = append(objects, createSecrets(t, cluster, initConfig)...)
Expand All @@ -530,18 +530,18 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
}
result, err := k.Reconcile(request)
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expected to requeue")
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != time.Duration(0) {
t.Fatal("did not expected to requeue after")
t.Fatal("did not expect to requeue after")
}

cfg, err := getKubeadmConfig(myclient, "worker-join-cfg")
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}

if cfg.Status.Ready != true {
Expand All @@ -560,18 +560,18 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
}
result, err = k.Reconcile(request)
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expected to requeue")
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != time.Duration(0) {
t.Fatal("did not expected to requeue after")
t.Fatal("did not expect to requeue after")
}

cfg, err = getKubeadmConfig(myclient, "control-plane-join-cfg")
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}

if cfg.Status.Ready != true {
Expand All @@ -585,11 +585,11 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
myremoteclient, _ := k.SecretsClientFactory.NewSecretsClient(nil, nil)
l, err := myremoteclient.List(metav1.ListOptions{})
if err != nil {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}

if len(l.Items) != 2 {
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
t.Fatalf("Failed to reconcile:\n %+v", err)
}
}

Expand Down Expand Up @@ -898,7 +898,7 @@ func TestKubeadmConfigReconciler_Reconcile_AlwaysCheckCAVerificationUnlessReques
Port: 6443,
},
}
controlPlaneInitMachine := newControlPlaneMachine(cluster)
controlPlaneInitMachine := newControlPlaneMachine(cluster, "my-control-plane-init-machine")
initConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine, "my-control-plane-init-config")

controlPlaneMachineName := "my-machine"
Expand Down Expand Up @@ -1017,7 +1017,7 @@ func TestKubeadmConfigReconciler_Reconcile_DoesNotFailIfCASecretsAlreadyExist(t
cluster := newCluster("my-cluster")
cluster.Status.InfrastructureReady = true
cluster.Status.ControlPlaneInitialized = false
m := newControlPlaneMachine(cluster)
m := newControlPlaneMachine(cluster, "control-plane-machine")
configName := "my-config"
c := newControlPlaneInitKubeadmConfig(m, configName)
scrt := &corev1.Secret{
Expand All @@ -1044,6 +1044,67 @@ func TestKubeadmConfigReconciler_Reconcile_DoesNotFailIfCASecretsAlreadyExist(t
}
}

// Exactly one control plane machine initializes if there are multiple control plane machines defined
func TestKubeadmConfigReconciler_Reconcile_ExactlyOneControlPlaneMachineInitializes(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side topic: i think that _ in function names fails golint
is this file ignored from golint checks?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure actually..i didn't see anything in the code that indicated tests are skipped. I'd say let's not worry about it for this PR. I've made an issue for it #223

cluster := newCluster("cluster")
cluster.Status.InfrastructureReady = true

controlPlaneInitMachineFirst := newControlPlaneMachine(cluster, "control-plane-init-machine-first")
controlPlaneInitConfigFirst := newControlPlaneInitKubeadmConfig(controlPlaneInitMachineFirst, "control-plane-init-cfg-first")

controlPlaneInitMachineSecond := newControlPlaneMachine(cluster, "control-plane-init-machine-second")
controlPlaneInitConfigSecond := newControlPlaneInitKubeadmConfig(controlPlaneInitMachineSecond, "control-plane-init-cfg-second")

objects := []runtime.Object{
cluster,
controlPlaneInitMachineFirst,
controlPlaneInitConfigFirst,
controlPlaneInitMachineSecond,
controlPlaneInitConfigSecond,
}
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
k := &KubeadmConfigReconciler{
Log: log.Log,
Client: myclient,
SecretsClientFactory: newFakeSecretFactory(),
KubeadmInitLock: &myInitLocker{},
}

request := ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: "default",
Name: "control-plane-init-cfg-first",
},
}
result, err := k.Reconcile(request)
if err != nil {
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != time.Duration(0) {
t.Fatal("did not expect to requeue after")
}

request = ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: "default",
Name: "control-plane-init-cfg-second",
},
}
result, err = k.Reconcile(request)
if err != nil {
t.Fatalf("Failed to reconcile:\n %+v", err)
}
if result.Requeue == true {
t.Fatal("did not expect to requeue")
}
if result.RequeueAfter != 30*time.Second {
t.Fatal("expected to requeue after 30s")
}
}

// test utils

// newCluster return a CAPI cluster object
Expand Down Expand Up @@ -1092,8 +1153,8 @@ func newWorkerMachine(cluster *clusterv1.Cluster) *clusterv1.Machine {
return newMachine(cluster, "worker-machine") // machine by default is a worker node (not the bootstrapNode)
}

func newControlPlaneMachine(cluster *clusterv1.Cluster) *clusterv1.Machine {
m := newMachine(cluster, "control-plane-machine")
func newControlPlaneMachine(cluster *clusterv1.Cluster, name string) *clusterv1.Machine {
m := newMachine(cluster, name)
m.Labels[clusterv1.MachineControlPlaneLabelName] = "true"
return m
}
Expand Down Expand Up @@ -1180,9 +1241,21 @@ func (f FakeSecretFactory) NewSecretsClient(client client.Client, cluster *clust
return f.client, nil
}

type myInitLocker struct{}
type myInitLocker struct {
locked bool
}

func (m *myInitLocker) Lock(_ context.Context, _ *clusterv1.Cluster, _ *clusterv1.Machine) bool {
if !m.locked {
m.locked = true
return true
}
return false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we always return true for the fake Lock?

}

func (m *myInitLocker) Unlock(_ context.Context, _ *clusterv1.Cluster) bool {
if m.locked {
m.locked = false
}
return true
}
func (m *myInitLocker) Unlock(_ context.Context, _ *clusterv1.Cluster) bool { return true }