Skip to content

Commit

Permalink
Fix unit test coverage in KubeadmConfig
Browse files Browse the repository at this point in the history
Signed-off-by: killianmuldoon <[email protected]>
  • Loading branch information
killianmuldoon committed Jan 18, 2023
1 parent e274f44 commit 484b4cf
Showing 1 changed file with 66 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,17 @@ func TestKubeadmConfigReconciler_MachineToBootstrapMapFuncReturn(t *testing.T) {
// Reconcile returns early if the kubeadm config is ready because it should never re-generate bootstrap data.
func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfKubeadmConfigIsReady(t *testing.T) {
g := NewWithT(t)

cluster := builder.Cluster(metav1.NamespaceDefault, "cluster1").Build()
cluster.Status.InfrastructureReady = true
machine := builder.Machine(metav1.NamespaceDefault, "m1").WithClusterName("cluster1").Build()
config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")
addKubeadmConfigToMachine(config, machine)

config.Status.Ready = true

objects := []client.Object{
cluster,
machine,
config,
}
myclient := fake.NewClientBuilder().WithObjects(objects...).Build()
Expand All @@ -117,7 +123,7 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfKubeadmConfigIsReady(t *
g.Expect(result.RequeueAfter).To(Equal(time.Duration(0)))
}

// Reconcile returns early if the kubeadm config is ready because it should never re-generate bootstrap data.
// Reconcile should update owner references on bootstrap secrets on creation and update.
func TestKubeadmConfigReconciler_TestSecretOwnerReferenceReconciliation(t *testing.T) {
g := NewWithT(t)

Expand Down Expand Up @@ -249,14 +255,20 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnNilIfReferencedMachineIsNotFoun
// If the machine has bootstrap data secret reference, there is no need to generate more bootstrap data.
func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfMachineHasDataSecretName(t *testing.T) {
g := NewWithT(t)
cluster := builder.Cluster(metav1.NamespaceDefault, "cluster1").Build()
cluster.Status.InfrastructureReady = true

machine := builder.Machine(metav1.NamespaceDefault, "machine").
WithVersion("v1.19.1").
WithClusterName("cluster1").
WithBootstrapTemplate(bootstrapbuilder.KubeadmConfig(metav1.NamespaceDefault, "cfg").Unstructured()).
Build()
machine.Spec.Bootstrap.DataSecretName = pointer.String("something")

config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")
addKubeadmConfigToMachine(config, machine)
objects := []client.Object{
cluster,
machine,
config,
}
Expand All @@ -273,9 +285,12 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfMachineHasDataSecretName
},
}
result, err := k.Reconcile(ctx, request)
actual := &bootstrapv1.KubeadmConfig{}
g.Expect(myclient.Get(ctx, client.ObjectKey{Namespace: config.Namespace, Name: config.Name}, actual)).To(Succeed())
g.Expect(err).NotTo(HaveOccurred())
g.Expect(result.Requeue).To(BeFalse())
g.Expect(result.RequeueAfter).To(Equal(time.Duration(0)))
assertHasTrueCondition(g, myclient, request, bootstrapv1.DataSecretAvailableCondition)
}

func TestKubeadmConfigReconciler_ReturnEarlyIfClusterInfraNotReady(t *testing.T) {
Expand Down Expand Up @@ -328,35 +343,7 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnEarlyIfMachineHasNoCluster(t *t
WithBootstrapTemplate(bootstrapbuilder.KubeadmConfig(metav1.NamespaceDefault, "cfg").Unstructured()).
Build()
config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")

objects := []client.Object{
machine,
config,
}
myclient := fake.NewClientBuilder().WithObjects(objects...).Build()

k := &KubeadmConfigReconciler{
Client: myclient,
}

request := ctrl.Request{
NamespacedName: client.ObjectKey{
Namespace: metav1.NamespaceDefault,
Name: "cfg",
},
}
_, err := k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred())
}

// This does not expect an error, hoping the machine gets updated with a cluster.
func TestKubeadmConfigReconciler_Reconcile_ReturnNilIfMachineDoesNotHaveAssociatedCluster(t *testing.T) {
g := NewWithT(t)
machine := builder.Machine(metav1.NamespaceDefault, "machine").
WithVersion("v1.19.1").
WithBootstrapTemplate(bootstrapbuilder.KubeadmConfig(metav1.NamespaceDefault, "cfg").Unstructured()).
Build()
config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")
addKubeadmConfigToMachine(config, machine)

objects := []client.Object{
machine,
Expand Down Expand Up @@ -390,6 +377,7 @@ func TestKubeadmConfigReconciler_Reconcile_ReturnNilIfAssociatedClusterIsNotFoun
Build()
config := newKubeadmConfig(metav1.NamespaceDefault, "cfg")

addKubeadmConfigToMachine(config, machine)
objects := []client.Object{
// intentionally omitting cluster
machine,
Expand Down Expand Up @@ -430,7 +418,7 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueJoiningNodesIfControlPlaneNotI
objects []client.Object
}{
{
name: "requeue worker when control plane is not yet initialiezd",
name: "requeue worker when control plane is not yet initialized",
request: ctrl.Request{
NamespacedName: client.ObjectKey{
Namespace: workerJoinConfig.Namespace,
Expand Down Expand Up @@ -482,11 +470,19 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueJoiningNodesIfControlPlaneNotI
func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T) {
g := NewWithT(t)

configName := "control-plane-init-cfg"
cluster := builder.Cluster(metav1.NamespaceDefault, "cluster").Build()
cluster.Spec.ControlPlaneEndpoint = clusterv1.APIEndpoint{Host: "validhost", Port: 6443}
cluster.Status.InfrastructureReady = true
conditions.MarkTrue(cluster, clusterv1.ControlPlaneInitializedCondition)

controlPlaneInitMachine := newControlPlaneMachine(cluster, "control-plane-init-machine")
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine.Namespace, "control-plane-init-cfg")
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneInitMachine.Namespace, configName)
controlPlaneInitConfig.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{}
controlPlaneInitConfig.Spec.JoinConfiguration.Discovery.BootstrapToken = &bootstrapv1.BootstrapTokenDiscovery{
CACertHashes: []string{"...."},
}

addKubeadmConfigToMachine(controlPlaneInitConfig, controlPlaneInitMachine)

objects := []client.Object{
Expand All @@ -499,8 +495,9 @@ func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T)
myclient := fake.NewClientBuilder().WithObjects(objects...).Build()

k := &KubeadmConfigReconciler{
Client: myclient,
KubeadmInitLock: &myInitLocker{},
Client: myclient,
KubeadmInitLock: &myInitLocker{},
remoteClientGetter: fakeremote.NewClusterClient,
}

request := ctrl.Request{
Expand All @@ -509,6 +506,9 @@ func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T)
Name: "control-plane-init-cfg",
},
}
s := &corev1.Secret{}
g.Expect(myclient.Get(ctx, client.ObjectKey{Namespace: metav1.NamespaceDefault, Name: configName}, s)).ToNot(Succeed())

result, err := k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(result.Requeue).To(BeFalse())
Expand All @@ -522,6 +522,9 @@ func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T)
assertHasTrueCondition(g, myclient, request, bootstrapv1.CertificatesAvailableCondition)
assertHasTrueCondition(g, myclient, request, bootstrapv1.DataSecretAvailableCondition)

// Expect the Secret to exist, and for it to contain some data under the "value" key.
g.Expect(myclient.Get(ctx, client.ObjectKey{Namespace: metav1.NamespaceDefault, Name: configName}, s)).To(Succeed())
g.Expect(len(s.Data["value"])).To(BeNumerically(">", 0))
// Ensure that we don't fail trying to refresh any bootstrap tokens
_, err = k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -561,11 +564,15 @@ func TestKubeadmConfigReconciler_Reconcile_ErrorIfJoiningControlPlaneHasInvalidC
request := ctrl.Request{
NamespacedName: client.ObjectKey{
Namespace: metav1.NamespaceDefault,
Name: "control-plane-join-cfg",
Name: controlPlaneJoinConfig.Name,
},
}
_, err := k.Reconcile(ctx, request)
g.Expect(err).NotTo(HaveOccurred())
actualConfig := &bootstrapv1.KubeadmConfig{}
g.Expect(myclient.Get(ctx, client.ObjectKey{Namespace: controlPlaneJoinConfig.Namespace, Name: controlPlaneJoinConfig.Name}, actualConfig)).To(Succeed())
assertHasTrueCondition(g, myclient, request, bootstrapv1.DataSecretAvailableCondition)
assertHasTrueCondition(g, myclient, request, bootstrapv1.CertificatesAvailableCondition)
}

// If there is no APIEndpoint but everything is ready then requeue in hopes of a new APIEndpoint showing up eventually.
Expand Down Expand Up @@ -607,9 +614,16 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueIfControlPlaneIsMissingAPIEndp
g.Expect(err).NotTo(HaveOccurred())
g.Expect(result.Requeue).To(BeFalse())
g.Expect(result.RequeueAfter).To(Equal(10 * time.Second))

actualConfig := &bootstrapv1.KubeadmConfig{}
g.Expect(myclient.Get(ctx, client.ObjectKey{Namespace: workerJoinConfig.Namespace, Name: workerJoinConfig.Name}, actualConfig)).To(Succeed())

// At this point the DataSecretAvailableCondition should not be set. CertificatesAvailableCondition should be true.
g.Expect(conditions.Get(actualConfig, bootstrapv1.DataSecretAvailableCondition)).To(BeNil())
assertHasTrueCondition(g, myclient, request, bootstrapv1.CertificatesAvailableCondition)
}

