github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/configuration/configconstraint_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  	"time"
    24  
    25  	. "github.com/onsi/ginkgo/v2"
    26  	. "github.com/onsi/gomega"
    27  
    28  	corev1 "k8s.io/api/core/v1"
    29  	"sigs.k8s.io/controller-runtime/pkg/client"
    30  	"sigs.k8s.io/controller-runtime/pkg/log"
    31  
    32  	appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1"
    33  	cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core"
    34  	"github.com/1aal/kubeblocks/pkg/constant"
    35  	intctrlutil "github.com/1aal/kubeblocks/pkg/generics"
    36  	testapps "github.com/1aal/kubeblocks/pkg/testutil/apps"
    37  )
    38  
    39  var _ = Describe("ConfigConstraint Controller", func() {
    40  	const clusterDefName = "test-clusterdef"
    41  	const clusterVersionName = "test-clusterversion"
    42  	const statefulCompDefName = "replicasets"
    43  	const configSpecName = "mysql-config-tpl"
    44  	const configVolumeName = "mysql-config"
    45  
    46  	cleanEnv := func() {
    47  		// must wait till resources deleted and no longer existed before the testcases start,
    48  		// otherwise if later it needs to create some new resource objects with the same name,
    49  		// in race conditions, it will find the existence of old objects, resulting failure to
    50  		// create the new objects.
    51  		By("clean resources")
    52  
    53  		// delete cluster(and all dependent sub-resources), clusterversion and clusterdef
    54  		testapps.ClearClusterResources(&testCtx)
    55  
    56  		// delete rest mocked objects
    57  		inNS := client.InNamespace(testCtx.DefaultNamespace)
    58  		ml := client.HasLabels{testCtx.TestObjLabelKey}
    59  		// non-namespaced
    60  		testapps.ClearResources(&testCtx, intctrlutil.ConfigConstraintSignature, ml)
    61  		// namespaced
    62  		testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, intctrlutil.ConfigMapSignature, true, inNS, ml)
    63  	}
    64  
    65  	BeforeEach(cleanEnv)
    66  
    67  	AfterEach(cleanEnv)
    68  
    69  	Context("Create config constraint with cue validate", func() {
    70  		It("Should ready", func() {
    71  			By("creating a configmap and a config constraint")
    72  
    73  			configmap := testapps.CreateCustomizedObj(&testCtx,
    74  				"resources/mysql-config-template.yaml", &corev1.ConfigMap{},
    75  				testCtx.UseDefaultNamespace())
    76  
    77  			constraint := testapps.CreateCustomizedObj(&testCtx,
    78  				"resources/mysql-config-constraint.yaml",
    79  				&appsv1alpha1.ConfigConstraint{})
    80  			constraintKey := client.ObjectKeyFromObject(constraint)
    81  
    82  			By("Create a clusterDefinition obj")
    83  			clusterDefObj := testapps.NewClusterDefFactory(clusterDefName).
    84  				AddComponentDef(testapps.StatefulMySQLComponent, statefulCompDefName).
    85  				AddConfigTemplate(configSpecName, configmap.Name, constraint.Name, testCtx.DefaultNamespace, configVolumeName).
    86  				AddLabels(cfgcore.GenerateTPLUniqLabelKeyWithConfig(configSpecName), configmap.Name,
    87  					cfgcore.GenerateConstraintsUniqLabelKeyWithConfig(constraint.Name), constraint.Name).
    88  				Create(&testCtx).GetObject()
    89  
    90  			By("Create a clusterVersion obj")
    91  			clusterVersionObj := testapps.NewClusterVersionFactory(clusterVersionName, clusterDefObj.GetName()).
    92  				AddComponentVersion(statefulCompDefName).
    93  				AddLabels(cfgcore.GenerateTPLUniqLabelKeyWithConfig(configSpecName), configmap.Name,
    94  					cfgcore.GenerateConstraintsUniqLabelKeyWithConfig(constraint.Name), constraint.Name).
    95  				Create(&testCtx).GetObject()
    96  
    97  			By("check ConfigConstraint(template) status and finalizer")
    98  			Eventually(testapps.CheckObj(&testCtx, constraintKey,
    99  				func(g Gomega, tpl *appsv1alpha1.ConfigConstraint) {
   100  					g.Expect(tpl.Status.Phase).To(BeEquivalentTo(appsv1alpha1.AvailablePhase))
   101  					g.Expect(tpl.Finalizers).To(ContainElement(constant.ConfigurationTemplateFinalizerName))
   102  				})).Should(Succeed())
   103  
   104  			By("By delete ConfigConstraint")
   105  			Expect(k8sClient.Delete(testCtx.Ctx, constraint)).Should(Succeed())
   106  
   107  			By("check ConfigConstraint should not be deleted")
   108  			log.Log.Info("expect that ConfigConstraint is not deleted.")
   109  			Consistently(testapps.CheckObjExists(&testCtx, constraintKey, &appsv1alpha1.ConfigConstraint{}, true)).Should(Succeed())
   110  
   111  			By("check ConfigConstraint status should be deleting")
   112  			Eventually(testapps.CheckObj(&testCtx, constraintKey,
   113  				func(g Gomega, tpl *appsv1alpha1.ConfigConstraint) {
   114  					g.Expect(tpl.Status.Phase).To(BeEquivalentTo(appsv1alpha1.CCDeletingPhase))
   115  				})).Should(Succeed())
   116  
   117  			By("By delete referencing clusterdefinition and clusterversion")
   118  			Expect(k8sClient.Delete(testCtx.Ctx, clusterVersionObj)).Should(Succeed())
   119  			Expect(k8sClient.Delete(testCtx.Ctx, clusterDefObj)).Should(Succeed())
   120  
   121  			By("check ConfigConstraint should be deleted")
   122  			Eventually(testapps.CheckObjExists(&testCtx, constraintKey, &appsv1alpha1.ConfigConstraint{}, false), time.Second*60, time.Second*1).Should(Succeed())
   123  		})
   124  	})
   125  
   126  	Context("Create config constraint without cue validate", func() {
   127  		It("Should ready", func() {
   128  			By("creating a configmap and a config constraint")
   129  
   130  			_ = testapps.CreateCustomizedObj(&testCtx, "resources/mysql-config-template.yaml", &corev1.ConfigMap{},
   131  				testCtx.UseDefaultNamespace())
   132  
   133  			constraint := testapps.CreateCustomizedObj(&testCtx, "resources/mysql-config-constraint-not-validate.yaml",
   134  				&appsv1alpha1.ConfigConstraint{})
   135  
   136  			By("check config constraint status")
   137  			Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(constraint),
   138  				func(g Gomega, tpl *appsv1alpha1.ConfigConstraint) {
   139  					g.Expect(tpl.Status.Phase).Should(BeEquivalentTo(appsv1alpha1.AvailablePhase))
   140  				})).Should(Succeed())
   141  		})
   142  	})
   143  })