From 3c3710e150719888fdea7efa8e55c55067d3c49b Mon Sep 17 00:00:00 2001 From: KeerthanaAP Date: Sun, 10 Nov 2024 15:32:55 +0530 Subject: [PATCH] Added UT for reconcileDelete function --- controllers/ibmpowervscluster_controller.go | 2 +- .../ibmpowervscluster_controller_test.go | 802 +++++++++++++++++- 2 files changed, 801 insertions(+), 3 deletions(-) diff --git a/controllers/ibmpowervscluster_controller.go b/controllers/ibmpowervscluster_controller.go index 74d035151..20669e7cc 100644 --- a/controllers/ibmpowervscluster_controller.go +++ b/controllers/ibmpowervscluster_controller.go @@ -384,7 +384,7 @@ func (r *IBMPowerVSClusterReconciler) reconcileDelete(ctx context.Context, clust clusterScope.Info("Deleting VPC security group") if err := clusterScope.DeleteVPCSecurityGroups(); err != nil { - allErrs = append(allErrs, errors.Wrapf(err, "failed to delete VPC subnet")) + allErrs = append(allErrs, errors.Wrapf(err, "failed to delete VPC security group")) } clusterScope.Info("Deleting VPC subnet") diff --git a/controllers/ibmpowervscluster_controller_test.go b/controllers/ibmpowervscluster_controller_test.go index d0f15bb9e..33fff5d88 100644 --- a/controllers/ibmpowervscluster_controller_test.go +++ b/controllers/ibmpowervscluster_controller_test.go @@ -739,8 +739,12 @@ func TestIBMPowerVSClusterReconciler_reconcile(t *testing.T) { func TestIBMPowerVSClusterReconciler_delete(t *testing.T) { var ( - reconciler IBMPowerVSClusterReconciler - clusterScope *scope.PowerVSClusterScope + reconciler IBMPowerVSClusterReconciler + clusterScope *scope.PowerVSClusterScope + mockPowerVS *powervsmock.MockPowerVS + mockTransitGateway *tgmock.MockTransitGateway + mockVpc *vpcmock.MockVpc + mockResourceClient *resourceclientmock.MockResourceController ) reconciler = IBMPowerVSClusterReconciler{ Client: testEnv.Client, @@ -764,6 +768,7 @@ func TestIBMPowerVSClusterReconciler_delete(t *testing.T) { }, Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), } + result, err := reconciler.reconcileDelete(ctx, clusterScope) g.Expect(err).To(BeNil()) g.Expect(result.RequeueAfter).To(BeZero()) @@ -839,6 +844,799 @@ func TestIBMPowerVSClusterReconciler_delete(t *testing.T) { g.Expect(clusterScope.Client.Update(ctx, powervsImage2)).To(Not(Succeed())) }) }) + + t.Run("when delete TransitGateway returns error", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + TransitGateway: &infrav1beta2.TransitGatewayStatus{ + ID: ptr.To("transitgatewayID"), + ControllerCreated: ptr.To(true), + PowerVSConnection: &infrav1beta2.ResourceReference{ + ControllerCreated: ptr.To(false), + ID: ptr.To("connectionID"), + }, + VPCConnection: &infrav1beta2.ResourceReference{ + ControllerCreated: ptr.To(false), + ID: ptr.To("connectionID"), + }, + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + tgw := &tgapiv1.TransitGateway{ + Name: ptr.To("transitGateway"), + ID: ptr.To("transitGatewayID"), + Status: ptr.To(string(infrav1beta2.TransitGatewayStateAvailable))} + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + mockTransitGateway.EXPECT().GetTransitGateway(gomock.Any()).Return(tgw, nil, nil) + mockTransitGateway.EXPECT().DeleteTransitGateway(gomock.Any()).Return(response, errors.New("failed to delete transit gateway")) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + + t.Run("when delete TransitGateway returns requeue as true", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + TransitGateway: &infrav1beta2.TransitGatewayStatus{ + ID: ptr.To("transitgatewayID"), + ControllerCreated: ptr.To(true), + PowerVSConnection: &infrav1beta2.ResourceReference{ + ControllerCreated: ptr.To(false), + ID: ptr.To("connectionID"), + }, + VPCConnection: &infrav1beta2.ResourceReference{ + ControllerCreated: ptr.To(false), + ID: ptr.To("connectionID"), + }, + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + tgw := &tgapiv1.TransitGateway{ + Name: ptr.To("transitGateway"), + ID: ptr.To("transitGatewayID"), + Status: ptr.To(string(infrav1beta2.TransitGatewayStateDeletePending))} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + mockTransitGateway.EXPECT().GetTransitGateway(gomock.Any()).Return(tgw, nil, nil) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(BeNil()) + expectedResult := ctrl.Result{RequeueAfter: time.Minute} + g.Expect(result).To(Equal(expectedResult)) + + }) + + t.Run("when delete LoadBalancer returns error ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + LoadBalancers: map[string]infrav1beta2.VPCLoadBalancerStatus{ + "lb": { + ID: ptr.To("lb-id"), + ControllerCreated: ptr.To(true), + }, + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetLoadBalancer(gomock.Any()).Return(&vpcv1.LoadBalancer{ + ID: ptr.To("lb-id"), + Name: ptr.To("lb"), + ProvisioningStatus: ptr.To(string(infrav1beta2.VPCLoadBalancerStateActive)), + }, nil, nil) + mockVpc.EXPECT().DeleteLoadBalancer(gomock.Any()).Return(response, errors.New("failed to delete load balancer")) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + + t.Run("when delete LoadBalancer returns requeue as true", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + LoadBalancers: map[string]infrav1beta2.VPCLoadBalancerStatus{ + "lb": { + ID: ptr.To("lb-id"), + ControllerCreated: ptr.To(true), + }, + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetLoadBalancer(gomock.Any()).Return(&vpcv1.LoadBalancer{ + ID: ptr.To("lb-id"), + Name: ptr.To("lb"), + ProvisioningStatus: ptr.To(string(infrav1beta2.VPCLoadBalancerStateDeletePending)), + }, nil, nil) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(BeNil()) + expectedResult := ctrl.Result{RequeueAfter: time.Minute} + g.Expect(result).To(Equal(expectedResult)) + + }) + + t.Run("when delete VPC security group returns error ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + VPCSecurityGroups: map[string]infrav1beta2.VPCSecurityGroupStatus{ + "sc": { + ID: ptr.To("sc-id"), + ControllerCreated: ptr.To(true), + }, + }, + }, + }, + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetSecurityGroup(gomock.Any()).Return(&vpcv1.SecurityGroup{ + ID: ptr.To("sc-id"), + Name: ptr.To("sc"), + }, nil, nil) + mockVpc.EXPECT().DeleteSecurityGroup(gomock.Any()).Return(response, errors.New("failed to delete VPC security group")) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + + t.Run("when delete VPC subnet returns error ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + VPCSubnet: map[string]infrav1beta2.ResourceReference{ + "subent1": { + ID: ptr.To("subent1"), + ControllerCreated: ptr.To(true), + }, + }, + }, + }, + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetSubnet(gomock.Any()).Return(&vpcv1.Subnet{Name: ptr.To("subnet1"), Status: ptr.To("active")}, nil, nil) + mockVpc.EXPECT().DeleteSubnet(gomock.Any()).Return(response, errors.New("failed to delete VPC subnet")) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + }) + + t.Run("when delete VPC subnet returns requeue as true", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + VPCSubnet: map[string]infrav1beta2.ResourceReference{ + "subent1": { + ID: ptr.To("subent1"), + ControllerCreated: ptr.To(true), + }, + }, + }, + }, + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetSubnet(gomock.Any()).Return(&vpcv1.Subnet{Name: ptr.To("subnet1"), Status: ptr.To(string(infrav1beta2.VPCSubnetStateDeleting))}, nil, nil) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(BeNil()) + expectedResult := ctrl.Result{RequeueAfter: 15 * time.Second} + g.Expect(result).To(Equal(expectedResult)) + }) + + t.Run("when delete VPC returns error ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + VPC: &infrav1beta2.ResourceReference{ + ID: ptr.To("vpcid"), + ControllerCreated: ptr.To(true), + }, + }, + }, + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetVPC(gomock.Any()).Return(&vpcv1.VPC{ID: ptr.To("vpcid"), Status: ptr.To("active")}, nil, nil) + mockVpc.EXPECT().DeleteVPC(gomock.Any()).Return(response, errors.New("failed to delete VPC")) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + }) + + t.Run("when delete VPC returns requeue as true", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + VPC: &infrav1beta2.ResourceReference{ + ID: ptr.To("vpcid"), + ControllerCreated: ptr.To(true), + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + mockVpc.EXPECT().GetVPC(gomock.Any()).Return(&vpcv1.VPC{ID: ptr.To("vpcid"), Status: ptr.To(string(infrav1beta2.VPCStateDeleting))}, nil, nil) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(BeNil()) + expectedResult := ctrl.Result{RequeueAfter: 15 * time.Second} + g.Expect(result).To(Equal(expectedResult)) + + }) + + t.Run("when delete DHCP returns error", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + ControllerCreated: ptr.To(false), + }, + DHCPServer: &infrav1beta2.ResourceReference{ + ID: ptr.To("DHCPServerID"), + ControllerCreated: ptr.To(true), + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + mockPowerVS.EXPECT().GetDHCPServer(gomock.Any()).Return(&models.DHCPServerDetail{ + ID: ptr.To("dhcpID"), + Status: ptr.To(string(infrav1beta2.DHCPServerStateActive)), + }, nil) + mockPowerVS.EXPECT().DeleteDHCPServer(gomock.Any()).Return(errors.New("failed to delete DHCP server")) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + t.Run("when delete ServiceInstance returns error ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + ControllerCreated: ptr.To(true), + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + mockResourceClient.EXPECT().GetResourceInstance(gomock.Any()).Return(&resourcecontrollerv2.ResourceInstance{ + Name: ptr.To("serviceInstanceName"), + ID: ptr.To("serviceInstanceID"), + State: ptr.To("active"), + CRN: ptr.To("powervs_crn"), + }, nil, nil) + mockResourceClient.EXPECT().DeleteResourceInstance(gomock.Any()).Return(response, errors.New("failed to delete service instance")) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + + t.Run("when delete ServiceInstance returns requeue as true", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + ControllerCreated: ptr.To(true), + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + mockResourceClient.EXPECT().GetResourceInstance(gomock.Any()).Return(&resourcecontrollerv2.ResourceInstance{ + Name: ptr.To("serviceInstanceName"), + ID: ptr.To("serviceInstanceID"), + State: ptr.To("active"), + CRN: ptr.To("powervs_crn"), + }, nil, nil) + mockResourceClient.EXPECT().DeleteResourceInstance(gomock.Any()).Return(response, nil) + clusterScope.ResourceClient = mockResourceClient + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(BeNil()) + expectedResult := ctrl.Result{RequeueAfter: time.Minute} + g.Expect(result).To(Equal(expectedResult)) + + }) + + t.Run("when delete COSInstance returns error ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + Ignition: &infrav1beta2.Ignition{Version: "3.4"}, + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + COSInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("CosInstanceID"), + ControllerCreated: ptr.To(true), + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + response := &core.DetailedResponse{} + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + mockResourceClient.EXPECT().GetResourceInstance(gomock.Any()).Return(&resourcecontrollerv2.ResourceInstance{ + Name: ptr.To("COSInstanceName"), + ID: ptr.To("COSInstanceID"), + State: ptr.To("active"), + }, nil, nil) + mockResourceClient.EXPECT().DeleteResourceInstance(gomock.Any()).Return(response, errors.New("failed to delete COS service instance")) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(Not(BeNil())) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + + t.Run("when reconcile delete is successful ", func(t *testing.T) { + g := NewWithT(t) + clusterScope = &scope.PowerVSClusterScope{ + Logger: klog.Background(), + IBMPowerVSCluster: &infrav1beta2.IBMPowerVSCluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "IBMPowerVSCluster", + APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "capi-powervs-cluster", + Annotations: map[string]string{"powervs.cluster.x-k8s.io/create-infra": "true"}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capiv1beta1.GroupVersion.String(), + Kind: "Cluster", + Name: "capi-test", + UID: "1", + }}, + }, + Spec: infrav1beta2.IBMPowerVSClusterSpec{ + ServiceInstanceID: "service-instance-1", + Ignition: &infrav1beta2.Ignition{Version: "3.4"}, + }, + Status: infrav1beta2.IBMPowerVSClusterStatus{ + ServiceInstance: &infrav1beta2.ResourceReference{ + ID: ptr.To("serviceInstanceID"), + }, + }, + }, + + Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithObjects().Build(), + } + mockPowerVS = powervsmock.NewMockPowerVS(gomock.NewController(t)) + mockPowerVS.EXPECT().WithClients(gomock.Any()) + clusterScope.IBMPowerVSClient = mockPowerVS + mockResourceClient = resourceclientmock.NewMockResourceController(gomock.NewController(t)) + clusterScope.ResourceClient = mockResourceClient + mockTransitGateway = tgmock.NewMockTransitGateway(gomock.NewController(t)) + clusterScope.TransitGatewayClient = mockTransitGateway + mockVpc = vpcmock.NewMockVpc(gomock.NewController(t)) + clusterScope.IBMVPCClient = mockVpc + result, err := reconciler.reconcileDelete(ctx, clusterScope) + g.Expect(err).To(BeNil()) + g.Expect(result.RequeueAfter).To(BeZero()) + + }) + } func TestReconcileVPCResources(t *testing.T) {