Skip to content

Commit

Permalink
Add unit tests for MPs in topology/scope package
Browse files Browse the repository at this point in the history
Co-authored-by: razashahid107 <razashahid107@gmail.com>
  • Loading branch information
willie-yao and abdurrehman107 committed Feb 21, 2024
1 parent ae2e1e9 commit 6685ddd
Show file tree
Hide file tree
Showing 5 changed files with 888 additions and 5 deletions.
234 changes: 233 additions & 1 deletion internal/controllers/topology/cluster/scope/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,103 @@ import (
"testing"

. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
"sigs.k8s.io/cluster-api/internal/test/builder"
)

func TestUpgrading(t *testing.T) {
func TestMDIsUpgrading(t *testing.T) {
g := NewWithT(t)
scheme := runtime.NewScheme()
g.Expect(clusterv1.AddToScheme(scheme)).To(Succeed())

tests := []struct {
name string
md *clusterv1.MachineDeployment
machines []*clusterv1.Machine
want bool
wantErr bool
}{
{
name: "should return false if all the machines of MachineDeployment have the same version as the MachineDeployment",
md: builder.MachineDeployment("ns", "md1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
machines: []*clusterv1.Machine{
builder.Machine("ns", "machine1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
builder.Machine("ns", "machine2").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
},
want: false,
wantErr: false,
},
{
name: "should return true if at least one of the machines of MachineDeployment has a different version",
md: builder.MachineDeployment("ns", "md1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
machines: []*clusterv1.Machine{
builder.Machine("ns", "machine1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
builder.Machine("ns", "machine2").
WithClusterName("cluster1").
WithVersion("v1.2.2").
Build(),
},
want: true,
wantErr: false,
},
{
name: "should return false if the MachineDeployment has no machines (creation phase)",
md: builder.MachineDeployment("ns", "md1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
machines: []*clusterv1.Machine{},
want: false,
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
ctx := context.Background()
objs := []client.Object{}
objs = append(objs, tt.md)
for _, m := range tt.machines {
objs = append(objs, m)
}
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build()
mdState := &MachineDeploymentState{
Object: tt.md,
}
got, err := mdState.IsUpgrading(ctx, fakeClient)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(got).To(Equal(tt.want))
}
})
}
}

func TestMDUpgrading(t *testing.T) {
g := NewWithT(t)
scheme := runtime.NewScheme()
g.Expect(clusterv1.AddToScheme(scheme)).To(Succeed())
Expand Down Expand Up @@ -69,3 +157,147 @@ func TestUpgrading(t *testing.T) {
g.Expect(got).To(BeComparableTo(want))
})
}

func TestMPIsUpgrading(t *testing.T) {
g := NewWithT(t)
scheme := runtime.NewScheme()
g.Expect(expv1.AddToScheme(scheme)).To(Succeed())
g.Expect(corev1.AddToScheme(scheme)).To(Succeed())

tests := []struct {
name string
mp *expv1.MachinePool
nodes []*corev1.Node
want bool
wantErr bool
}{
{
name: "should return false if all the nodes of MachinePool have the same version as the MachinePool",
mp: builder.MachinePool("ns", "mp1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
Build(),
nodes: []*corev1.Node{
builder.Node("node1").
WithStatus(corev1.NodeStatus{
NodeInfo: corev1.NodeSystemInfo{
KubeletVersion: "v1.2.3",
},
}).
Build(),
},
want: false,
wantErr: false,
},
{
name: "should return true if the MachinePool's node has a different kubelet version",
mp: builder.MachinePool("ns", "mp1").
WithClusterName("cluster1").
WithVersion("v1.2.3").
WithStatus(expv1.MachinePoolStatus{
NodeRefs: []corev1.ObjectReference{
{
Name: "node1",
},
},
}).
Build(),
nodes: []*corev1.Node{
builder.Node("node1").
WithStatus(corev1.NodeStatus{
NodeInfo: corev1.NodeSystemInfo{
KubeletVersion: "v1.2.2",
},
}).
Build(),
},
want: true,
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
ctx := context.Background()
objs := []client.Object{}
objs = append(objs, tt.mp)
for _, n := range tt.nodes {
objs = append(objs, n)
}
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build()
mpState := &MachinePoolState{
Object: tt.mp,
}
got, err := mpState.IsUpgrading(ctx, fakeClient)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
} else {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(got).To(Equal(tt.want))
}
})
}
}

func TestMPUpgrading(t *testing.T) {
g := NewWithT(t)
scheme := runtime.NewScheme()
g.Expect(expv1.AddToScheme(scheme)).To(Succeed())
g.Expect(corev1.AddToScheme(scheme)).To(Succeed())

ctx := context.Background()

t.Run("should return the names of the upgrading MachinePools", func(t *testing.T) {

Check failure on line 251 in internal/controllers/topology/cluster/scope/state_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)

Check warning on line 251 in internal/controllers/topology/cluster/scope/state_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)
stableMP := builder.MachinePool("ns", "stableMP").
WithClusterName("cluster1").
WithVersion("v1.2.3").
WithStatus(expv1.MachinePoolStatus{
NodeRefs: []corev1.ObjectReference{
{
Name: "stableMP-node1",
},
},
}).
Build()
stableMPNode := builder.Node("stableMP-node1").
WithStatus(corev1.NodeStatus{
NodeInfo: corev1.NodeSystemInfo{
KubeletVersion: "v1.2.3",
},
}).
Build()

upgradingMP := builder.MachinePool("ns", "upgradingMP").
WithClusterName("cluster2").
WithVersion("v1.2.3").
WithStatus(expv1.MachinePoolStatus{
NodeRefs: []corev1.ObjectReference{
{
Name: "upgradingMP-node1",
},
},
}).
Build()
upgradingMPNode := builder.Node("upgradingMP-node1").
WithStatus(corev1.NodeStatus{
NodeInfo: corev1.NodeSystemInfo{
KubeletVersion: "v1.2.2",
},
}).
Build()

objs := []client.Object{stableMP, stableMPNode, upgradingMP, upgradingMPNode}
fakeClient := fake.NewClientBuilder().WithObjects(objs...).WithScheme(scheme).Build()

mpsStateMap := MachinePoolsStateMap{
"stableMP": {Object: stableMP},
"upgradingMP": {Object: upgradingMP},
}
want := []string{"upgradingMP"}

got, err := mpsStateMap.Upgrading(ctx, fakeClient)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(got).To(BeComparableTo(want))
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ func TestNewUpgradeTracker(t *testing.T) {
},
{
name: "should set the value of 1 if given concurrency is less than 1",
options: []UpgradeTrackerOption{MaxMDUpgradeConcurrency(0)},
options: []UpgradeTrackerOption{MaxMDUpgradeConcurrency(0), MaxMPUpgradeConcurrency(0)},
want: 1,
},
{
name: "should set the value to the given concurrency if the value is greater than 0",
options: []UpgradeTrackerOption{MaxMDUpgradeConcurrency(2)},
options: []UpgradeTrackerOption{MaxMDUpgradeConcurrency(2), MaxMPUpgradeConcurrency(2)},
want: 2,
},
}
Expand All @@ -50,6 +50,7 @@ func TestNewUpgradeTracker(t *testing.T) {
g := NewWithT(t)
got := NewUpgradeTracker(tt.options...)
g.Expect(got.MachineDeployments.maxUpgradeConcurrency).To(Equal(tt.want))
g.Expect(got.MachinePools.maxUpgradeConcurrency).To(Equal(tt.want))
}
})
}
30 changes: 30 additions & 0 deletions internal/test/builder/builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,36 @@ func (c *TestControlPlaneBuilder) Build() *unstructured.Unstructured {
return c.obj
}

// NodeBuilder holds the variables required to build a Node.
type NodeBuilder struct {
name string
status corev1.NodeStatus
}

// Node returns a NodeBuilder.
func Node(name string) *NodeBuilder {
return &NodeBuilder{
name: name,
}
}

// WithStatus adds Status to the NodeBuilder.
func (n *NodeBuilder) WithStatus(status corev1.NodeStatus) *NodeBuilder {
n.status = status
return n
}

// Build produces a new Node from the information passed to the NodeBuilder.
func (n *NodeBuilder) Build() *corev1.Node {
obj := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: n.name,
},
Status: n.status,
}
return obj
}

// MachinePoolBuilder holds the variables and objects needed to build a generic MachinePool.
type MachinePoolBuilder struct {
namespace string
Expand Down
16 changes: 16 additions & 0 deletions internal/test/builder/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6685ddd

Please sign in to comment.