github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/configuration/configuration_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 "sigs.k8s.io/controller-runtime/pkg/log" 29 30 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 31 "github.com/1aal/kubeblocks/pkg/configuration/core" 32 "github.com/1aal/kubeblocks/pkg/constant" 33 "github.com/1aal/kubeblocks/pkg/controller/builder" 34 "github.com/1aal/kubeblocks/pkg/controller/component" 35 "github.com/1aal/kubeblocks/pkg/controller/configuration" 36 intctrlutil "github.com/1aal/kubeblocks/pkg/controllerutil" 37 "github.com/1aal/kubeblocks/pkg/generics" 38 testapps "github.com/1aal/kubeblocks/pkg/testutil/apps" 39 ) 40 41 const clusterDefName = "test-clusterdef" 42 const clusterVersionName = "test-clusterversion" 43 const clusterName = "test-cluster" 44 const statefulCompDefName = "replicasets" 45 const statefulCompName = "mysql" 46 const statefulSetName = "mysql-statefulset" 47 const configSpecName = "mysql-config-tpl" 48 const configVolumeName = "mysql-config" 49 const cmName = "mysql-tree-node-template-8.0" 50 51 func mockConfigResource() (*corev1.ConfigMap, *appsv1alpha1.ConfigConstraint) { 52 By("Create a config template obj") 53 configmap := testapps.CreateCustomizedObj(&testCtx, 54 "resources/mysql-config-template.yaml", &corev1.ConfigMap{}, 55 testCtx.UseDefaultNamespace(), 56 testapps.WithLabels( 57 constant.AppNameLabelKey, clusterName, 58 constant.AppInstanceLabelKey, clusterName, 59 constant.KBAppComponentLabelKey, statefulCompName, 60 constant.CMConfigurationTemplateNameLabelKey, configSpecName, 61 constant.CMConfigurationConstraintsNameLabelKey, cmName, 62 constant.CMConfigurationSpecProviderLabelKey, configSpecName, 63 constant.CMConfigurationTypeLabelKey, constant.ConfigInstanceType, 64 ), 65 testapps.WithAnnotations( 66 constant.KBParameterUpdateSourceAnnotationKey, constant.ReconfigureManagerSource, 67 constant.ConfigurationRevision, "1", 68 constant.CMInsEnableRerenderTemplateKey, "true")) 69 70 By("Create a config constraint obj") 71 constraint := testapps.CreateCustomizedObj(&testCtx, 72 "resources/mysql-config-constraint.yaml", 73 &appsv1alpha1.ConfigConstraint{}) 74 75 By("check config constraint") 76 Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(constraint), func(g Gomega, tpl *appsv1alpha1.ConfigConstraint) { 77 g.Expect(tpl.Status.Phase).Should(BeEquivalentTo(appsv1alpha1.AvailablePhase)) 78 })).Should(Succeed()) 79 80 By("Create a configuration obj") 81 // test-cluster-mysql-mysql-config-tpl 82 configuration := builder.NewConfigurationBuilder(testCtx.DefaultNamespace, core.GenerateComponentConfigurationName(clusterName, statefulCompName)). 83 ClusterRef(clusterName). 84 Component(statefulCompName). 85 AddConfigurationItem(appsv1alpha1.ComponentConfigSpec{ 86 ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ 87 Name: configSpecName, 88 TemplateRef: configmap.Name, 89 Namespace: configmap.Namespace, 90 VolumeName: configVolumeName, 91 }, 92 ConfigConstraintRef: constraint.Name, 93 }). 94 GetObject() 95 Expect(testCtx.CreateObj(testCtx.Ctx, configuration)).Should(Succeed()) 96 97 return configmap, constraint 98 } 99 100 func mockReconcileResource() (*corev1.ConfigMap, *appsv1alpha1.ConfigConstraint, *appsv1alpha1.Cluster, *appsv1alpha1.ClusterVersion, *component.SynthesizedComponent) { 101 configmap, constraint := mockConfigResource() 102 103 By("Create a clusterDefinition obj") 104 clusterDefObj := testapps.NewClusterDefFactory(clusterDefName). 105 AddComponentDef(testapps.StatefulMySQLComponent, statefulCompDefName). 106 AddConfigTemplate(configSpecName, configmap.Name, constraint.Name, testCtx.DefaultNamespace, configVolumeName). 107 AddLabels(core.GenerateTPLUniqLabelKeyWithConfig(configSpecName), configmap.Name, 108 core.GenerateConstraintsUniqLabelKeyWithConfig(constraint.Name), constraint.Name). 109 Create(&testCtx).GetObject() 110 111 By("Create a clusterVersion obj") 112 clusterVersionObj := testapps.NewClusterVersionFactory(clusterVersionName, clusterDefObj.GetName()). 113 AddComponentVersion(statefulCompDefName). 114 AddLabels(core.GenerateTPLUniqLabelKeyWithConfig(configSpecName), configmap.Name, 115 core.GenerateConstraintsUniqLabelKeyWithConfig(constraint.Name), constraint.Name). 116 Create(&testCtx).GetObject() 117 118 By("Creating a cluster") 119 clusterObj := testapps.NewClusterFactory(testCtx.DefaultNamespace, clusterName, 120 clusterDefObj.Name, clusterVersionObj.Name). 121 AddComponent(statefulCompName, statefulCompDefName).Create(&testCtx).GetObject() 122 123 container := *builder.NewContainerBuilder("mock-container"). 124 AddVolumeMounts(corev1.VolumeMount{ 125 Name: configVolumeName, 126 MountPath: "/mnt/config", 127 }).GetObject() 128 _ = testapps.NewStatefulSetFactory(testCtx.DefaultNamespace, statefulSetName, clusterObj.Name, statefulCompName). 129 AddConfigmapVolume(configVolumeName, configmap.Name). 130 AddContainer(container). 131 AddAppNameLabel(clusterName). 132 AddAppInstanceLabel(clusterName). 133 AddAppComponentLabel(statefulCompName). 134 AddAnnotations(core.GenerateTPLUniqLabelKeyWithConfig(configSpecName), configmap.Name). 135 Create(&testCtx).GetObject() 136 137 synthesizedComp, err := component.BuildComponent(intctrlutil.RequestCtx{ 138 Ctx: ctx, 139 Log: log.FromContext(ctx), 140 }, nil, 141 clusterObj, 142 clusterDefObj, 143 clusterDefObj.GetComponentDefByName(statefulCompDefName), 144 clusterObj.Spec.GetComponentByName(statefulCompName), 145 nil, 146 clusterVersionObj.Spec.GetDefNameMappingComponents()[statefulCompDefName]) 147 Expect(err).ShouldNot(HaveOccurred()) 148 149 return configmap, constraint, clusterObj, clusterVersionObj, synthesizedComp 150 } 151 152 func initConfiguration(resourceCtx *intctrlutil.ResourceCtx, synthesizedComponent *component.SynthesizedComponent, clusterObj *appsv1alpha1.Cluster, clusterVersionObj *appsv1alpha1.ClusterVersion) error { 153 return configuration.NewCreatePipeline(configuration.ReconcileCtx{ 154 ResourceCtx: resourceCtx, 155 Component: synthesizedComponent, 156 Cluster: clusterObj, 157 ClusterVer: clusterVersionObj, 158 PodSpec: synthesizedComponent.PodSpec, 159 }). 160 Prepare(). 161 UpdateConfiguration(). // reconcile Configuration 162 Configuration(). // sync Configuration 163 CreateConfigTemplate(). 164 UpdateConfigRelatedObject(). 165 UpdateConfigurationStatus(). 166 Complete() 167 } 168 169 func cleanEnv() { 170 // must wait till resources deleted and no longer existed before the testcases start, 171 // otherwise if later it needs to create some new resource objects with the same name, 172 // in race conditions, it will find the existence of old objects, resulting failure to 173 // create the new objects. 174 By("clean resources") 175 176 // delete cluster(and all dependent sub-resources), clusterversion and clusterdef 177 testapps.ClearClusterResources(&testCtx) 178 179 // delete rest mocked objects 180 inNS := client.InNamespace(testCtx.DefaultNamespace) 181 ml := client.HasLabels{testCtx.TestObjLabelKey} 182 // non-namespaced 183 testapps.ClearResources(&testCtx, generics.ConfigConstraintSignature, ml) 184 // namespaced 185 testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ConfigMapSignature, true, inNS, ml) 186 testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.StatefulSetSignature, true, inNS, ml) 187 testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ConfigurationSignature, false, inNS, ml) 188 }