github.com/oam-dev/kubevela@v1.9.11/references/cli/addon_test.go (about) 1 /* 2 Copyright 2021 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package cli 18 19 import ( 20 "fmt" 21 "os" 22 "testing" 23 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 27 "github.com/fatih/color" 28 "github.com/getkin/kin-openapi/openapi3" 29 "github.com/stretchr/testify/assert" 30 31 pkgaddon "github.com/oam-dev/kubevela/pkg/addon" 32 "github.com/oam-dev/kubevela/pkg/utils/common" 33 "github.com/oam-dev/kubevela/pkg/utils/util" 34 ) 35 36 func TestParseMap(t *testing.T) { 37 testcase := []struct { 38 args []string 39 res map[string]interface{} 40 nilError bool 41 }{ 42 { 43 args: []string{"key1=value1"}, 44 res: map[string]interface{}{ 45 "key1": "value1", 46 }, 47 nilError: true, 48 }, 49 { 50 args: []string{"dbUrl=mongodb=mgset-58800212"}, 51 res: map[string]interface{}{ 52 "dbUrl": "mongodb=mgset-58800212", 53 }, 54 nilError: true, 55 }, 56 { 57 args: []string{"imagePullSecrets={a,b,c}"}, 58 res: map[string]interface{}{ 59 "imagePullSecrets": []interface{}{ 60 "a", "b", "c", 61 }, 62 }, 63 nilError: true, 64 }, 65 { 66 args: []string{"image.repo=www.test.com", "image.tag=1.1"}, 67 res: map[string]interface{}{ 68 "image": map[string]interface{}{ 69 "repo": "www.test.com", 70 "tag": "1.1", 71 }, 72 }, 73 nilError: true, 74 }, 75 { 76 args: []string{"local=true"}, 77 res: map[string]interface{}{ 78 "local": true, 79 }, 80 nilError: true, 81 }, 82 { 83 args: []string{"replicas=3"}, 84 res: map[string]interface{}{ 85 "replicas": int64(3), 86 }, 87 nilError: true, 88 }, 89 } 90 for _, s := range testcase { 91 r, err := parseAddonArgsToMap(s.args) 92 if s.nilError { 93 assert.NoError(t, err) 94 assert.Equal(t, s.res, r) 95 } else { 96 assert.Error(t, err, fmt.Sprintf("%v should be error case", s.args)) 97 } 98 } 99 } 100 101 func TestAddonEnableCmdWithErrLocalPath(t *testing.T) { 102 testcase := []struct { 103 args []string 104 errMsg string 105 }{ 106 { 107 args: []string{"./a_local_path"}, 108 errMsg: "addon directory ./a_local_path not found in local", 109 }, 110 { 111 args: []string{"a_local_path/"}, 112 errMsg: "addon directory a_local_path/ not found in local", 113 }, 114 } 115 116 ioStream := util.IOStreams{} 117 commandArgs := common.Args{} 118 cmd := NewAddonEnableCommand(commandArgs, ioStream) 119 initCommand(cmd) 120 121 for _, s := range testcase { 122 cmd.SetArgs(s.args) 123 err := cmd.Execute() 124 assert.Error(t, err, s.errMsg) 125 } 126 } 127 128 var _ = Describe("Test AddonRegistry Cmd", func() { 129 It("Test AddonRegistryAddCmd", func() { 130 testAddonRegistryAddCmd() 131 }) 132 }) 133 134 func testAddonRegistryAddCmd() { 135 testcase := []struct { 136 args []string 137 errMsg string 138 result *pkgaddon.Registry 139 }{ 140 { 141 args: []string{"noAuthRegistry", "--type=helm", "--endpoint=http://127.0.0.1/chartrepo/oam"}, 142 errMsg: "fail to add no auth addon registry", 143 }, 144 { 145 args: []string{"basicAuthRegistry", "--type=helm", "--endpoint=http://127.0.0.1/chartrepo/oam", "--username=hello", "--password=word"}, 146 errMsg: "fail to add basis auth addon registry", 147 }, 148 { 149 args: []string{"skipTlsRegistry", "--type=helm", "--endpoint=https://127.0.0.1/chartrepo/oam", "--insecureSkipTLS=true"}, 150 }, 151 } 152 153 ioStream := util.IOStreams{} 154 commandArgs := common.Args{} 155 commandArgs.SetClient(k8sClient) 156 157 cmd := NewAddAddonRegistryCommand(commandArgs, ioStream) 158 159 for _, s := range testcase { 160 cmd.SetArgs(s.args) 161 err := cmd.Execute() 162 Expect(err).To(HaveOccurred()) 163 } 164 } 165 166 func TestAddonUpgradeCmdWithErrLocalPath(t *testing.T) { 167 testcase := []struct { 168 args []string 169 errMsg string 170 }{ 171 { 172 args: []string{"./a_local_path"}, 173 errMsg: "addon directory ./a_local_path not found in local", 174 }, 175 { 176 args: []string{"a_local_path/"}, 177 errMsg: "addon directory a_local_path/ not found in local", 178 }, 179 } 180 181 ioStream := util.IOStreams{} 182 commandArgs := common.Args{} 183 cmd := NewAddonUpgradeCommand(commandArgs, ioStream) 184 initCommand(cmd) 185 186 for _, s := range testcase { 187 cmd.SetArgs(s.args) 188 err := cmd.Execute() 189 assert.Error(t, err, s.errMsg) 190 } 191 } 192 193 func TestTransCluster(t *testing.T) { 194 testcase := []struct { 195 str string 196 res []interface{} 197 }{ 198 { 199 str: "{cluster1, cluster2}", 200 res: []interface{}{"cluster1", "cluster2"}, 201 }, 202 { 203 str: "{cluster1,cluster2}", 204 res: []interface{}{"cluster1", "cluster2"}, 205 }, 206 { 207 str: "{cluster1, cluster2 }", 208 res: []interface{}{"cluster1", "cluster2"}, 209 }, 210 } 211 for _, s := range testcase { 212 assert.Equal(t, transClusters(s.str), s.res) 213 } 214 } 215 216 func TestGenerateAvailableVersions(t *testing.T) { 217 type testcase struct { 218 inVersion string 219 versions []string 220 } 221 testcases := []struct { 222 c testcase 223 res string 224 }{ 225 { 226 c: testcase{ 227 inVersion: "1.2.1", 228 versions: []string{"1.2.1"}, 229 }, 230 res: fmt.Sprintf("[%s]", color.New(color.Bold, color.FgGreen).Sprintf("1.2.1")), 231 }, 232 { 233 c: testcase{ 234 inVersion: "1.2.1", 235 versions: []string{"1.2.3", "1.2.2", "1.2.1"}, 236 }, 237 res: fmt.Sprintf("[%s, 1.2.3, 1.2.2]", color.New(color.Bold, color.FgGreen).Sprintf("1.2.1")), 238 }, 239 { 240 c: testcase{ 241 inVersion: "1.2.1", 242 versions: []string{"1.2.3", "1.2.2", "1.2.1", "1.2.0"}, 243 }, 244 res: fmt.Sprintf("[%s, 1.2.3, 1.2.2, ...]", color.New(color.Bold, color.FgGreen).Sprintf("1.2.1")), 245 }, 246 } 247 for _, s := range testcases { 248 re := genAvailableVersionInfo(s.c.versions, s.c.inVersion, 3) 249 assert.Equal(t, re, s.res) 250 } 251 } 252 253 func TestLimitStringLength(t *testing.T) { 254 type testcase struct { 255 testString string 256 lengthLimit int 257 } 258 259 testcases := []struct { 260 c testcase 261 res string 262 }{ 263 // len = limit 264 { 265 c: testcase{ 266 testString: "4444", 267 lengthLimit: 4, 268 }, 269 res: "4444", 270 }, 271 // len > limit 272 { 273 c: testcase{ 274 testString: "3333", 275 lengthLimit: 3, 276 }, 277 res: "333...", 278 }, 279 // len < limit 280 { 281 c: testcase{ 282 testString: "22", 283 lengthLimit: 3, 284 }, 285 res: "22", 286 }, 287 // limit = 0 288 { 289 c: testcase{ 290 testString: "000", 291 lengthLimit: 0, 292 }, 293 res: "000", 294 }, 295 // limit < 0 296 { 297 c: testcase{ 298 testString: "000", 299 lengthLimit: -1, 300 }, 301 res: "000", 302 }, 303 } 304 305 for _, s := range testcases { 306 re := limitStringLength(s.c.testString, s.c.lengthLimit) 307 assert.Equal(t, re, s.res) 308 } 309 } 310 311 func TestAddonPackageCmdWithInvalidArgs(t *testing.T) { 312 testcase := []struct { 313 args []string 314 msg string 315 }{ 316 { 317 args: []string{}, 318 msg: "must specify addon directory path", 319 }, 320 { 321 args: []string{"./a_local_path"}, 322 msg: "fail to package", 323 }, 324 { 325 args: []string{"a_local_path/"}, 326 msg: "fail to package", 327 }, 328 } 329 330 commandArgs := common.Args{} 331 cmd := NewAddonPackageCommand(commandArgs) 332 333 for _, s := range testcase { 334 cmd.SetArgs(s.args) 335 err := cmd.Execute() 336 assert.ErrorContains(t, err, s.msg) 337 } 338 } 339 340 func TestPackageValidAddon(t *testing.T) { 341 commandArgs := common.Args{} 342 cmd := NewAddonPackageCommand(commandArgs) 343 cmd.SetArgs([]string{"./test-data/addon/sample"}) 344 err := cmd.Execute() 345 assert.NoError(t, err) 346 defer func() { 347 _ = os.RemoveAll("sample-1.0.1.tgz") 348 }() 349 } 350 351 func TestGenerateParameterString(t *testing.T) { 352 testcase := []struct { 353 status pkgaddon.Status 354 addonPackage *pkgaddon.WholeAddonPackage 355 outputs []string 356 }{ 357 { 358 status: pkgaddon.Status{}, 359 addonPackage: &pkgaddon.WholeAddonPackage{ 360 APISchema: nil, 361 }, 362 outputs: []string{""}, 363 }, 364 { 365 status: pkgaddon.Status{ 366 Parameters: map[string]interface{}{ 367 "database": "kubevela", 368 "dbType": "kubeapi", 369 }, 370 }, 371 addonPackage: &pkgaddon.WholeAddonPackage{ 372 APISchema: &openapi3.Schema{ 373 Required: []string{"dbType", "serviceAccountName", "serviceType", "dex"}, 374 Properties: openapi3.Schemas{ 375 "database": &openapi3.SchemaRef{ 376 Value: &openapi3.Schema{ 377 Description: "Specify the database name, for the kubeapi db type, it represents namespace.", 378 Default: nil, 379 }, 380 }, 381 "dbURL": &openapi3.SchemaRef{ 382 Value: &openapi3.Schema{ 383 Description: "Specify the MongoDB URL. it only enabled where DB type is MongoDB.", 384 Default: "abc.com", 385 }, 386 }, 387 "dbType": &openapi3.SchemaRef{ 388 Value: &openapi3.Schema{ 389 Description: "Specify the database type, current support KubeAPI(default) and MongoDB.", 390 Enum: []interface{}{"kubeapi", "mongodb"}, 391 }, 392 }, 393 }, 394 }, 395 }, 396 outputs: []string{ 397 // dbType 398 color.New(color.FgCyan).Sprintf("-> ") + 399 color.New(color.Bold).Sprint("dbType") + ": " + 400 "Specify the database type, current support KubeAPI(default) and MongoDB.\n" + 401 "\tcurrent value: " + color.New(color.FgGreen).Sprint("\"kubeapi\"\n") + 402 "\trequired: " + color.GreenString("✔\n") + 403 "\toptions: \"kubeapi\", \"mongodb\"\n", 404 // dbURL 405 color.New(color.FgCyan).Sprintf("-> ") + 406 color.New(color.Bold).Sprint("dbURL") + ": " + 407 "Specify the MongoDB URL. it only enabled where DB type is MongoDB.\n" + 408 "\tdefault: " + "\"abc.com\"\n", 409 // database 410 color.New(color.FgCyan).Sprintf("-> ") + 411 color.New(color.Bold).Sprint("database") + ": " + 412 "Specify the database name, for the kubeapi db type, it represents namespace.\n" + 413 "\tcurrent value: " + color.New(color.FgGreen).Sprint("\"kubevela\""), 414 }, 415 }, 416 } 417 418 for _, s := range testcase { 419 res := generateParameterString(s.status, s.addonPackage) 420 for _, o := range s.outputs { 421 assert.Contains(t, res, o) 422 } 423 424 } 425 } 426 427 func TestNewAddonCreateCommand(t *testing.T) { 428 cmd := NewAddonInitCommand() 429 cmd.SetArgs([]string{}) 430 err := cmd.Execute() 431 assert.ErrorContains(t, err, "required") 432 433 cmd.SetArgs([]string{"--chart", "a", "--helm-repo", "https://some.com", "--chart-version", "c"}) 434 err = cmd.Execute() 435 assert.ErrorContains(t, err, "required") 436 437 cmd.SetArgs([]string{"test-addon", "--chart", "a", "--helm-repo", "https://some.com", "--chart-version", "c"}) 438 err = cmd.Execute() 439 assert.NoError(t, err) 440 _ = os.RemoveAll("test-addon") 441 442 cmd.SetArgs([]string{"test-addon"}) 443 err = cmd.Execute() 444 assert.NoError(t, err) 445 _ = os.RemoveAll("test-addon") 446 447 } 448 449 func TestCheckSpecifyRegistry(t *testing.T) { 450 testCases := []struct { 451 name string 452 registry string 453 addonName string 454 hasError bool 455 }{ 456 { 457 name: "fluxcd", 458 registry: "", 459 addonName: "fluxcd", 460 hasError: false, 461 }, 462 { 463 name: "kubevela/fluxcd", 464 registry: "kubevela", 465 addonName: "fluxcd", 466 hasError: false, 467 }, 468 { 469 name: "test/kubevela/fluxcd", 470 registry: "", 471 addonName: "", 472 hasError: true, 473 }, 474 } 475 for _, testCase := range testCases { 476 r, n, err := splitSpecifyRegistry(testCase.name) 477 assert.Equal(t, err != nil, testCase.hasError) 478 assert.Equal(t, r, testCase.registry) 479 assert.Equal(t, n, testCase.addonName) 480 } 481 }