func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
func TestReconcileIfJoinCertificatesAvailableConditioninNodesAndControlPlaneIsReady(t *testing.T) {
cluster := builder.Cluster(metav1.NamespaceDefault, "cluster").Build()
cluster.Status.InfrastructureReady = true
conditions.MarkTrue(cluster, clusterv1.ControlPlaneInitializedCondition)
Expand Down Expand Up @@ -1848,6 +1862,17 @@ func TestKubeadmConfigReconciler_Reconcile_ExactlyOneControlPlaneMachineInitiali
g.Expect(err).NotTo(HaveOccurred())
g.Expect(result.Requeue).To(BeFalse())
g.Expect(result.RequeueAfter).To(Equal(30 * time.Second))
confList := &bootstrapv1.KubeadmConfigList{}
g.Expect(myclient.List(ctx, confList)).To(Succeed())
for _, c := range confList.Items {
// Ensure the DataSecretName is only set for controlPlaneInitConfigFirst.
if c.Name == controlPlaneInitConfigFirst.Name {
g.Expect(*c.Status.DataSecretName).To(Not(BeEmpty()))
}
if c.Name == controlPlaneInitConfigSecond.Name {
g.Expect(c.Status.DataSecretName).To(BeNil())
}
}
}

// Patch should be applied if there is an error in reconcile.
Expand Down Expand Up @@ -2252,6 +2277,10 @@ func addKubeadmConfigToMachine(config *bootstrapv1.KubeadmConfig, machine *clust
},
}

if machine.Spec.Bootstrap.ConfigRef == nil {
machine.Spec.Bootstrap.ConfigRef = &corev1.ObjectReference{}
}

machine.Spec.Bootstrap.ConfigRef.Name = config.Name
machine.Spec.Bootstrap.ConfigRef.Namespace = config.Namespace
}
Expand Down

0 comments on commit 484b4cf

Please sign in to comment.