github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/cluster/config_ops_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 cluster 21 22 import ( 23 "bytes" 24 "io" 25 26 . "github.com/onsi/ginkgo/v2" 27 . "github.com/onsi/gomega" 28 29 cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core" 30 31 corev1 "k8s.io/api/core/v1" 32 "k8s.io/apimachinery/pkg/runtime" 33 "k8s.io/cli-runtime/pkg/genericiooptions" 34 clientfake "k8s.io/client-go/rest/fake" 35 cmdtesting "k8s.io/kubectl/pkg/cmd/testing" 36 37 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 38 "github.com/1aal/kubeblocks/pkg/cli/testing" 39 testapps "github.com/1aal/kubeblocks/pkg/testutil/apps" 40 ) 41 42 var _ = Describe("reconfigure test", func() { 43 const ( 44 clusterName = "cluster-ops" 45 clusterName1 = "cluster-ops1" 46 ) 47 var ( 48 streams genericiooptions.IOStreams 49 tf *cmdtesting.TestFactory 50 in *bytes.Buffer 51 ) 52 53 BeforeEach(func() { 54 streams, in, _, _ = genericiooptions.NewTestIOStreams() 55 tf = cmdtesting.NewTestFactory().WithNamespace(testing.Namespace) 56 clusterWithTwoComps := testing.FakeCluster(clusterName, testing.Namespace) 57 clusterWithOneComp := clusterWithTwoComps.DeepCopy() 58 clusterWithOneComp.Name = clusterName1 59 clusterWithOneComp.Spec.ComponentSpecs = []appsv1alpha1.ClusterComponentSpec{ 60 clusterWithOneComp.Spec.ComponentSpecs[0], 61 } 62 tf.FakeDynamicClient = testing.FakeDynamicClient(testing.FakeClusterDef(), 63 testing.FakeClusterVersion(), clusterWithTwoComps, clusterWithOneComp) 64 tf.Client = &clientfake.RESTClient{} 65 }) 66 67 AfterEach(func() { 68 tf.Cleanup() 69 }) 70 71 It("check params for reconfiguring operations", func() { 72 const ( 73 ns = "default" 74 clusterDefName = "test-clusterdef" 75 clusterVersionName = "test-clusterversion" 76 clusterName = "test-cluster" 77 statefulCompDefName = "replicasets" 78 statefulCompName = "mysql" 79 configSpecName = "mysql-config-tpl" 80 configVolumeName = "mysql-config" 81 ) 82 83 By("Create configmap and config constraint obj") 84 configmap := testapps.NewCustomizedObj("resources/mysql-config-template.yaml", &corev1.ConfigMap{}, testapps.WithNamespace(ns)) 85 constraint := testapps.NewCustomizedObj("resources/mysql-config-constraint.yaml", 86 &appsv1alpha1.ConfigConstraint{}) 87 componentConfig := testapps.NewConfigMap(ns, cfgcore.GetComponentCfgName(clusterName, statefulCompName, configSpecName), testapps.SetConfigMapData("my.cnf", "")) 88 By("Create a clusterDefinition obj") 89 clusterDefObj := testapps.NewClusterDefFactory(clusterDefName). 90 AddComponentDef(testapps.StatefulMySQLComponent, statefulCompDefName). 91 AddConfigTemplate(configSpecName, configmap.Name, constraint.Name, ns, configVolumeName). 92 GetObject() 93 By("Create a clusterVersion obj") 94 clusterVersionObj := testapps.NewClusterVersionFactory(clusterVersionName, clusterDefObj.GetName()). 95 AddComponentVersion(statefulCompDefName). 96 GetObject() 97 By("creating a cluster") 98 clusterObj := testapps.NewClusterFactory(ns, clusterName, 99 clusterDefObj.Name, ""). 100 AddComponent(statefulCompName, statefulCompDefName).GetObject() 101 102 objs := []runtime.Object{configmap, constraint, clusterDefObj, clusterVersionObj, clusterObj, componentConfig} 103 ttf, ops := NewFakeOperationsOptions(ns, clusterObj.Name, appsv1alpha1.ReconfiguringType, objs...) 104 o := &configOpsOptions{ 105 // nil cannot be set to a map struct in CueLang, so init the map of KeyValues. 106 OperationsOptions: &OperationsOptions{ 107 CreateOptions: *ops, 108 }, 109 } 110 o.KeyValues = make(map[string]*string) 111 o.HasPatch = true 112 defer ttf.Cleanup() 113 114 By("validate reconfiguring parameters") 115 o.ComponentNames = []string{statefulCompName} 116 _, err := o.parseUpdatedParams() 117 Expect(err.Error()).To(ContainSubstring(missingUpdatedParametersErrMessage)) 118 o.Parameters = []string{"abcd"} 119 120 _, err = o.parseUpdatedParams() 121 Expect(err.Error()).To(ContainSubstring("updated parameter format")) 122 o.Parameters = []string{"abcd=test"} 123 o.CfgTemplateName = configSpecName 124 o.IOStreams = streams 125 in.Write([]byte(o.Name + "\n")) 126 127 Expect(o.Complete()).Should(Succeed()) 128 129 in := &bytes.Buffer{} 130 in.Write([]byte("yes\n")) 131 132 o.CreateOptions.In = io.NopCloser(in) 133 Expect(o.Validate()).Should(Succeed()) 134 }) 135 136 })