Skip to content

Commit

Permalink
Merge pull request #5225 from fabriziopandini/clusterclass-test-cleanups
Browse files Browse the repository at this point in the history
🌱 Small cleanups to ClusterClass tests
  • Loading branch information
k8s-ci-robot authored Sep 15, 2021
2 parents b80194f + 9672f4a commit 6c9b898
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 101 deletions.
60 changes: 44 additions & 16 deletions controllers/topology/blueprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestGetBlueprint(t *testing.T) {
// TODO: Make composable version of these options in the builder package to reuse these filters across tests.
ignoreResourceVersion := cmpopts.IgnoreFields(metav1.ObjectMeta{}, "ResourceVersion")

// Create objects used across test cases.
infraClusterTemplate := testtypes.NewInfrastructureClusterTemplateBuilder(metav1.NamespaceDefault, "infraclustertemplate1").
Build()
controlPlaneTemplate := testtypes.NewControlPlaneTemplateBuilder(metav1.NamespaceDefault, "controlplanetemplate1").
Expand All @@ -67,6 +68,7 @@ func TestGetBlueprint(t *testing.T) {
Build()
mds := []clusterv1.MachineDeploymentClass{*machineDeployment}

// Define test cases.
tests := []struct {
name string
clusterClass *clusterv1.ClusterClass
Expand All @@ -75,35 +77,51 @@ func TestGetBlueprint(t *testing.T) {
wantErr bool
}{
{
name: "ClusterClass does not exist",
name: "Fails if ClusterClass does not exist",
wantErr: true,
},
{
name: "ClusterClass exists without references",
name: "Fails if ClusterClass does not have reference to the InfrastructureClusterTemplate",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "clusterclass1").
// No InfrastructureClusterTemplate reference!
Build(),
wantErr: true,
},
{
name: "Ref to missing InfraClusterTemplate",
name: "Fails if ClusterClass references an InfrastructureClusterTemplate that does not exist",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "clusterclass1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
Build(),
objects: []client.Object{
// infraClusterTemplate is missing!
},
wantErr: true,
},
{
name: "Valid ref to InfraClusterTemplate, Ref to missing ControlPlaneTemplate",
name: "Fails if ClusterClass does not have reference to the ControlPlaneTemplate",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
// No ControlPlaneTemplate reference!
Build(),
objects: []client.Object{
infraClusterTemplate,
},
wantErr: true,
},
{
name: "Fails if ClusterClass does not have reference to the ControlPlaneTemplate",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplate).
Build(),
objects: []client.Object{
infraClusterTemplate,
// ControlPlaneTemplate is missing!
},
wantErr: true,
},
{
name: "Valid refs to InfraClusterTemplate and ControlPlaneTemplate",
name: "Should read a ClusterClass without worker classes",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplate).
Expand All @@ -125,7 +143,7 @@ func TestGetBlueprint(t *testing.T) {
},
},
{
name: "Valid refs to InfraClusterTemplate, ControlPlaneTemplate and ControlPlaneInfrastructureMachineTemplate",
name: "Should read a ClusterClass referencing an InfrastructureMachineTemplate for the ControlPlane (but without any worker class)",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplateWithInfrastructureMachine).
Expand All @@ -151,7 +169,7 @@ func TestGetBlueprint(t *testing.T) {
},
},
{
name: "Valid refs to InfraClusterTemplate, ControlPlaneTemplate, Ref to missing ControlPlaneInfrastructureMachineTemplate",
name: "Fails if ClusterClass references an InfrastructureMachineTemplate for the ControlPlane that does not exist",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplate).
Expand All @@ -160,11 +178,12 @@ func TestGetBlueprint(t *testing.T) {
objects: []client.Object{
infraClusterTemplate,
controlPlaneTemplate,
// controlPlaneInfrastructureMachineTemplate is missing!
},
wantErr: true,
},
{
name: "Valid refs to InfraClusterTemplate, ControlPlaneTemplate, worker InfrastructureMachineTemplate and BootstrapTemplate",
name: "Should read a ClusterClass with a MachineDeploymentClass",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplate).
Expand Down Expand Up @@ -199,7 +218,7 @@ func TestGetBlueprint(t *testing.T) {
},
},
{
name: "Valid refs to InfraClusterTemplate, ControlPlaneTemplate, InfrastructureMachineTemplate, Ref to missing BootstrapTemplate",
name: "Fails if ClusterClass has a MachineDeploymentClass referencing a BootstrapTemplate that does not exist",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplate).
Expand All @@ -209,11 +228,12 @@ func TestGetBlueprint(t *testing.T) {
infraClusterTemplate,
controlPlaneTemplate,
workerInfrastructureMachineTemplate,
// workerBootstrapTemplate is missing!
},
wantErr: true,
},
{
name: "Valid refs to InfraClusterTemplate, ControlPlaneTemplate, worker BootstrapTemplate, Ref to missing InfrastructureMachineTemplate",
name: "Fails if ClusterClass has a MachineDeploymentClass referencing a InfrastructureMachineTemplate that does not exist",
clusterClass: testtypes.NewClusterClassBuilder(metav1.NamespaceDefault, "class1").
WithInfrastructureClusterTemplate(infraClusterTemplate).
WithControlPlaneTemplate(controlPlaneTemplate).
Expand All @@ -223,6 +243,7 @@ func TestGetBlueprint(t *testing.T) {
infraClusterTemplate,
controlPlaneTemplate,
workerBootstrapTemplate,
// workerInfrastructureTemplate is missing!
},
wantErr: true,
},
Expand All @@ -231,33 +252,38 @@ func TestGetBlueprint(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

objs := []client.Object{}
objs = append(objs, crds...)
objs = append(objs, tt.objects...)

// Set up a cluster using the ClusterClass, if any.
cluster := testtypes.NewClusterBuilder(metav1.NamespaceDefault, "cluster1").Build()

if tt.clusterClass != nil {
cluster.Spec.Topology = &clusterv1.Topology{
Class: tt.clusterClass.Name,
}
objs = append(objs, tt.clusterClass)
} else {
cluster.Spec.Topology = &clusterv1.Topology{
Class: "foo",
}
}

// Sets up the fakeClient for the test case.
objs := []client.Object{}
objs = append(objs, crds...)
objs = append(objs, tt.objects...)
if tt.clusterClass != nil {
objs = append(objs, tt.clusterClass)
}
fakeClient := fake.NewClientBuilder().
WithScheme(fakeScheme).
WithObjects(objs...).
Build()

// Calls getBlueprint.
r := &ClusterReconciler{
Client: fakeClient,
UnstructuredCachingClient: fakeClient,
}
got, err := r.getBlueprint(ctx, scope.New(cluster).Current.Cluster)

// Checks the return error.
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
} else {
Expand All @@ -269,6 +295,8 @@ func TestGetBlueprint(t *testing.T) {
return
}

// Checks the blueprint content.

// Expect the Diff resulting from each object comparison to be empty when ignoring ObjectMeta.ResourceVersion
// This is necessary as the FakeClient adds its own ResourceVersion on object creation.
g.Expect(cmp.Diff(tt.want.ClusterClass, got.ClusterClass, ignoreResourceVersion)).To(Equal(""),
Expand Down
23 changes: 13 additions & 10 deletions controllers/topology/current_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (r *ClusterReconciler) getCurrentMachineDeploymentState(ctx context.Context
for i := range md.Items {
m := &md.Items[i]

// Retrieve the name which is usually assigned in Cluster's topology
// Retrieve the name which is assigned in Cluster's topology
// from a well-defined label.
mdTopologyName, ok := m.ObjectMeta.Labels[clusterv1.ClusterTopologyMachineDeploymentLabelName]
if !ok || len(mdTopologyName) == 0 {
Expand All @@ -143,24 +143,27 @@ func (r *ClusterReconciler) getCurrentMachineDeploymentState(ctx context.Context
if _, ok := state[mdTopologyName]; ok {
return nil, fmt.Errorf("duplicate %s found for label %s: %s", tlog.KObj{Obj: m}, clusterv1.ClusterTopologyMachineDeploymentLabelName, mdTopologyName)
}
infraRef := &m.Spec.Template.Spec.InfrastructureRef
if infraRef == nil {
return nil, fmt.Errorf("%s does not have a reference to a InfrastructureMachineTemplate", tlog.KObj{Obj: m})
}

// Gets the BootstrapTemplate
bootstrapRef := m.Spec.Template.Spec.Bootstrap.ConfigRef
if bootstrapRef == nil {
return nil, fmt.Errorf("%s does not have a reference to a Bootstrap Config", tlog.KObj{Obj: m})
}

i, err := r.getReference(ctx, infraRef)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("%s Infrastructure reference could not be retrieved", tlog.KObj{Obj: m}))
}
b, err := r.getReference(ctx, bootstrapRef)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("%s Bootstrap reference could not be retrieved", tlog.KObj{Obj: m}))
}

// Gets the InfrastructureMachineTemplate
infraRef := m.Spec.Template.Spec.InfrastructureRef
if infraRef.Name == "" {
return nil, fmt.Errorf("%s does not have a reference to a InfrastructureMachineTemplate", tlog.KObj{Obj: m})
}
i, err := r.getReference(ctx, &infraRef)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("%s Infrastructure reference could not be retrieved", tlog.KObj{Obj: m}))
}

state[mdTopologyName] = &scope.MachineDeploymentState{
Object: m,
BootstrapTemplate: b,
Expand Down
Loading

0 comments on commit 6c9b898

Please sign in to comment.