github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/cluster/update_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 . "github.com/onsi/ginkgo/v2" 24 . "github.com/onsi/gomega" 25 "github.com/spf13/cobra" 26 "k8s.io/cli-runtime/pkg/genericiooptions" 27 "k8s.io/client-go/dynamic" 28 cmdtesting "k8s.io/kubectl/pkg/cmd/testing" 29 30 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 31 32 "github.com/1aal/kubeblocks/pkg/cli/patch" 33 "github.com/1aal/kubeblocks/pkg/cli/testing" 34 "github.com/1aal/kubeblocks/pkg/cli/types" 35 ) 36 37 var _ = Describe("cluster update", func() { 38 var streams genericiooptions.IOStreams 39 var tf *cmdtesting.TestFactory 40 41 BeforeEach(func() { 42 streams, _, _, _ = genericiooptions.NewTestIOStreams() 43 tf = cmdtesting.NewTestFactory().WithNamespace("default") 44 }) 45 46 AfterEach(func() { 47 tf.Cleanup() 48 }) 49 50 It("update command", func() { 51 cmd := NewUpdateCmd(tf, streams) 52 Expect(cmd).ShouldNot(BeNil()) 53 }) 54 55 Context("complete", func() { 56 var o *updateOptions 57 var cmd *cobra.Command 58 var args []string 59 BeforeEach(func() { 60 cmd = NewUpdateCmd(tf, streams) 61 o = &updateOptions{Options: patch.NewOptions(tf, streams, types.ClusterGVR())} 62 args = []string{"c1"} 63 64 }) 65 66 It("args is empty", func() { 67 Expect(o.complete(cmd, nil)).Should(HaveOccurred()) 68 }) 69 70 It("the length of args greater than 1", func() { 71 Expect(o.complete(cmd, []string{"c1", "c2"})).Should(HaveOccurred()) 72 }) 73 74 It("args only contains one cluster name", func() { 75 Expect(o.complete(cmd, args)).Should(Succeed()) 76 Expect(o.Names[0]).Should(Equal("c1")) 77 }) 78 79 It("set termination-policy", func() { 80 Expect(cmd.Flags().Set("termination-policy", "Delete")).Should(Succeed()) 81 Expect(o.complete(cmd, args)).Should(Succeed()) 82 Expect(o.namespace).Should(Equal("default")) 83 Expect(o.dynamic).ShouldNot(BeNil()) 84 Expect(o.Patch).Should(ContainSubstring("terminationPolicy")) 85 }) 86 87 It("set monitoring interval", func() { 88 fakeCluster := testing.FakeCluster("c1", "default") 89 tf.FakeDynamicClient = testing.FakeDynamicClient(fakeCluster) 90 Expect(cmd.Flags().Set("monitoring-interval", "15")).Should(Succeed()) 91 Expect(o.complete(cmd, args)).Should(Succeed()) 92 Expect(o.Patch).Should(ContainSubstring("\"monitor\":true")) 93 }) 94 95 It("set enable-all-logs", func() { 96 fakeCluster := testing.FakeCluster("c1", "default") 97 tf.FakeDynamicClient = testing.FakeDynamicClient(fakeCluster) 98 Expect(cmd.Flags().Set("enable-all-logs", "false")).Should(Succeed()) 99 Expect(o.complete(cmd, args)).Should(Succeed()) 100 }) 101 102 It("set node-labels", func() { 103 fakeCluster := testing.FakeCluster("c1", "default") 104 tf.FakeDynamicClient = testing.FakeDynamicClient(fakeCluster) 105 Expect(cmd.Flags().Set("node-labels", "k1=v1,k2=v2")).Should(Succeed()) 106 Expect(o.complete(cmd, args)).Should(Succeed()) 107 Expect(o.Patch).Should(ContainSubstring("k1")) 108 }) 109 }) 110 Context("logs variables reconfiguring tests", func() { 111 var ( 112 c *appsv1alpha1.Cluster 113 cd *appsv1alpha1.ClusterDefinition 114 myConfig string 115 ) 116 BeforeEach(func() { 117 c = testing.FakeCluster("c1", "default") 118 cd = testing.FakeClusterDef() 119 myConfig = ` 120 {{ block "logsBlock" . }} 121 log_statements_unsafe_for_binlog=OFF 122 log_error_verbosity=2 123 log_output=FILE 124 {{- if hasKey $.component "enabledLogs" }} 125 {{- if mustHas "error" $.component.enabledLogs }} 126 log_error=/data/mysql/log/mysqld-error.log 127 {{- end }} 128 {{- if mustHas "slow" $.component.enabledLogs }} 129 slow_query_log=ON 130 long_query_time=5 131 slow_query_log_file=/data/mysql/log/mysqld-slowquery.log 132 {{- end }} 133 {{- if mustHas "general" $.component.enabledLogs }} 134 general_log=ON 135 general_log_file=/data/mysql/log/mysqld.log 136 {{- end }} 137 {{- end }} 138 {{ end }} 139 ` 140 }) 141 142 It("findFirstConfigSpec tests", func() { 143 tests := []struct { 144 compSpecs []appsv1alpha1.ClusterComponentSpec 145 cdCompSpecs []appsv1alpha1.ClusterComponentDefinition 146 compName string 147 expectedErr bool 148 }{ 149 { 150 compSpecs: nil, 151 cdCompSpecs: nil, 152 compName: "name", 153 expectedErr: true, 154 }, 155 { 156 compSpecs: c.Spec.ComponentSpecs, 157 cdCompSpecs: cd.Spec.ComponentDefs, 158 compName: testing.ComponentName, 159 expectedErr: false, 160 }, 161 { 162 compSpecs: c.Spec.ComponentSpecs, 163 cdCompSpecs: cd.Spec.ComponentDefs, 164 compName: "error-name", 165 expectedErr: true, 166 }, 167 } 168 for _, test := range tests { 169 configSpec, err := findFirstConfigSpec(test.compSpecs, test.cdCompSpecs, test.compName) 170 if test.expectedErr { 171 Expect(err).Should(HaveOccurred()) 172 } else { 173 Expect(configSpec).ShouldNot(BeNil()) 174 Expect(err).ShouldNot(HaveOccurred()) 175 } 176 } 177 }) 178 179 It("findConfigTemplateInfo tests", func() { 180 tests := []struct { 181 dynamic dynamic.Interface 182 configSpec *appsv1alpha1.ComponentConfigSpec 183 expectedErr bool 184 }{{ 185 dynamic: nil, 186 configSpec: nil, 187 expectedErr: true, 188 }, { 189 dynamic: testing.FakeDynamicClient(testing.FakeConfigMap("config-template", testing.Namespace, map[string]string{"fake": "fake"})), 190 configSpec: &appsv1alpha1.ComponentConfigSpec{ 191 ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ 192 TemplateRef: "config-template", 193 Namespace: testing.Namespace, 194 }, 195 }, 196 expectedErr: true, 197 }, { 198 dynamic: testing.FakeDynamicClient(testing.FakeConfigMap("config-template", testing.Namespace, map[string]string{"fake": "fake"})), 199 configSpec: &appsv1alpha1.ComponentConfigSpec{ 200 ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ 201 TemplateRef: "config-template", 202 Namespace: testing.Namespace, 203 }, 204 }, 205 expectedErr: true, 206 }, { 207 dynamic: testing.FakeDynamicClient(testing.FakeConfigMap("config-template", testing.Namespace, map[string]string{"fake": "fake"}), testing.FakeConfigConstraint("config-constraint")), 208 configSpec: &appsv1alpha1.ComponentConfigSpec{ 209 ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ 210 TemplateRef: "config-template", 211 212 Namespace: testing.Namespace, 213 }, 214 ConfigConstraintRef: "config-constraint", 215 }, 216 expectedErr: false, 217 }} 218 for _, test := range tests { 219 cm, format, err := findConfigTemplateInfo(test.dynamic, test.configSpec) 220 if test.expectedErr { 221 Expect(err).Should(HaveOccurred()) 222 } else { 223 Expect(cm).ShouldNot(BeNil()) 224 Expect(format).ShouldNot(BeNil()) 225 Expect(err).ShouldNot(HaveOccurred()) 226 } 227 } 228 }) 229 230 It("findLogsBlockTPL tests", func() { 231 tests := []struct { 232 confData map[string]string 233 keyName string 234 expectedErr bool 235 expectedNil bool 236 }{{ 237 confData: nil, 238 keyName: "", 239 expectedErr: false, 240 expectedNil: true, 241 }, { 242 confData: map[string]string{ 243 "test.cnf": "test", 244 "my.cnf": "{{ logsBlock", 245 }, 246 keyName: "my.cnf", 247 expectedErr: true, 248 }, { 249 confData: map[string]string{ 250 "my.cnf": myConfig, 251 }, 252 keyName: "my.cnf", 253 expectedErr: false, 254 }, 255 } 256 for _, test := range tests { 257 key, tpl, err := findLogsBlockTPL(test.confData) 258 if test.expectedErr { 259 Expect(err).Should(HaveOccurred()) 260 } else { 261 Expect(key).Should(Equal(test.keyName)) 262 if !test.expectedNil { 263 Expect(tpl).ShouldNot(BeNil()) 264 } 265 Expect(err).ShouldNot(HaveOccurred()) 266 } 267 } 268 }) 269 270 It("buildLogsTPLValues tests", func() { 271 configSpec := testing.FakeCluster("test", "test").Spec.ComponentSpecs[0] 272 tplValue, err := buildLogsTPLValues(&configSpec) 273 Expect(err).ShouldNot(HaveOccurred()) 274 Expect(tplValue).ShouldNot(BeNil()) 275 }) 276 277 It("buildLogsReconfiguringOps tests", func() { 278 opsRequest := buildLogsReconfiguringOps("clusterName", "namespace", "compName", "configName", "keyName", map[string]string{"key1": "value1", "key2": "value2"}) 279 Expect(opsRequest).ShouldNot(BeNil()) 280 Expect(opsRequest.Spec.Reconfigure.ComponentName).Should(Equal("compName")) 281 Expect(opsRequest.Spec.Reconfigure.Configurations).Should(HaveLen(1)) 282 Expect(opsRequest.Spec.Reconfigure.Configurations[0].Keys).Should(HaveLen(1)) 283 Expect(opsRequest.Spec.Reconfigure.Configurations[0].Keys[0].Parameters).Should(HaveLen(2)) 284 }) 285 286 }) 287 })