github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/configuration/reconfigure_controller_test.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package configuration
    21  
    22  import (
    23  	. "github.com/onsi/ginkgo/v2"
    24  	. "github.com/onsi/gomega"
    25  
    26  	corev1 "k8s.io/api/core/v1"
    27  	"sigs.k8s.io/controller-runtime/pkg/client"
    28  
    29  	"github.com/1aal/kubeblocks/pkg/configuration/core"
    30  	"github.com/1aal/kubeblocks/pkg/constant"
    31  	testapps "github.com/1aal/kubeblocks/pkg/testutil/apps"
    32  )
    33  
    34  var _ = Describe("Reconfigure Controller", func() {
    35  	BeforeEach(cleanEnv)
    36  
    37  	AfterEach(cleanEnv)
    38  
    39  	Context("When updating configmap", func() {
    40  		It("Should rolling upgrade pod", func() {
    41  			configmap, _, clusterObj, _, _ := mockReconcileResource()
    42  
    43  			By("Check config for instance")
    44  			var configHash string
    45  			Eventually(func(g Gomega) {
    46  				cm := &corev1.ConfigMap{}
    47  				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), cm)).Should(Succeed())
    48  				g.Expect(cm.Labels[constant.AppInstanceLabelKey]).To(Equal(clusterObj.Name))
    49  				g.Expect(cm.Labels[constant.CMConfigurationTemplateNameLabelKey]).To(Equal(configSpecName))
    50  				g.Expect(cm.Labels[constant.CMConfigurationTypeLabelKey]).NotTo(Equal(""))
    51  				g.Expect(cm.Labels[constant.CMInsLastReconfigurePhaseKey]).To(Equal(core.ReconfigureCreatedPhase))
    52  				configHash = cm.Labels[constant.CMInsConfigurationHashLabelKey]
    53  				g.Expect(configHash).NotTo(Equal(""))
    54  				g.Expect(core.IsNotUserReconfigureOperation(cm)).To(BeTrue())
    55  				// g.Expect(cm.Annotations[constant.KBParameterUpdateSourceAnnotationKey]).To(Equal(constant.ReconfigureManagerSource))
    56  			}).Should(Succeed())
    57  
    58  			By("manager changes will not change the phase of configmap.")
    59  			Eventually(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(configmap), func(cm *corev1.ConfigMap) {
    60  				cm.Data["new_data"] = "###"
    61  				core.SetParametersUpdateSource(cm, constant.ReconfigureManagerSource)
    62  			})).Should(Succeed())
    63  
    64  			Eventually(func(g Gomega) {
    65  				cm := &corev1.ConfigMap{}
    66  				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), cm)).Should(Succeed())
    67  				newHash := cm.Labels[constant.CMInsConfigurationHashLabelKey]
    68  				g.Expect(newHash).NotTo(Equal(configHash))
    69  				g.Expect(core.IsNotUserReconfigureOperation(cm)).To(BeTrue())
    70  			}).Should(Succeed())
    71  
    72  			By("recover normal update parameters")
    73  			Eventually(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(configmap), func(cm *corev1.ConfigMap) {
    74  				delete(cm.Data, "new_data")
    75  				core.SetParametersUpdateSource(cm, constant.ReconfigureManagerSource)
    76  			})).Should(Succeed())
    77  
    78  			Eventually(func(g Gomega) {
    79  				cm := &corev1.ConfigMap{}
    80  				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), cm)).Should(Succeed())
    81  				newHash := cm.Labels[constant.CMInsConfigurationHashLabelKey]
    82  				g.Expect(newHash).To(Equal(configHash))
    83  				g.Expect(core.IsNotUserReconfigureOperation(cm)).To(BeTrue())
    84  			}).Should(Succeed())
    85  
    86  			By("Update config, old version: " + configHash)
    87  			updatedCM := testapps.NewCustomizedObj("resources/mysql-ins-config-update.yaml", &corev1.ConfigMap{})
    88  			Eventually(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(configmap), func(cm *corev1.ConfigMap) {
    89  				cm.Data = updatedCM.Data
    90  				core.SetParametersUpdateSource(cm, constant.ReconfigureUserSource)
    91  			})).Should(Succeed())
    92  
    93  			By("check config new version")
    94  			Eventually(func(g Gomega) {
    95  				cm := &corev1.ConfigMap{}
    96  				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), cm)).Should(Succeed())
    97  				newHash := cm.Labels[constant.CMInsConfigurationHashLabelKey]
    98  				g.Expect(newHash).NotTo(Equal(configHash))
    99  				g.Expect(cm.Labels[constant.CMInsLastReconfigurePhaseKey]).To(Equal(core.ReconfigureAutoReloadPhase))
   100  				g.Expect(core.IsNotUserReconfigureOperation(cm)).NotTo(BeTrue())
   101  			}).Should(Succeed())
   102  
   103  			By("invalid Update")
   104  			invalidUpdatedCM := testapps.NewCustomizedObj("resources/mysql-ins-config-invalid-update.yaml", &corev1.ConfigMap{})
   105  			Eventually(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(configmap), func(cm *corev1.ConfigMap) {
   106  				cm.Data = invalidUpdatedCM.Data
   107  				core.SetParametersUpdateSource(cm, constant.ReconfigureUserSource)
   108  			})).Should(Succeed())
   109  
   110  			By("check invalid update")
   111  			Eventually(func(g Gomega) {
   112  				cm := &corev1.ConfigMap{}
   113  				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), cm)).Should(Succeed())
   114  				g.Expect(core.IsNotUserReconfigureOperation(cm)).NotTo(BeTrue())
   115  				// g.Expect(cm.Labels[constant.CMInsLastReconfigurePhaseKey]).Should(BeEquivalentTo(cfgcore.ReconfigureNoChangeType))
   116  			}).Should(Succeed())
   117  
   118  			By("restart Update")
   119  			restartUpdatedCM := testapps.NewCustomizedObj("resources/mysql-ins-config-update-with-restart.yaml", &corev1.ConfigMap{})
   120  			Eventually(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(configmap), func(cm *corev1.ConfigMap) {
   121  				cm.Data = restartUpdatedCM.Data
   122  				core.SetParametersUpdateSource(cm, constant.ReconfigureUserSource)
   123  			})).Should(Succeed())
   124  
   125  			By("check invalid update")
   126  			Eventually(func(g Gomega) {
   127  				cm := &corev1.ConfigMap{}
   128  				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), cm)).Should(Succeed())
   129  				g.Expect(core.IsNotUserReconfigureOperation(cm)).NotTo(BeTrue())
   130  				g.Expect(cm.Labels[constant.CMInsLastReconfigurePhaseKey]).Should(BeEquivalentTo(core.ReconfigureSimplePhase))
   131  			}).Should(Succeed())
   132  		})
   133  	})
   134  
   135  })