@@ -40,8 +40,10 @@ import (
4040 "k8s.io/client-go/tools/record"
4141 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
4242 "sigs.k8s.io/cluster-api/util/conditions"
43+ ctrl "sigs.k8s.io/controller-runtime"
4344 "sigs.k8s.io/controller-runtime/pkg/client"
4445 "sigs.k8s.io/controller-runtime/pkg/client/fake"
46+ "sigs.k8s.io/controller-runtime/pkg/client/interceptor"
4547 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
4648 "sigs.k8s.io/controller-runtime/pkg/log"
4749 "sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -196,19 +198,22 @@ func TestNormalReconciliationFunction(t *testing.T) {
196198 teardown := func (t * testing.T , g * WithT ) {
197199 mockCtrl .Finish ()
198200 }
199- tests := [] struct {
201+ type test struct {
200202 name string
201203 errorExpected bool
202204 expectedEvent string
203205 eventNotExpected string
204206 conditionAssertion []conditionAssertion
205- testSpecificSetup func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient )
206- }{
207+ deleteMachines []clusterv1.Machine
208+ testSpecificSetup func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient )
209+ validate func (g * WithT , t * test , result ctrl.Result )
210+ }
211+ tests := []test {
207212 {
208213 name : "instance in provisioning state" ,
209214 errorExpected : false ,
210215 conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionFalse , clusterv1 .ConditionSeverityInfo , infrastructurev1beta2 .InstanceNotReadyReason }},
211- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
216+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
212217 computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
213218 InstanceId : common .String ("test" ),
214219 })).
@@ -224,7 +229,59 @@ func TestNormalReconciliationFunction(t *testing.T) {
224229 name : "instance in running state" ,
225230 errorExpected : false ,
226231 conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionTrue , "" , "" }},
227- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
232+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
233+ machineScope .OCIMachine .Status .Addresses = []clusterv1.MachineAddress {
234+ {
235+ Type : clusterv1 .MachineInternalIP ,
236+ Address : "1.1.1.1" ,
237+ },
238+ }
239+ computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
240+ InstanceId : common .String ("test" ),
241+ })).
242+ Return (core.GetInstanceResponse {
243+ Instance : core.Instance {
244+ Id : common .String ("test" ),
245+ LifecycleState : core .InstanceLifecycleStateRunning ,
246+ },
247+ }, nil )
248+ },
249+ },
250+ {
251+ name : "instance in running state, reconcile every 5 minutes" ,
252+ errorExpected : false ,
253+ conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionTrue , "" , "" }},
254+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
255+ if machineScope .Machine .ObjectMeta .Annotations == nil {
256+ machineScope .Machine .ObjectMeta .Annotations = make (map [string ]string )
257+ }
258+ machineScope .Machine .ObjectMeta .Annotations [infrastructurev1beta2 .DeleteMachineOnInstanceTermination ] = ""
259+ machineScope .OCIMachine .Status .Addresses = []clusterv1.MachineAddress {
260+ {
261+ Type : clusterv1 .MachineInternalIP ,
262+ Address : "1.1.1.1" ,
263+ },
264+ }
265+ computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
266+ InstanceId : common .String ("test" ),
267+ })).
268+ Return (core.GetInstanceResponse {
269+ Instance : core.Instance {
270+ Id : common .String ("test" ),
271+ LifecycleState : core .InstanceLifecycleStateRunning ,
272+ },
273+ }, nil )
274+ },
275+ },
276+ {
277+ name : "instance in running state, reconcile every 5 minutes" ,
278+ errorExpected : false ,
279+ conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionTrue , "" , "" }},
280+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
281+ if machineScope .Machine .ObjectMeta .Annotations == nil {
282+ machineScope .Machine .ObjectMeta .Annotations = make (map [string ]string )
283+ }
284+ machineScope .Machine .ObjectMeta .Annotations [infrastructurev1beta2 .DeleteMachineOnInstanceTermination ] = ""
228285 machineScope .OCIMachine .Status .Addresses = []clusterv1.MachineAddress {
229286 {
230287 Type : clusterv1 .MachineInternalIP ,
@@ -241,13 +298,49 @@ func TestNormalReconciliationFunction(t *testing.T) {
241298 },
242299 }, nil )
243300 },
301+ validate : func (g * WithT , t * test , result ctrl.Result ) {
302+ g .Expect (result .RequeueAfter ).To (Equal (300 * time .Second ))
303+ },
244304 },
245305 {
246306 name : "instance in terminated state" ,
247307 errorExpected : true ,
248308 expectedEvent : "invalid lifecycle state TERMINATED" ,
249309 conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionFalse , clusterv1 .ConditionSeverityError , infrastructurev1beta2 .InstanceProvisionFailedReason }},
250- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
310+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
311+ computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
312+ InstanceId : common .String ("test" ),
313+ })).
314+ Return (core.GetInstanceResponse {
315+ Instance : core.Instance {
316+ Id : common .String ("test" ),
317+ LifecycleState : core .InstanceLifecycleStateTerminated ,
318+ },
319+ }, nil )
320+ },
321+ validate : func (g * WithT , t * test , result ctrl.Result ) {
322+ g .Expect (result .RequeueAfter ).To (Equal (0 * time .Second ))
323+ },
324+ },
325+ {
326+ name : "instance in terminated state, machine has to be deleted" ,
327+ errorExpected : true ,
328+ expectedEvent : "invalid lifecycle state TERMINATED" ,
329+ conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionFalse , clusterv1 .ConditionSeverityError , infrastructurev1beta2 .InstanceProvisionFailedReason }},
330+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
331+ fakeClient := fake .NewClientBuilder ().WithObjects (getSecret ()).Build ()
332+ if machineScope .Machine .ObjectMeta .Annotations == nil {
333+ machineScope .Machine .ObjectMeta .Annotations = make (map [string ]string )
334+ }
335+ machineScope .Machine .ObjectMeta .Annotations [infrastructurev1beta2 .DeleteMachineOnInstanceTermination ] = ""
336+ t .deleteMachines = make ([]clusterv1.Machine , 0 )
337+ machineScope .Client = interceptor .NewClient (fakeClient , interceptor.Funcs {
338+ Delete : func (ctx context.Context , client client.WithWatch , obj client.Object , opts ... client.DeleteOption ) error {
339+ m := obj .(* clusterv1.Machine )
340+ t .deleteMachines = append (t .deleteMachines , * m )
341+ return nil
342+ },
343+ })
251344 computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
252345 InstanceId : common .String ("test" ),
253346 })).
@@ -258,13 +351,16 @@ func TestNormalReconciliationFunction(t *testing.T) {
258351 },
259352 }, nil )
260353 },
354+ validate : func (g * WithT , t * test , result ctrl.Result ) {
355+ g .Expect (len (t .deleteMachines )).To (Equal (1 ))
356+ },
261357 },
262358 {
263359 name : "control plane backend vnic attachments call error" ,
264360 errorExpected : true ,
265361 expectedEvent : "server error" ,
266362 conditionAssertion : []conditionAssertion {{infrastructurev1beta2 .InstanceReadyCondition , corev1 .ConditionFalse , clusterv1 .ConditionSeverityError , infrastructurev1beta2 .InstanceIPAddressNotFound }},
267- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
363+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbclient * mock_nlb.MockNetworkLoadBalancerClient ) {
268364 machineScope .Machine .ObjectMeta .Labels = make (map [string ]string )
269365 machineScope .Machine .ObjectMeta .Labels [clusterv1 .MachineControlPlaneLabel ] = "true"
270366 computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
@@ -287,7 +383,7 @@ func TestNormalReconciliationFunction(t *testing.T) {
287383 {
288384 name : "control plane backend backend exists" ,
289385 errorExpected : false ,
290- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
386+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
291387 machineScope .Machine .ObjectMeta .Labels = make (map [string ]string )
292388 machineScope .Machine .ObjectMeta .Labels [clusterv1 .MachineControlPlaneLabel ] = "true"
293389 computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
@@ -344,7 +440,7 @@ func TestNormalReconciliationFunction(t *testing.T) {
344440 {
345441 name : "backend creation" ,
346442 errorExpected : false ,
347- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
443+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
348444 machineScope .Machine .ObjectMeta .Labels = make (map [string ]string )
349445 machineScope .Machine .ObjectMeta .Labels [clusterv1 .MachineControlPlaneLabel ] = "true"
350446 computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
@@ -419,7 +515,7 @@ func TestNormalReconciliationFunction(t *testing.T) {
419515 {
420516 name : "ip address exists" ,
421517 errorExpected : false ,
422- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
518+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
423519 machineScope .Machine .ObjectMeta .Labels = make (map [string ]string )
424520 machineScope .OCIMachine .Status .Addresses = []clusterv1.MachineAddress {
425521 {
@@ -478,7 +574,7 @@ func TestNormalReconciliationFunction(t *testing.T) {
478574 {
479575 name : "backend creation fails" ,
480576 errorExpected : true ,
481- testSpecificSetup : func (machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
577+ testSpecificSetup : func (t * test , machineScope * scope.MachineScope , computeClient * mock_compute.MockComputeClient , vcnClient * mock_vcn.MockClient , nlbClient * mock_nlb.MockNetworkLoadBalancerClient ) {
482578 machineScope .Machine .ObjectMeta .Labels = make (map [string ]string )
483579 machineScope .Machine .ObjectMeta .Labels [clusterv1 .MachineControlPlaneLabel ] = "true"
484580 computeClient .EXPECT ().GetInstance (gomock .Any (), gomock .Eq (core.GetInstanceRequest {
@@ -557,9 +653,9 @@ func TestNormalReconciliationFunction(t *testing.T) {
557653 g := NewWithT (t )
558654 defer teardown (t , g )
559655 setup (t , g )
560- tc .testSpecificSetup (ms , computeClient , vcnClient , nlbClient )
656+ tc .testSpecificSetup (& tc , ms , computeClient , vcnClient , nlbClient )
561657 ctx := context .Background ()
562- _ , err := r .reconcileNormal (ctx , log .FromContext (ctx ), ms )
658+ result , err := r .reconcileNormal (ctx , log .FromContext (ctx ), ms )
563659 if len (tc .conditionAssertion ) > 0 {
564660 expectConditions (g , ociMachine , tc .conditionAssertion )
565661 }
@@ -571,6 +667,9 @@ func TestNormalReconciliationFunction(t *testing.T) {
571667 if tc .expectedEvent != "" {
572668 g .Eventually (recorder .Events ).Should (Receive (ContainSubstring (tc .expectedEvent )))
573669 }
670+ if tc .validate != nil {
671+ tc .validate (g , & tc , result )
672+ }
574673 })
575674 }
576675}
0 commit comments