@@ -21,10 +21,12 @@ import (
2121 . "github.com/onsi/ginkgo/v2"
2222 . "github.com/onsi/gomega"
2323 "k8s.io/apimachinery/pkg/api/errors"
24+ "k8s.io/utils/pointer"
2425 infrav1 "sigs.k8s.io/cluster-api-provider-cloudstack/api/v1beta2"
2526 "sigs.k8s.io/cluster-api-provider-cloudstack/pkg/cloud"
2627 dummies "sigs.k8s.io/cluster-api-provider-cloudstack/test/dummies/v1beta2"
2728 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
29+ "sigs.k8s.io/cluster-api/util/patch"
2830 "sigs.k8s.io/controller-runtime/pkg/client"
2931)
3032
@@ -47,84 +49,93 @@ var _ = Describe("CloudStackFailureDomainReconciler", func() {
4749 arg1 .(* infrav1.CloudStackZoneSpec ).Network .ID = "SomeID"
4850 arg1 .(* infrav1.CloudStackZoneSpec ).Network .Type = cloud .NetworkTypeShared
4951 }).MinTimes (1 )
50-
5152 })
5253
53- It ("Should set failure domain Status.Ready to true." , func () {
54- assertFailureDomainCreated ()
55- })
5654 It ("Should delete failure domain if no VM under this failure domain." , func () {
57- assertFailureDomainCreated ()
55+ Eventually (func () bool {
56+ return getFailuredomainStatus (dummies .CSFailureDomain1 )
57+ }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
58+
5859 Ω (k8sClient .Delete (ctx , dummies .CSFailureDomain1 ))
5960
60- assertFailureDomainNotExisted ()
61+ tempfd := & infrav1.CloudStackFailureDomain {}
62+ Eventually (func () bool {
63+ key := client .ObjectKeyFromObject (dummies .CSFailureDomain1 )
64+ if err := k8sClient .Get (ctx , key , tempfd ); err != nil {
65+ return errors .IsNotFound (err )
66+ }
67+ return false
68+ }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
6169 })
70+
6271 DescribeTable ("Should function in different replicas conditions" ,
63- func (shouldDeleteVM bool , specReplicas , statusReplicas , statusReadyReplicas * int32 , statusReady * bool ) {
64- assertFailureDomainCreated ()
72+ func (shouldDeleteVM bool , specReplicas , statusReplicas , statusReadyReplicas * int32 , statusReady * bool , controlPlaneReady bool ) {
73+ Eventually (func () bool {
74+ return getFailuredomainStatus (dummies .CSFailureDomain1 )
75+ }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
76+
6577 setCSMachineOwnerCRD (dummies .CSMachineOwner , specReplicas , statusReplicas , statusReadyReplicas , statusReady )
6678 setCAPIMachineAndCSMachineCRDs (dummies .CSMachine1 , dummies .CAPIMachine )
6779 setMachineOwnerReference (dummies .CSMachine1 , dummies .CSMachineOwnerReference )
6880 labelMachineFailuredomain (dummies .CSMachine1 , dummies .CSFailureDomain1 )
6981
82+ if ! controlPlaneReady {
83+ Eventually (func () error {
84+ ph , err := patch .NewHelper (dummies .CAPICluster , k8sClient )
85+ Ω (err ).ShouldNot (HaveOccurred ())
86+ dummies .CAPICluster .Status .Conditions = []clusterv1.Condition {
87+ {
88+ Type : "Ready" ,
89+ Status : "False" ,
90+ },
91+ }
92+ return ph .Patch (ctx , dummies .CAPICluster , patch.WithStatusObservedGeneration {})
93+ }, timeout ).Should (Succeed ())
94+ }
95+
7096 Ω (k8sClient .Delete (ctx , dummies .CSFailureDomain1 ))
7197
7298 CAPIMachine := & clusterv1.Machine {}
73- Eventually ( func () bool {
74- key := client. ObjectKey { Namespace : dummies . ClusterNameSpace , Name : dummies . CAPIMachine . Name }
75- if shouldDeleteVM {
99+ if shouldDeleteVM {
100+ Eventually ( func () bool {
101+ key := client. ObjectKey { Namespace : dummies . ClusterNameSpace , Name : dummies . CAPIMachine . Name }
76102 if err := k8sClient .Get (ctx , key , CAPIMachine ); err != nil {
77103 return errors .IsNotFound (err )
78104 }
79- } else {
105+ return false
106+ }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
107+ } else {
108+ Consistently (func () bool {
109+ key := client.ObjectKey {Namespace : dummies .ClusterNameSpace , Name : dummies .CAPIMachine .Name }
80110 if err := k8sClient .Get (ctx , key , CAPIMachine ); err == nil {
81111 return CAPIMachine .DeletionTimestamp .IsZero ()
82112 }
83- }
84- return false
85- }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
113+ return false
114+ }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
115+ }
116+
86117 },
87118 // should delete - simulate owner is kubeadmcontrolplane
88- Entry ("Should delete machine if spec.replicas > 1" , true , int32Pointer (2 ), int32Pointer (2 ), int32Pointer (2 ), boolPointer (true )),
119+ Entry ("Should delete machine if spec.replicas > 1" , true , pointer . Int32 (2 ), pointer . Int32 (2 ), pointer . Int32 (2 ), pointer . Bool (true ), true ),
89120 // should delete - simulate owner is etcdadmcluster
90- Entry ("Should delete machine if status.readyReplica does not exist" , true , int32Pointer (2 ), int32Pointer (2 ), nil , boolPointer (true )),
121+ Entry ("Should delete machine if status.readyReplica does not exist" , true , pointer . Int32 (2 ), pointer . Int32 (2 ), nil , pointer . Bool (true ), true ),
91122 // should delete - simulate owner is machineset
92- Entry ("Should delete machine if status.ready does not exist" , true , int32Pointer (2 ), int32Pointer (2 ), int32Pointer (2 ), nil ),
123+ Entry ("Should delete machine if status.ready does not exist" , true , pointer . Int32 (2 ), pointer . Int32 (2 ), pointer . Int32 (2 ), nil , true ),
93124 // should not delete if condition not met
94- Entry ("Should return error if status.replicas < spec.replicas" , false , int32Pointer (2 ), int32Pointer (1 ), int32Pointer (1 ), boolPointer (true )),
95- Entry ("Should return error if spec.replicas < 2" , false , int32Pointer (1 ), int32Pointer (1 ), int32Pointer (1 ), boolPointer (true )),
96- Entry ("Should return error if status.ready is false" , false , int32Pointer (2 ), int32Pointer (2 ), int32Pointer (2 ), boolPointer (false )),
97- Entry ("Should return error if status.readyReplicas <> status.replicas" , false , int32Pointer (2 ), int32Pointer (2 ), int32Pointer (1 ), boolPointer (true )),
125+ Entry ("Should not delete machine if cluster control plane not ready" , false , pointer .Int32 (2 ), pointer .Int32 (2 ), pointer .Int32 (2 ), pointer .Bool (true ), false ),
126+ Entry ("Should not delete machine if status.replicas < spec.replicas" , false , pointer .Int32 (2 ), pointer .Int32 (1 ), pointer .Int32 (1 ), pointer .Bool (true ), true ),
127+ Entry ("Should not delete machine if spec.replicas < 2" , false , pointer .Int32 (1 ), pointer .Int32 (1 ), pointer .Int32 (1 ), pointer .Bool (true ), true ),
128+ Entry ("Should not delete machine if status.ready is false" , false , pointer .Int32 (2 ), pointer .Int32 (2 ), pointer .Int32 (2 ), pointer .Bool (false ), true ),
129+ Entry ("Should not delete machine if status.readyReplicas <> status.replicas" , false , pointer .Int32 (2 ), pointer .Int32 (2 ), pointer .Int32 (1 ), pointer .Bool (true ), true ),
98130 )
99131 })
100132})
101133
102- func assertFailureDomainCreated () {
103- tempfd := & infrav1.CloudStackFailureDomain {}
104- Eventually (func () bool {
105- key := client .ObjectKeyFromObject (dummies .CSFailureDomain1 )
106- if err := k8sClient .Get (ctx , key , tempfd ); err == nil {
107- return tempfd .Status .Ready
108- }
109- return false
110- }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
111- }
112-
113- func assertFailureDomainNotExisted () {
134+ func getFailuredomainStatus (failureDomain * infrav1.CloudStackFailureDomain ) bool {
114135 tempfd := & infrav1.CloudStackFailureDomain {}
115- Eventually (func () bool {
116- key := client .ObjectKeyFromObject (dummies .CSFailureDomain1 )
117- if err := k8sClient .Get (ctx , key , tempfd ); err != nil {
118- return true
119- }
120- return false
121- }, timeout ).WithPolling (pollInterval ).Should (BeTrue ())
122- }
123-
124- func boolPointer (b bool ) * bool {
125- return & b
126- }
127-
128- func int32Pointer (b int32 ) * int32 {
129- return & b
136+ key := client .ObjectKeyFromObject (failureDomain )
137+ if err := k8sClient .Get (ctx , key , tempfd ); err == nil {
138+ return tempfd .Status .Ready
139+ }
140+ return false
130141}
0 commit comments