github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/action/upgradedbs_test.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package action_test
    20  
    21  import (
    22  	"context"
    23  	"errors"
    24  	"strings"
    25  
    26  	controllermocks "github.com/IBM-Blockchain/fabric-operator/controllers/mocks"
    27  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    28  	. "github.com/onsi/ginkgo/v2"
    29  	. "github.com/onsi/gomega"
    30  	appsv1 "k8s.io/api/apps/v1"
    31  	batchv1 "k8s.io/api/batch/v1"
    32  	corev1 "k8s.io/api/core/v1"
    33  	v1 "k8s.io/api/core/v1"
    34  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    35  	"k8s.io/apimachinery/pkg/runtime"
    36  	"k8s.io/apimachinery/pkg/types"
    37  	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
    38  
    39  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    40  	"github.com/IBM-Blockchain/fabric-operator/pkg/action"
    41  	"github.com/IBM-Blockchain/fabric-operator/pkg/action/mocks"
    42  	"github.com/IBM-Blockchain/fabric-operator/pkg/apis/common"
    43  )
    44  
    45  var _ = Describe("actions", func() {
    46  	var (
    47  		depMgr   *mocks.DeploymentReset
    48  		client   *controllermocks.Client
    49  		instance *current.IBPPeer
    50  	)
    51  
    52  	BeforeEach(func() {
    53  		depMgr = &mocks.DeploymentReset{}
    54  		instance = &current.IBPPeer{
    55  			ObjectMeta: metav1.ObjectMeta{
    56  				Name: "peer",
    57  			},
    58  			Spec: current.IBPPeerSpec{
    59  				Images: &current.PeerImages{
    60  					PeerImage: "peerimage",
    61  					PeerTag:   "peertag",
    62  				},
    63  			},
    64  		}
    65  
    66  		replicas := int32(1)
    67  		dep := &appsv1.Deployment{
    68  			Spec: appsv1.DeploymentSpec{
    69  				Replicas: &replicas,
    70  				Template: corev1.PodTemplateSpec{
    71  					Spec: corev1.PodSpec{
    72  						Containers: []corev1.Container{
    73  							v1.Container{
    74  								Name: "peer",
    75  							},
    76  						},
    77  					},
    78  				},
    79  			},
    80  		}
    81  		depMgr.GetReturnsOnCall(0, dep, nil)
    82  		depMgr.GetReturnsOnCall(1, &appsv1.Deployment{}, nil)
    83  		depMgr.GetReturnsOnCall(2, &appsv1.Deployment{}, nil)
    84  		depMgr.GetSchemeReturns(&runtime.Scheme{})
    85  
    86  		status := appsv1.DeploymentStatus{
    87  			Replicas: int32(0),
    88  		}
    89  		depMgr.DeploymentStatusReturnsOnCall(0, status, nil)
    90  
    91  		status.Replicas = 1
    92  		depMgr.DeploymentStatusReturnsOnCall(1, status, nil)
    93  
    94  		client = &controllermocks.Client{
    95  			GetStub: func(ctx context.Context, types types.NamespacedName, obj k8sclient.Object) error {
    96  				switch obj.(type) {
    97  				case *batchv1.Job:
    98  					job := obj.(*batchv1.Job)
    99  					job.Status.Active = int32(1)
   100  				}
   101  				return nil
   102  			},
   103  			ListStub: func(ctx context.Context, obj k8sclient.ObjectList, opts ...k8sclient.ListOption) error {
   104  				switch obj.(type) {
   105  				case *corev1.PodList:
   106  					pods := obj.(*corev1.PodList)
   107  					if strings.Contains(opts[0].(*k8sclient.ListOptions).LabelSelector.String(), "job-name") {
   108  						pods.Items = []corev1.Pod{
   109  							{
   110  								Status: corev1.PodStatus{
   111  									ContainerStatuses: []corev1.ContainerStatus{
   112  										{
   113  											State: corev1.ContainerState{
   114  												Terminated: &corev1.ContainerStateTerminated{},
   115  												// Running: &corev1.ContainerStateRunning{},
   116  											},
   117  										},
   118  									},
   119  								},
   120  							},
   121  						}
   122  					}
   123  				}
   124  				return nil
   125  			},
   126  		}
   127  	})
   128  
   129  	Context("peer upgrade dbs", func() {
   130  		It("returns error if failed to set replica to zero", func() {
   131  			client.PatchReturnsOnCall(0, errors.New("update error"))
   132  			err := action.UpgradeDBs(depMgr, client, instance, config.DBMigrationTimeouts{})
   133  			Expect(err).To(HaveOccurred())
   134  			Expect(err).To(MatchError(ContainSubstring("update error")))
   135  		})
   136  
   137  		It("returns error if failed to set replica to original value", func() {
   138  			client.PatchReturnsOnCall(1, errors.New("update error"))
   139  			err := action.UpgradeDBs(depMgr, client, instance, config.DBMigrationTimeouts{
   140  				JobStart:      common.MustParseDuration("1s"),
   141  				JobCompletion: common.MustParseDuration("1s"),
   142  			})
   143  			Expect(err).To(HaveOccurred())
   144  			Expect(err).To(MatchError(ContainSubstring("update error")))
   145  		})
   146  
   147  		It("returns error if failed start job", func() {
   148  			client.CreateReturns(errors.New("job create error"))
   149  			err := action.UpgradeDBs(depMgr, client, instance, config.DBMigrationTimeouts{})
   150  			Expect(err).To(HaveOccurred())
   151  			Expect(err).To(MatchError(ContainSubstring("job create error")))
   152  		})
   153  
   154  		It("upgrade dbs", func() {
   155  			err := action.UpgradeDBs(depMgr, client, instance, config.DBMigrationTimeouts{})
   156  			Expect(err).NotTo(HaveOccurred())
   157  
   158  			By("starting job", func() {
   159  				Expect(client.CreateCallCount()).To(Equal(1))
   160  			})
   161  
   162  			By("updating deployments to update replicas", func() {
   163  				_, dep, _, _ := client.PatchArgsForCall(0)
   164  				Expect(*dep.(*appsv1.Deployment).Spec.Replicas).To(Equal(int32(0)))
   165  
   166  				_, dep, _, _ = client.PatchArgsForCall(1)
   167  				Expect(*dep.(*appsv1.Deployment).Spec.Replicas).To(Equal(int32(1)))
   168  
   169  				Expect(client.PatchCallCount()).To(Equal(2))
   170  			})
   171  		})
   172  	})
   173  })