Skip to content

Commit 1ae8a33

Browse files
willie-yaosbueringer
authored andcommitted
Add unit tests for reconcile_state, cluster_controller, & conditions
1 parent 321096f commit 1ae8a33

File tree

9 files changed

+1248
-41
lines changed

9 files changed

+1248
-41
lines changed

controllers/remote/cluster_cache_tracker_fake.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func NewTestClusterCacheTracker(log logr.Logger, cl client.Client, scheme *runti
3030
client: cl,
3131
scheme: scheme,
3232
clusterAccessors: make(map[client.ObjectKey]*clusterAccessor),
33+
clusterLock: newKeyedMutex(),
3334
}
3435

3536
testCacheTracker.clusterAccessors[objKey] = &clusterAccessor{

internal/controllers/topology/cluster/cluster_controller_test.go

Lines changed: 219 additions & 18 deletions
Large diffs are not rendered by default.

internal/controllers/topology/cluster/conditions_test.go

Lines changed: 329 additions & 6 deletions
Large diffs are not rendered by default.

internal/controllers/topology/cluster/reconcile_state_test.go

Lines changed: 549 additions & 2 deletions
Large diffs are not rendered by default.

internal/controllers/topology/cluster/suite_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"time"
2525

2626
. "github.com/onsi/gomega"
27+
corev1 "k8s.io/api/core/v1"
2728
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2829
"k8s.io/apimachinery/pkg/runtime"
2930
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
@@ -33,6 +34,7 @@ import (
3334

3435
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3536
"sigs.k8s.io/cluster-api/api/v1beta1/index"
37+
"sigs.k8s.io/cluster-api/controllers/remote"
3638
expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
3739
"sigs.k8s.io/cluster-api/internal/controllers/clusterclass"
3840
"sigs.k8s.io/cluster-api/internal/test/envtest"
@@ -49,6 +51,7 @@ func init() {
4951
_ = clusterv1.AddToScheme(fakeScheme)
5052
_ = apiextensionsv1.AddToScheme(fakeScheme)
5153
_ = expv1.AddToScheme(fakeScheme)
54+
_ = corev1.AddToScheme(fakeScheme)
5255
}
5356
func TestMain(m *testing.M) {
5457
setupIndexes := func(ctx context.Context, mgr ctrl.Manager) {
@@ -71,11 +74,40 @@ func TestMain(m *testing.M) {
7174
if err != nil {
7275
panic(fmt.Sprintf("unable to create unstructuredCachineClient: %v", err))
7376
}
77+
// Set up a ClusterCacheTracker and ClusterCacheReconciler to provide to controllers
78+
// requiring a connection to a remote cluster
79+
log := ctrl.Log.WithName("remote").WithName("ClusterCacheTracker")
80+
secretCachingClient, err := client.New(mgr.GetConfig(), client.Options{
81+
HTTPClient: mgr.GetHTTPClient(),
82+
Cache: &client.CacheOptions{
83+
Reader: mgr.GetCache(),
84+
},
85+
})
86+
if err != nil {
87+
panic(fmt.Sprintf("unable to create secretCachingClient: %v", err))
88+
}
89+
tracker, err := remote.NewClusterCacheTracker(
90+
mgr,
91+
remote.ClusterCacheTrackerOptions{
92+
Log: &log,
93+
SecretCachingClient: secretCachingClient,
94+
},
95+
)
96+
if err != nil {
97+
panic(fmt.Sprintf("unable to create cluster cache tracker: %v", err))
98+
}
99+
if err := (&remote.ClusterCacheReconciler{
100+
Client: mgr.GetClient(),
101+
Tracker: tracker,
102+
}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 1}); err != nil {
103+
panic(fmt.Sprintf("Failed to start ClusterCacheReconciler: %v", err))
104+
}
74105
if err := (&Reconciler{
75106
Client: mgr.GetClient(),
76107
APIReader: mgr.GetAPIReader(),
77108
UnstructuredCachingClient: unstructuredCachingClient,
78-
}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 5}); err != nil {
109+
Tracker: tracker,
110+
}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: 1}); err != nil {
79111
panic(fmt.Sprintf("unable to create topology cluster reconciler: %v", err))
80112
}
81113
if err := (&clusterclass.Reconciler{

internal/test/builder/builders.go

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,15 +1440,16 @@ func (c *TestControlPlaneBuilder) Build() *unstructured.Unstructured {
14401440

14411441
// MachinePoolBuilder holds the variables and objects needed to build a generic MachinePool.
14421442
type MachinePoolBuilder struct {
1443-
namespace string
1444-
name string
1445-
bootstrap *unstructured.Unstructured
1446-
infrastructure *unstructured.Unstructured
1447-
version *string
1448-
clusterName string
1449-
replicas *int32
1450-
labels map[string]string
1451-
status *expv1.MachinePoolStatus
1443+
namespace string
1444+
name string
1445+
bootstrap *unstructured.Unstructured
1446+
infrastructure *unstructured.Unstructured
1447+
version *string
1448+
clusterName string
1449+
replicas *int32
1450+
labels map[string]string
1451+
status *expv1.MachinePoolStatus
1452+
minReadySeconds *int32
14521453
}
14531454

14541455
// MachinePool creates a MachinePoolBuilder with the given name and namespace.
@@ -1501,6 +1502,12 @@ func (m *MachinePoolBuilder) WithStatus(status expv1.MachinePoolStatus) *Machine
15011502
return m
15021503
}
15031504

1505+
// WithMinReadySeconds sets the passed value on the machine pool spec.
1506+
func (m *MachinePoolBuilder) WithMinReadySeconds(minReadySeconds int32) *MachinePoolBuilder {
1507+
m.minReadySeconds = &minReadySeconds
1508+
return m
1509+
}
1510+
15041511
// Build creates a new MachinePool with the variables and objects passed to the MachinePoolBuilder.
15051512
func (m *MachinePoolBuilder) Build() *expv1.MachinePool {
15061513
obj := &expv1.MachinePool{
@@ -1514,8 +1521,15 @@ func (m *MachinePoolBuilder) Build() *expv1.MachinePool {
15141521
Labels: m.labels,
15151522
},
15161523
Spec: expv1.MachinePoolSpec{
1517-
ClusterName: m.clusterName,
1518-
Replicas: m.replicas,
1524+
ClusterName: m.clusterName,
1525+
Replicas: m.replicas,
1526+
MinReadySeconds: m.minReadySeconds,
1527+
Template: clusterv1.MachineTemplateSpec{
1528+
Spec: clusterv1.MachineSpec{
1529+
Version: m.version,
1530+
ClusterName: m.clusterName,
1531+
},
1532+
},
15191533
},
15201534
}
15211535
if m.bootstrap != nil {
@@ -1524,9 +1538,6 @@ func (m *MachinePoolBuilder) Build() *expv1.MachinePool {
15241538
if m.infrastructure != nil {
15251539
obj.Spec.Template.Spec.InfrastructureRef = *objToRef(m.infrastructure)
15261540
}
1527-
if m.version != nil {
1528-
obj.Spec.Template.Spec.Version = m.version
1529-
}
15301541
if m.status != nil {
15311542
obj.Status = *m.status
15321543
}
@@ -1546,6 +1557,7 @@ type MachineDeploymentBuilder struct {
15461557
generation *int64
15471558
labels map[string]string
15481559
status *clusterv1.MachineDeploymentStatus
1560+
minReadySeconds *int32
15491561
}
15501562

15511563
// MachineDeployment creates a MachineDeploymentBuilder with the given name and namespace.
@@ -1610,6 +1622,12 @@ func (m *MachineDeploymentBuilder) WithStatus(status clusterv1.MachineDeployment
16101622
return m
16111623
}
16121624

1625+
// WithMinReadySeconds sets the passed value on the machine deployment spec.
1626+
func (m *MachineDeploymentBuilder) WithMinReadySeconds(minReadySeconds int32) *MachineDeploymentBuilder {
1627+
m.minReadySeconds = &minReadySeconds
1628+
return m
1629+
}
1630+
16131631
// Build creates a new MachineDeployment with the variables and objects passed to the MachineDeploymentBuilder.
16141632
func (m *MachineDeploymentBuilder) Build() *clusterv1.MachineDeployment {
16151633
obj := &clusterv1.MachineDeployment{
@@ -1653,6 +1671,7 @@ func (m *MachineDeploymentBuilder) Build() *clusterv1.MachineDeployment {
16531671
clusterv1.ClusterNameLabel: m.clusterName,
16541672
}
16551673
}
1674+
obj.Spec.MinReadySeconds = m.minReadySeconds
16561675

16571676
return obj
16581677
}

internal/test/builder/infrastructure.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ var (
3737

3838
// GenericInfrastructureMachinePoolTemplateKind is the Kind for the GenericInfrastructureMachinePoolTemplate.
3939
GenericInfrastructureMachinePoolTemplateKind = "GenericInfrastructureMachinePoolTemplate"
40+
// GenericInfrastructureMachinePoolTemplateCRD is a generic infrastructure machine pool template CRD.
41+
GenericInfrastructureMachinePoolTemplateCRD = untypedCRD(InfrastructureGroupVersion.WithKind(GenericInfrastructureMachinePoolTemplateKind))
4042

4143
// GenericInfrastructureMachinePoolKind is the Kind for the GenericInfrastructureMachinePool.
4244
GenericInfrastructureMachinePoolKind = "GenericInfrastructureMachinePool"
45+
// GenericInfrastructureMachinePoolCRD is a generic infrastructure machine pool CRD.
46+
GenericInfrastructureMachinePoolCRD = untypedCRD(InfrastructureGroupVersion.WithKind(GenericInfrastructureMachinePoolKind))
4347

4448
// GenericInfrastructureClusterKind is the kind for the GenericInfrastructureCluster type.
4549
GenericInfrastructureClusterKind = "GenericInfrastructureCluster"
@@ -70,9 +74,13 @@ var (
7074

7175
// TestInfrastructureMachinePoolTemplateKind is the kind for the TestInfrastructureMachinePoolTemplate type.
7276
TestInfrastructureMachinePoolTemplateKind = "TestInfrastructureMachinePoolTemplate"
77+
// TestInfrastructureMachinePoolTemplateCRD is a test infrastructure machine pool template CRD.
78+
TestInfrastructureMachinePoolTemplateCRD = testInfrastructureMachinePoolTemplateCRD(InfrastructureGroupVersion.WithKind(TestInfrastructureMachinePoolTemplateKind))
7379

7480
// TestInfrastructureMachinePoolKind is the kind for the TestInfrastructureMachinePool type.
7581
TestInfrastructureMachinePoolKind = "TestInfrastructureMachinePool"
82+
// TestInfrastructureMachinePoolCRD is a test infrastructure machine CRD.
83+
TestInfrastructureMachinePoolCRD = testInfrastructureMachinePoolCRD(InfrastructureGroupVersion.WithKind(TestInfrastructureMachinePoolKind))
7684

7785
// TestInfrastructureMachineKind is the kind for the TestInfrastructureMachine type.
7886
TestInfrastructureMachineKind = "TestInfrastructureMachine"
@@ -147,6 +155,29 @@ func testInfrastructureMachineTemplateCRD(gvk schema.GroupVersionKind) *apiexten
147155
})
148156
}
149157

158+
func testInfrastructureMachinePoolTemplateCRD(gvk schema.GroupVersionKind) *apiextensionsv1.CustomResourceDefinition {
159+
return generateCRD(gvk, map[string]apiextensionsv1.JSONSchemaProps{
160+
"metadata": {
161+
// NOTE: in CRD there is only a partial definition of metadata schema.
162+
// Ref https://github.com/kubernetes-sigs/controller-tools/blob/59485af1c1f6a664655dad49543c474bb4a0d2a2/pkg/crd/gen.go#L185
163+
Type: "object",
164+
},
165+
"spec": {
166+
Type: "object",
167+
Properties: map[string]apiextensionsv1.JSONSchemaProps{
168+
// Mandatory field from the Cluster API contract
169+
"template": {
170+
Type: "object",
171+
Properties: map[string]apiextensionsv1.JSONSchemaProps{
172+
"metadata": metadataSchema,
173+
"spec": machinePoolSpecSchema,
174+
},
175+
},
176+
},
177+
},
178+
})
179+
}
180+
150181
func testInfrastructureMachineCRD(gvk schema.GroupVersionKind) *apiextensionsv1.CustomResourceDefinition {
151182
return generateCRD(gvk, map[string]apiextensionsv1.JSONSchemaProps{
152183
"metadata": {
@@ -168,6 +199,27 @@ func testInfrastructureMachineCRD(gvk schema.GroupVersionKind) *apiextensionsv1.
168199
})
169200
}
170201

202+
func testInfrastructureMachinePoolCRD(gvk schema.GroupVersionKind) *apiextensionsv1.CustomResourceDefinition {
203+
return generateCRD(gvk, map[string]apiextensionsv1.JSONSchemaProps{
204+
"metadata": {
205+
// NOTE: in CRD there is only a partial definition of metadata schema.
206+
// Ref https://github.com/kubernetes-sigs/controller-tools/blob/59485af1c1f6a664655dad49543c474bb4a0d2a2/pkg/crd/gen.go#L185
207+
Type: "object",
208+
},
209+
"spec": machinePoolSpecSchema,
210+
"status": {
211+
Type: "object",
212+
Properties: map[string]apiextensionsv1.JSONSchemaProps{
213+
// mandatory field from the Cluster API contract
214+
"ready": {Type: "boolean"},
215+
// General purpose fields to be used in different test scenario.
216+
"foo": {Type: "string"},
217+
"bar": {Type: "string"},
218+
},
219+
},
220+
})
221+
}
222+
171223
var (
172224
clusterSpecSchema = apiextensionsv1.JSONSchemaProps{
173225
Type: "object",
@@ -215,4 +267,22 @@ var (
215267
"bar": {Type: "string"},
216268
},
217269
}
270+
271+
machinePoolSpecSchema = apiextensionsv1.JSONSchemaProps{
272+
Type: "object",
273+
Properties: map[string]apiextensionsv1.JSONSchemaProps{
274+
// Mandatory field from the Cluster API contract
275+
"providerIDList": {
276+
Type: "array",
277+
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
278+
Schema: &apiextensionsv1.JSONSchemaProps{
279+
Type: "string",
280+
},
281+
},
282+
},
283+
// General purpose fields to be used in different test scenario.
284+
"foo": {Type: "string"},
285+
"bar": {Type: "string"},
286+
},
287+
}
218288
)

internal/test/builder/zz_generated.deepcopy.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/test/envtest/environment.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,17 @@ func newEnvironment(uncachedObjs ...client.Object) *Environment {
212212
builder.GenericControlPlaneTemplateCRD.DeepCopy(),
213213
builder.GenericInfrastructureMachineCRD.DeepCopy(),
214214
builder.GenericInfrastructureMachineTemplateCRD.DeepCopy(),
215+
builder.GenericInfrastructureMachinePoolCRD.DeepCopy(),
216+
builder.GenericInfrastructureMachinePoolTemplateCRD.DeepCopy(),
215217
builder.GenericInfrastructureClusterCRD.DeepCopy(),
216218
builder.GenericInfrastructureClusterTemplateCRD.DeepCopy(),
217219
builder.GenericRemediationCRD.DeepCopy(),
218220
builder.GenericRemediationTemplateCRD.DeepCopy(),
219221
builder.TestInfrastructureClusterTemplateCRD.DeepCopy(),
220222
builder.TestInfrastructureClusterCRD.DeepCopy(),
221223
builder.TestInfrastructureMachineTemplateCRD.DeepCopy(),
224+
builder.TestInfrastructureMachinePoolCRD.DeepCopy(),
225+
builder.TestInfrastructureMachinePoolTemplateCRD.DeepCopy(),
222226
builder.TestInfrastructureMachineCRD.DeepCopy(),
223227
builder.TestBootstrapConfigTemplateCRD.DeepCopy(),
224228
builder.TestBootstrapConfigCRD.DeepCopy(),

0 commit comments

Comments
 (0)