@@ -2,17 +2,25 @@ package controller
22
33import (
44 "context"
5+ "reflect"
6+ "testing"
7+ "time"
58
69 . "github.com/onsi/ginkgo/v2"
710 . "github.com/onsi/gomega"
11+ infrav1 "github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1"
12+ "github.com/scaleway/cluster-api-provider-scaleway/internal/scope"
13+ "github.com/scaleway/scaleway-sdk-go/scw"
14+ corev1 "k8s.io/api/core/v1"
815 "k8s.io/apimachinery/pkg/api/errors"
16+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17+ "k8s.io/apimachinery/pkg/runtime"
918 "k8s.io/apimachinery/pkg/types"
19+ clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
20+ ctrl "sigs.k8s.io/controller-runtime"
21+ "sigs.k8s.io/controller-runtime/pkg/client"
22+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
1023 "sigs.k8s.io/controller-runtime/pkg/reconcile"
11-
12- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13-
14- infrav1 "github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1"
15- "github.com/scaleway/scaleway-sdk-go/scw"
1624)
1725
1826var _ = Describe ("ScalewayMachine Controller" , func () {
@@ -23,7 +31,7 @@ var _ = Describe("ScalewayMachine Controller", func() {
2331
2432 typeNamespacedName := types.NamespacedName {
2533 Name : resourceName ,
26- Namespace : "default" , // TODO(user):Modify as needed
34+ Namespace : "default" ,
2735 }
2836 scalewaymachine := & infrav1.ScalewayMachine {}
2937
@@ -47,7 +55,6 @@ var _ = Describe("ScalewayMachine Controller", func() {
4755 })
4856
4957 AfterEach (func () {
50- // TODO(user): Cleanup logic after each test, like removing the resource instance.
5158 resource := & infrav1.ScalewayMachine {}
5259 err := k8sClient .Get (ctx , typeNamespacedName , resource )
5360 Expect (err ).NotTo (HaveOccurred ())
@@ -66,8 +73,270 @@ var _ = Describe("ScalewayMachine Controller", func() {
6673 NamespacedName : typeNamespacedName ,
6774 })
6875 Expect (err ).NotTo (HaveOccurred ())
69- // TODO(user): Add more specific assertions depending on your controller's reconciliation logic.
70- // Example: If you expect a certain status condition after reconciliation, verify it here.
7176 })
7277 })
7378})
79+
80+ var (
81+ scalewayMachineNamespacedName = types.NamespacedName {
82+ Namespace : "caps" ,
83+ Name : "scalewaymachine" ,
84+ }
85+ machineNamespacedName = types.NamespacedName {
86+ Namespace : "caps" ,
87+ Name : "machine" ,
88+ }
89+ )
90+
91+ func TestScalewayMachineReconciler_Reconcile (t * testing.T ) {
92+ t .Parallel ()
93+ type fields struct {
94+ createScalewayMachineService scalewayMachineServiceCreator
95+ }
96+ type args struct {
97+ ctx context.Context
98+ req ctrl.Request
99+ }
100+ tests := []struct {
101+ name string
102+ fields fields
103+ args args
104+ want ctrl.Result
105+ wantErr bool
106+ objects []client.Object
107+ asserts func (g * WithT , c client.Client )
108+ }{
109+ {
110+ name : "should reconcile normally" ,
111+ fields : fields {
112+ createScalewayMachineService : func (machineScope * scope.Machine ) * scalewayMachineService {
113+ return & scalewayMachineService {
114+ scope : machineScope ,
115+ Reconcile : func (ctx context.Context ) error { return nil },
116+ Delete : func (ctx context.Context ) error { return nil },
117+ }
118+ },
119+ },
120+ args : args {
121+ ctx : context .TODO (),
122+ req : reconcile.Request {
123+ NamespacedName : scalewayMachineNamespacedName ,
124+ },
125+ },
126+ objects : []client.Object {
127+ & infrav1.ScalewayCluster {
128+ ObjectMeta : metav1.ObjectMeta {
129+ Name : scalewayClusterNamespacedName .Name ,
130+ Namespace : scalewayClusterNamespacedName .Namespace ,
131+ OwnerReferences : []metav1.OwnerReference {
132+ {
133+ Name : clusterNamespacedName .Name ,
134+ Kind : "Cluster" ,
135+ APIVersion : clusterv1 .GroupVersion .String (),
136+ },
137+ },
138+ },
139+ Spec : infrav1.ScalewayClusterSpec {
140+ Region : "fr-par" ,
141+ ScalewaySecretName : secretNamespacedName .Name ,
142+ ProjectID : "11111111-1111-1111-1111-111111111111" ,
143+ },
144+ },
145+ & clusterv1.Cluster {
146+ ObjectMeta : metav1.ObjectMeta {
147+ Name : clusterNamespacedName .Name ,
148+ Namespace : clusterNamespacedName .Namespace ,
149+ },
150+ Spec : clusterv1.ClusterSpec {
151+ InfrastructureRef : & corev1.ObjectReference {
152+ Name : scalewayClusterNamespacedName .Name ,
153+ },
154+ },
155+ Status : clusterv1.ClusterStatus {
156+ InfrastructureReady : true ,
157+ },
158+ },
159+ & corev1.Secret {
160+ ObjectMeta : metav1.ObjectMeta {
161+ Name : secretNamespacedName .Name ,
162+ Namespace : secretNamespacedName .Namespace ,
163+ },
164+ Data : map [string ][]byte {
165+ scw .ScwAccessKeyEnv : []byte ("SCWXXXXXXXXXXXXXXXXX" ),
166+ scw .ScwSecretKeyEnv : []byte ("11111111-1111-1111-1111-111111111111" ),
167+ },
168+ },
169+ & infrav1.ScalewayMachine {
170+ ObjectMeta : metav1.ObjectMeta {
171+ Name : scalewayMachineNamespacedName .Name ,
172+ Namespace : scalewayMachineNamespacedName .Namespace ,
173+ OwnerReferences : []metav1.OwnerReference {
174+ {
175+ Name : machineNamespacedName .Name ,
176+ Kind : "Machine" ,
177+ APIVersion : clusterv1 .GroupVersion .String (),
178+ },
179+ },
180+ },
181+ },
182+ & clusterv1.Machine {
183+ ObjectMeta : metav1.ObjectMeta {
184+ Name : machineNamespacedName .Name ,
185+ Namespace : machineNamespacedName .Namespace ,
186+ Labels : map [string ]string {
187+ clusterv1 .ClusterNameLabel : clusterNamespacedName .Name ,
188+ },
189+ },
190+ Spec : clusterv1.MachineSpec {
191+ Bootstrap : clusterv1.Bootstrap {
192+ DataSecretName : scw .StringPtr ("bootstrap" ),
193+ },
194+ },
195+ },
196+ },
197+ asserts : func (g * WithT , c client.Client ) {
198+ // ScalewayMachine checks
199+ sc := & infrav1.ScalewayMachine {}
200+ g .Expect (c .Get (context .TODO (), scalewayMachineNamespacedName , sc )).To (Succeed ())
201+ g .Expect (sc .Status .Ready ).To (BeTrue ())
202+ g .Expect (sc .Finalizers ).To (ContainElement (infrav1 .MachineFinalizer ))
203+ },
204+ },
205+ {
206+ name : "should reconcile deletion" ,
207+ fields : fields {
208+ createScalewayMachineService : func (machineScope * scope.Machine ) * scalewayMachineService {
209+ return & scalewayMachineService {
210+ scope : machineScope ,
211+ Reconcile : func (ctx context.Context ) error { return nil },
212+ Delete : func (ctx context.Context ) error { return nil },
213+ }
214+ },
215+ },
216+ args : args {
217+ ctx : context .TODO (),
218+ req : reconcile.Request {
219+ NamespacedName : scalewayMachineNamespacedName ,
220+ },
221+ },
222+ objects : []client.Object {
223+ & infrav1.ScalewayCluster {
224+ ObjectMeta : metav1.ObjectMeta {
225+ Name : scalewayClusterNamespacedName .Name ,
226+ Namespace : scalewayClusterNamespacedName .Namespace ,
227+ OwnerReferences : []metav1.OwnerReference {
228+ {
229+ Name : clusterNamespacedName .Name ,
230+ Kind : "Cluster" ,
231+ APIVersion : clusterv1 .GroupVersion .String (),
232+ },
233+ },
234+ },
235+ Spec : infrav1.ScalewayClusterSpec {
236+ Region : "fr-par" ,
237+ ScalewaySecretName : secretNamespacedName .Name ,
238+ ProjectID : "11111111-1111-1111-1111-111111111111" ,
239+ },
240+ },
241+ & clusterv1.Cluster {
242+ ObjectMeta : metav1.ObjectMeta {
243+ Name : clusterNamespacedName .Name ,
244+ Namespace : clusterNamespacedName .Namespace ,
245+ },
246+ Spec : clusterv1.ClusterSpec {
247+ InfrastructureRef : & corev1.ObjectReference {
248+ Name : scalewayClusterNamespacedName .Name ,
249+ },
250+ },
251+ Status : clusterv1.ClusterStatus {
252+ InfrastructureReady : true ,
253+ },
254+ },
255+ & corev1.Secret {
256+ ObjectMeta : metav1.ObjectMeta {
257+ Name : secretNamespacedName .Name ,
258+ Namespace : secretNamespacedName .Namespace ,
259+ },
260+ Data : map [string ][]byte {
261+ scw .ScwAccessKeyEnv : []byte ("SCWXXXXXXXXXXXXXXXXX" ),
262+ scw .ScwSecretKeyEnv : []byte ("11111111-1111-1111-1111-111111111111" ),
263+ },
264+ },
265+ & infrav1.ScalewayMachine {
266+ ObjectMeta : metav1.ObjectMeta {
267+ Name : scalewayMachineNamespacedName .Name ,
268+ Namespace : scalewayMachineNamespacedName .Namespace ,
269+ OwnerReferences : []metav1.OwnerReference {
270+ {
271+ Name : machineNamespacedName .Name ,
272+ Kind : "Machine" ,
273+ APIVersion : clusterv1 .GroupVersion .String (),
274+ },
275+ },
276+ Finalizers : []string {infrav1 .MachineFinalizer },
277+ DeletionTimestamp : & metav1.Time {Time : time .Now ()},
278+ },
279+ },
280+ & clusterv1.Machine {
281+ ObjectMeta : metav1.ObjectMeta {
282+ Name : machineNamespacedName .Name ,
283+ Namespace : machineNamespacedName .Namespace ,
284+ Labels : map [string ]string {
285+ clusterv1 .ClusterNameLabel : clusterNamespacedName .Name ,
286+ },
287+ },
288+ Spec : clusterv1.MachineSpec {
289+ Bootstrap : clusterv1.Bootstrap {
290+ DataSecretName : scw .StringPtr ("bootstrap" ),
291+ },
292+ },
293+ },
294+ },
295+ asserts : func (g * WithT , c client.Client ) {
296+ // ScalewayMachine should not exist anymore if the finalizer was correctly removed.
297+ sc := & infrav1.ScalewayMachine {}
298+ g .Expect (c .Get (context .TODO (), scalewayMachineNamespacedName , sc )).NotTo (Succeed ())
299+ },
300+ },
301+ }
302+ for _ , tt := range tests {
303+ t .Run (tt .name , func (t * testing.T ) {
304+ t .Parallel ()
305+ g := NewWithT (t )
306+ sb := runtime .NewSchemeBuilder (
307+ corev1 .AddToScheme ,
308+ clusterv1 .AddToScheme ,
309+ infrav1 .AddToScheme ,
310+ )
311+ s := runtime .NewScheme ()
312+
313+ g .Expect (sb .AddToScheme (s )).To (Succeed ())
314+
315+ runtimeObjects := make ([]runtime.Object , 0 , len (tt .objects ))
316+ for _ , obj := range tt .objects {
317+ runtimeObjects = append (runtimeObjects , obj )
318+ }
319+
320+ c := fake .NewClientBuilder ().
321+ WithScheme (s ).
322+ WithRuntimeObjects (runtimeObjects ... ).
323+ WithStatusSubresource (tt .objects ... ).
324+ Build ()
325+
326+ r := & ScalewayMachineReconciler {
327+ Client : c ,
328+ createScalewayMachineService : tt .fields .createScalewayMachineService ,
329+ }
330+ got , err := r .Reconcile (tt .args .ctx , tt .args .req )
331+ if (err != nil ) != tt .wantErr {
332+ t .Errorf ("ScalewayMachineReconciler.Reconcile() error = %v, wantErr %v" , err , tt .wantErr )
333+ return
334+ }
335+ if ! reflect .DeepEqual (got , tt .want ) {
336+ t .Errorf ("ScalewayMachineReconciler.Reconcile() = %v, want %v" , got , tt .want )
337+ }
338+
339+ tt .asserts (g , c )
340+ })
341+ }
342+ }
0 commit comments