@@ -17,6 +17,7 @@ limitations under the License.
1717package controllers
1818
1919import (
20+ "context"
2021 "fmt"
2122 "reflect"
2223 "testing"
@@ -33,9 +34,13 @@ import (
3334 "go.uber.org/mock/gomock"
3435 corev1 "k8s.io/api/core/v1"
3536 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+ "k8s.io/apimachinery/pkg/runtime"
3638 "k8s.io/utils/ptr"
3739 clusterv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
40+ clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
3841 "sigs.k8s.io/cluster-api/util/conditions"
42+ "sigs.k8s.io/controller-runtime/pkg/client"
43+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
3944
4045 infrav1alpha1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha1"
4146 infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
@@ -194,6 +199,191 @@ var deleteRootVolume = func(r *recorders) {
194199 r .volume .DeleteVolume (rootVolumeUUID , volumes.DeleteOpts {}).Return (nil )
195200}
196201
202+ func TestOpenStackServerReconciler_requeueOpenStackServersForCluster (t * testing.T ) {
203+ tests := []struct {
204+ name string
205+ cluster * clusterv1.Cluster
206+ servers []* infrav1alpha1.OpenStackServer
207+ clusterDeleting bool
208+ wantRequests int
209+ wantServerNames []string
210+ }{
211+ {
212+ name : "returns reconcile requests for all servers in cluster" ,
213+ cluster : & clusterv1.Cluster {
214+ ObjectMeta : metav1.ObjectMeta {
215+ Name : "test-cluster" ,
216+ Namespace : "test-ns" ,
217+ },
218+ },
219+ servers : []* infrav1alpha1.OpenStackServer {
220+ {
221+ ObjectMeta : metav1.ObjectMeta {
222+ Name : "server-1" ,
223+ Namespace : "test-ns" ,
224+ Labels : map [string ]string {
225+ clusterv1beta1 .ClusterNameLabel : "test-cluster" ,
226+ },
227+ },
228+ Spec : infrav1alpha1.OpenStackServerSpec {
229+ Flavor : ptr .To ("m1.small" ),
230+ Image : infrav1.ImageParam {
231+ Filter : & infrav1.ImageFilter {Name : ptr .To ("test-image" )},
232+ },
233+ },
234+ },
235+ {
236+ ObjectMeta : metav1.ObjectMeta {
237+ Name : "server-2" ,
238+ Namespace : "test-ns" ,
239+ Labels : map [string ]string {
240+ clusterv1beta1 .ClusterNameLabel : "test-cluster" ,
241+ },
242+ },
243+ Spec : infrav1alpha1.OpenStackServerSpec {
244+ Flavor : ptr .To ("m1.small" ),
245+ Image : infrav1.ImageParam {
246+ Filter : & infrav1.ImageFilter {Name : ptr .To ("test-image" )},
247+ },
248+ },
249+ },
250+ },
251+ wantRequests : 2 ,
252+ wantServerNames : []string {"server-1" , "server-2" },
253+ },
254+ {
255+ name : "returns empty for deleted cluster" ,
256+ cluster : & clusterv1.Cluster {
257+ ObjectMeta : metav1.ObjectMeta {
258+ Name : "test-cluster" ,
259+ Namespace : "test-ns" ,
260+ },
261+ },
262+ servers : []* infrav1alpha1.OpenStackServer {
263+ {
264+ ObjectMeta : metav1.ObjectMeta {
265+ Name : "server-1" ,
266+ Namespace : "test-ns" ,
267+ Labels : map [string ]string {
268+ clusterv1beta1 .ClusterNameLabel : "test-cluster" ,
269+ },
270+ },
271+ Spec : infrav1alpha1.OpenStackServerSpec {
272+ Flavor : ptr .To ("m1.small" ),
273+ Image : infrav1.ImageParam {
274+ Filter : & infrav1.ImageFilter {Name : ptr .To ("test-image" )},
275+ },
276+ },
277+ },
278+ },
279+ clusterDeleting : true ,
280+ wantRequests : 0 ,
281+ },
282+ {
283+ name : "returns empty when no servers exist" ,
284+ cluster : & clusterv1.Cluster {
285+ ObjectMeta : metav1.ObjectMeta {
286+ Name : "test-cluster" ,
287+ Namespace : "test-ns" ,
288+ },
289+ },
290+ servers : []* infrav1alpha1.OpenStackServer {},
291+ wantRequests : 0 ,
292+ },
293+ {
294+ name : "only returns servers from same cluster" ,
295+ cluster : & clusterv1.Cluster {
296+ ObjectMeta : metav1.ObjectMeta {
297+ Name : "test-cluster" ,
298+ Namespace : "test-ns" ,
299+ },
300+ },
301+ servers : []* infrav1alpha1.OpenStackServer {
302+ {
303+ ObjectMeta : metav1.ObjectMeta {
304+ Name : "server-1" ,
305+ Namespace : "test-ns" ,
306+ Labels : map [string ]string {
307+ clusterv1beta1 .ClusterNameLabel : "test-cluster" ,
308+ },
309+ },
310+ Spec : infrav1alpha1.OpenStackServerSpec {
311+ Flavor : ptr .To ("m1.small" ),
312+ Image : infrav1.ImageParam {
313+ Filter : & infrav1.ImageFilter {Name : ptr .To ("test-image" )},
314+ },
315+ },
316+ },
317+ {
318+ ObjectMeta : metav1.ObjectMeta {
319+ Name : "server-2" ,
320+ Namespace : "test-ns" ,
321+ Labels : map [string ]string {
322+ clusterv1beta1 .ClusterNameLabel : "other-cluster" ,
323+ },
324+ },
325+ Spec : infrav1alpha1.OpenStackServerSpec {
326+ Flavor : ptr .To ("m1.small" ),
327+ Image : infrav1.ImageParam {
328+ Filter : & infrav1.ImageFilter {Name : ptr .To ("test-image" )},
329+ },
330+ },
331+ },
332+ },
333+ wantRequests : 1 ,
334+ wantServerNames : []string {"server-1" },
335+ },
336+ }
337+
338+ for i := range tests {
339+ tt := & tests [i ]
340+ t .Run (tt .name , func (t * testing.T ) {
341+ g := NewGomegaWithT (t )
342+ ctx := context .TODO ()
343+
344+ // Set deletion timestamp and finalizers if needed
345+ if tt .clusterDeleting {
346+ now := metav1 .Now ()
347+ tt .cluster .DeletionTimestamp = & now
348+ tt .cluster .Finalizers = []string {"test-finalizer" }
349+ }
350+
351+ // Create a fake client with the test data
352+ scheme := runtime .NewScheme ()
353+ g .Expect (clusterv1 .AddToScheme (scheme )).To (Succeed ())
354+ g .Expect (infrav1alpha1 .AddToScheme (scheme )).To (Succeed ())
355+
356+ objs := []client.Object {tt .cluster }
357+ for _ , server := range tt .servers {
358+ objs = append (objs , server )
359+ }
360+
361+ fakeClient := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (objs ... ).Build ()
362+
363+ // Create reconciler and call mapper function
364+ reconciler := & OpenStackServerReconciler {
365+ Client : fakeClient ,
366+ }
367+ mapFunc := reconciler .requeueOpenStackServersForCluster (ctx )
368+ requests := mapFunc (ctx , tt .cluster )
369+
370+ // Verify results
371+ if tt .wantRequests == 0 {
372+ g .Expect (requests ).To (Or (BeNil (), BeEmpty ()))
373+ } else {
374+ g .Expect (requests ).To (HaveLen (tt .wantRequests ))
375+ if len (tt .wantServerNames ) > 0 {
376+ gotNames := make ([]string , len (requests ))
377+ for i , req := range requests {
378+ gotNames [i ] = req .Name
379+ }
380+ g .Expect (gotNames ).To (ConsistOf (tt .wantServerNames ))
381+ }
382+ }
383+ })
384+ }
385+ }
386+
197387func TestOpenStackServer_serverToInstanceSpec (t * testing.T ) {
198388 tests := []struct {
199389 name string
0 commit comments