github.com/oam-dev/kubevela@v1.9.11/references/cli/def_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 "bytes" 21 "context" 22 "fmt" 23 "io" 24 "os" 25 "path/filepath" 26 "strings" 27 "testing" 28 "time" 29 30 "github.com/spf13/cobra" 31 "github.com/stretchr/testify/assert" 32 "github.com/stretchr/testify/require" 33 "k8s.io/apimachinery/pkg/api/errors" 34 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 35 "k8s.io/apimachinery/pkg/types" 36 "sigs.k8s.io/controller-runtime/pkg/client/fake" 37 "sigs.k8s.io/yaml" 38 39 common3 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 40 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 41 pkgdef "github.com/oam-dev/kubevela/pkg/definition" 42 addonutil "github.com/oam-dev/kubevela/pkg/utils/addon" 43 common2 "github.com/oam-dev/kubevela/pkg/utils/common" 44 "github.com/oam-dev/kubevela/pkg/utils/util" 45 ) 46 47 const ( 48 // VelaTestNamespace namespace for hosting objects used during test 49 VelaTestNamespace = "vela-test-system" 50 ) 51 52 func initArgs() common2.Args { 53 arg := common2.Args{} 54 arg.SetClient(fake.NewClientBuilder().WithScheme(common2.Scheme).Build()) 55 return arg 56 } 57 58 func initCommand(cmd *cobra.Command) { 59 cmd.SilenceErrors = true 60 cmd.SilenceUsage = true 61 cmd.Flags().StringP("env", "", "", "") 62 cmd.SetOut(io.Discard) 63 cmd.SetErr(io.Discard) 64 } 65 66 func createTrait(c common2.Args, t *testing.T) string { 67 return createTraitWithOwnerAddon(c, "", t) 68 } 69 70 func createTraitWithOwnerAddon(c common2.Args, addonName string, t *testing.T) string { 71 traitName := fmt.Sprintf("my-trait-%d", time.Now().UnixNano()) 72 createNamespacedTrait(c, traitName, VelaTestNamespace, addonName, t) 73 return traitName 74 } 75 76 func createNamespacedTrait(c common2.Args, name string, ns string, ownerAddon string, t *testing.T) { 77 traitName := fmt.Sprintf("my-trait-%d", time.Now().UnixNano()) 78 client, err := c.GetClient() 79 if err != nil { 80 t.Fatalf("failed to get client: %v", err) 81 } 82 if err := client.Create(context.Background(), &v1beta1.TraitDefinition{ 83 ObjectMeta: v1.ObjectMeta{ 84 Name: name, 85 Namespace: ns, 86 Annotations: map[string]string{ 87 pkgdef.DescriptionKey: "My test-trait " + traitName, 88 }, 89 OwnerReferences: []v1.OwnerReference{{ 90 Name: addonutil.Addon2AppName(ownerAddon), 91 }}, 92 }, 93 Spec: v1beta1.TraitDefinitionSpec{ 94 Schematic: &common3.Schematic{CUE: &common3.CUE{Template: "parameter: {}"}}, 95 }, 96 }); err != nil { 97 t.Fatalf("failed to create trait: %v", err) 98 } 99 } 100 101 func createLocalTraitAt(traitName string, localPath string, t *testing.T) string { 102 s := fmt.Sprintf(`// k8s metadata 103 "%s": { 104 type: "trait" 105 description: "My test-trait %s" 106 attributes: { 107 appliesToWorkloads: ["webservice", "worker"] 108 podDisruptive: true 109 } 110 } 111 112 // template 113 template: { 114 patch: { 115 spec: { 116 replicas: *1 | int 117 } 118 } 119 parameter: { 120 // +usage=Specify the number of workloads 121 replicas: *1 | int 122 } 123 } 124 `, traitName, traitName) 125 filename := filepath.Join(localPath, traitName+".cue") 126 if err := os.WriteFile(filename, []byte(s), 0600); err != nil { 127 t.Fatalf("failed to write temp trait file %s: %v", filename, err) 128 } 129 return filename 130 } 131 132 func createLocalTrait(t *testing.T) (string, string) { 133 traitName := fmt.Sprintf("my-trait-%d", time.Now().UnixNano()) 134 filename := createLocalTraitAt(traitName, os.TempDir(), t) 135 return traitName, filename 136 } 137 138 func createLocalTraits(t *testing.T) string { 139 dirname, err := os.MkdirTemp(os.TempDir(), "vela-def-test-*") 140 if err != nil { 141 t.Fatalf("failed to create temporary directory: %v", err) 142 } 143 for i := 0; i < 3; i++ { 144 createLocalTraitAt(fmt.Sprintf("trait-%d", i), dirname, t) 145 } 146 return dirname 147 } 148 149 func createLocalDeploymentYAML(t *testing.T) string { 150 s := `apiVersion: apps/v1 151 kind: Deployment 152 metadata: 153 name: "main" 154 Spec: 155 image: "busybox" 156 --- 157 apiVersion: apps/v1 158 kind: Deployment 159 metadata: 160 name: "secondary" 161 Spec: 162 image: "busybox" 163 ` 164 filename := filepath.Join(os.TempDir(), fmt.Sprintf("%d-deployments.yaml", time.Now().UnixNano())) 165 if err := os.WriteFile(filename, []byte(s), 0600); err != nil { 166 t.Fatalf("failed to create temp deployments file %s: %v", filename, err) 167 } 168 return filename 169 } 170 171 func removeFile(filename string, t *testing.T) { 172 if err := os.Remove(filename); err != nil { 173 t.Fatalf("failed to remove file %s: %v", filename, err) 174 } 175 } 176 177 func removeDir(dirname string, t *testing.T) { 178 if err := os.RemoveAll(dirname); err != nil { 179 t.Fatalf("failed to remove dir %s: %v", dirname, err) 180 } 181 } 182 183 func TestNewDefinitionCommandGroup(t *testing.T) { 184 cmd := DefinitionCommandGroup(common2.Args{}, "", util.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) 185 initCommand(cmd) 186 cmd.SetArgs([]string{"-h"}) 187 if err := cmd.Execute(); err != nil { 188 t.Fatalf("failed to execute definition command: %v", err) 189 } 190 } 191 192 func TestNewDefinitionInitCommand(t *testing.T) { 193 c := initArgs() 194 // test normal 195 cmd := NewDefinitionInitCommand(c) 196 initCommand(cmd) 197 cmd.SetArgs([]string{"my-ingress", "-t", "trait", "--desc", "test ingress"}) 198 if err := cmd.Execute(); err != nil { 199 t.Fatalf("unexpected error when executing init command: %v", err) 200 } 201 // test interactive 202 cmd = NewDefinitionInitCommand(initArgs()) 203 initCommand(cmd) 204 componentName := "my-webservice" 205 cmd.SetArgs([]string{componentName, "--interactive"}) 206 templateFilename := createLocalDeploymentYAML(t) 207 filename := strings.Replace(templateFilename, ".yaml", ".cue", 1) 208 defer removeFile(templateFilename, t) 209 defer removeFile(filename, t) 210 inputs := fmt.Sprintf("comp\ncomponent\nMy webservice component.\n%s\n%s\n", templateFilename, filename) 211 reader := strings.NewReader(inputs) 212 cmd.SetIn(reader) 213 if err := cmd.Execute(); err != nil { 214 t.Fatalf("unexpeced error when executing init command interactively: %v", err) 215 } 216 } 217 218 func TestNewDefinitionInitCommand4Terraform(t *testing.T) { 219 const ( 220 defVswitchFileName = "alibaba-vswitch.yaml" 221 defRedisFileName = "tencent-redis.yaml" 222 ) 223 testcases := []struct { 224 name string 225 args []string 226 output string 227 errMsg string 228 want string 229 }{ 230 { 231 name: "normal", 232 args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "xxx", "--git", "https://github.com/kubevela-contrib/terraform-modules.git", "--path", "alibaba/vswitch"}, 233 }, 234 { 235 name: "normal from local", 236 args: []string{"vswitch", "-t", "component", "--provider", "tencent", "--desc", "xxx", "--local", "test-data/redis.tf", "--output", defRedisFileName}, 237 output: defRedisFileName, 238 want: `apiVersion: core.oam.dev/v1beta1 239 kind: ComponentDefinition 240 metadata: 241 annotations: 242 definition.oam.dev/description: xxx 243 creationTimestamp: null 244 labels: 245 type: terraform 246 name: tencent-vswitch 247 namespace: vela-system 248 spec: 249 schematic: 250 terraform: 251 configuration: | 252 terraform { 253 required_providers { 254 tencentcloud = { 255 source = "tencentcloudstack/tencentcloud" 256 } 257 } 258 } 259 260 resource "tencentcloud_redis_instance" "main" { 261 type_id = 8 262 availability_zone = var.availability_zone 263 name = var.instance_name 264 password = var.user_password 265 mem_size = var.mem_size 266 port = var.port 267 } 268 269 output "DB_IP" { 270 value = tencentcloud_redis_instance.main.ip 271 } 272 273 output "DB_PASSWORD" { 274 value = var.user_password 275 } 276 277 output "DB_PORT" { 278 value = var.port 279 } 280 281 variable "availability_zone" { 282 description = "The available zone ID of an instance to be created." 283 type = string 284 default = "ap-chengdu-1" 285 } 286 287 variable "instance_name" { 288 description = "redis instance name" 289 type = string 290 default = "sample" 291 } 292 293 variable "user_password" { 294 description = "redis instance password" 295 type = string 296 default = "IEfewjf2342rfwfwYYfaked" 297 } 298 299 variable "mem_size" { 300 description = "redis instance memory size" 301 type = number 302 default = 1024 303 } 304 305 variable "port" { 306 description = "The port used to access a redis instance." 307 type = number 308 default = 6379 309 } 310 providerRef: 311 name: tencent 312 namespace: default 313 workload: 314 definition: 315 apiVersion: terraform.core.oam.dev/v1beta2 316 kind: Configuration 317 status: {} 318 `, 319 }, 320 { 321 name: "print in a file", 322 args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "xxx", "--git", "https://github.com/kubevela-contrib/terraform-modules.git", "--path", "alibaba/vswitch", "--output", defVswitchFileName}, 323 output: defVswitchFileName, 324 want: `apiVersion: core.oam.dev/v1beta1 325 kind: ComponentDefinition 326 metadata: 327 annotations: 328 definition.oam.dev/description: xxx 329 creationTimestamp: null 330 labels: 331 type: terraform 332 name: alibaba-vswitch 333 namespace: vela-system 334 spec: 335 schematic: 336 terraform: 337 configuration: https://github.com/kubevela-contrib/terraform-modules.git 338 path: alibaba/vswitch 339 type: remote 340 workload: 341 definition: 342 apiVersion: terraform.core.oam.dev/v1beta2 343 kind: Configuration 344 status: {}`, 345 }, 346 { 347 name: "not supported component", 348 args: []string{"vswitch", "-t", "trait", "--provider", "alibaba"}, 349 errMsg: "provider is only valid when the type of the definition is component", 350 }, 351 { 352 name: "not supported cloud provider", 353 args: []string{"vswitch", "-t", "component", "--provider", "xxx"}, 354 errMsg: "Provider `xxx` is not supported.", 355 }, 356 { 357 name: "git is not right", 358 args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "test", "--git", "xxx"}, 359 errMsg: "invalid git url", 360 }, 361 { 362 name: "git and local could be set at the same time", 363 args: []string{"vswitch", "-t", "component", "--provider", "alibaba", "--desc", "test", "--git", "xxx", "--local", "yyy"}, 364 errMsg: "only one of --git and --local can be set", 365 }, 366 { 367 name: "local file doesn't exist", 368 args: []string{"vswitch", "-t", "component", "--provider", "tencent", "--desc", "xxx", "--local", "test-data/redis2.tf"}, 369 errMsg: "failed to read Terraform configuration from file", 370 }, 371 } 372 373 for _, tc := range testcases { 374 t.Run(tc.name, func(t *testing.T) { 375 c := initArgs() 376 cmd := NewDefinitionInitCommand(c) 377 initCommand(cmd) 378 cmd.SetArgs(tc.args) 379 err := cmd.Execute() 380 if err != nil && !strings.Contains(err.Error(), tc.errMsg) { 381 t.Fatalf("unexpected error when executing init command: %v", err) 382 } else if tc.want != "" { 383 data, err := os.ReadFile(tc.output) 384 defer os.Remove(tc.output) 385 assert.Nil(t, err) 386 if !strings.Contains(string(data), tc.want) { 387 t.Fatalf("unexpected output: %s", string(data)) 388 } 389 } 390 }) 391 } 392 } 393 394 func TestNewDefinitionGetCommand(t *testing.T) { 395 c := initArgs() 396 397 // normal test 398 cmd := NewDefinitionGetCommand(c) 399 initCommand(cmd) 400 traitName := createTrait(c, t) 401 cmd.SetArgs([]string{traitName, "-n" + VelaTestNamespace}) 402 if err := cmd.Execute(); err != nil { 403 t.Fatalf("unexpeced error when executing get command: %v", err) 404 } 405 // test multi trait 406 cmd = NewDefinitionGetCommand(c) 407 initCommand(cmd) 408 createNamespacedTrait(c, traitName, "default", "", t) 409 cmd.SetArgs([]string{traitName}) 410 if err := cmd.Execute(); err == nil { 411 t.Fatalf("expect found multiple traits error, but not found") 412 } 413 // test no trait 414 cmd = NewDefinitionGetCommand(c) 415 initCommand(cmd) 416 cmd.SetArgs([]string{traitName + "s"}) 417 if err := cmd.Execute(); err == nil { 418 t.Fatalf("expect found no trait error, but not found") 419 } 420 421 // Load test DefinitionRevisions files into client 422 dir := filepath.Join("..", "..", "pkg", "definition", "testdata") 423 testFiles, err := os.ReadDir(dir) 424 assert.NoError(t, err, "read testdata failed") 425 for _, file := range testFiles { 426 if !strings.HasSuffix(file.Name(), ".yaml") { 427 continue 428 } 429 content, err := os.ReadFile(filepath.Join(dir, file.Name())) 430 assert.NoError(t, err) 431 def := &v1beta1.DefinitionRevision{} 432 err = yaml.Unmarshal(content, def) 433 assert.NoError(t, err) 434 client, err := c.GetClient() 435 assert.NoError(t, err) 436 err = client.Create(context.TODO(), def) 437 assert.NoError(t, err, "cannot create "+file.Name()) 438 } 439 440 // test get revision list 441 cmd = NewDefinitionGetCommand(c) 442 initCommand(cmd) 443 cmd.SetArgs([]string{"webservice", "--revisions", "--namespace=rev-test-ns"}) 444 err = cmd.Execute() 445 assert.NoError(t, err) 446 447 // test get a non-existent revision 448 cmd = NewDefinitionGetCommand(c) 449 initCommand(cmd) 450 cmd.SetArgs([]string{"webservice", "--revision=3"}) 451 err = cmd.Execute() 452 assert.NotNil(t, err, "should have not found error") 453 454 // test get a revision 455 cmd = NewDefinitionGetCommand(c) 456 initCommand(cmd) 457 cmd.SetArgs([]string{"webservice", "--revision=1", "--namespace=rev-test-ns"}) 458 err = cmd.Execute() 459 assert.NoError(t, err) 460 } 461 462 func TestNewDefinitionDocGenCommand(t *testing.T) { 463 c := initArgs() 464 cmd := NewDefinitionDocGenCommand(c, util.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) 465 assert.NotNil(t, cmd.Execute()) 466 467 cmd.SetArgs([]string{"alibaba-xxxxxxx"}) 468 assert.NotNil(t, cmd.Execute()) 469 } 470 471 func TestNewDefinitionListCommand(t *testing.T) { 472 c := initArgs() 473 // normal test 474 cmd := NewDefinitionListCommand(c) 475 initCommand(cmd) 476 _ = createTrait(c, t) 477 cmd.SetArgs([]string{}) 478 if err := cmd.Execute(); err != nil { 479 t.Fatalf("unexpeced error when executing list command: %v", err) 480 } 481 // test no trait 482 cmd = NewDefinitionListCommand(c) 483 initCommand(cmd) 484 cmd.SetArgs([]string{"--namespace", "default"}) 485 if err := cmd.Execute(); err != nil { 486 t.Fatalf("no trait found should not return error, err: %v", err) 487 } 488 // with addon filter 489 cmd = NewDefinitionListCommand(c) 490 initCommand(cmd) 491 cmd.SetArgs([]string{"--from", "non-existent-addon"}) 492 if err := cmd.Execute(); err != nil { 493 t.Fatalf("applying addon filter should not return error, err: %v", err) 494 } 495 } 496 497 func TestNewDefinitionEditCommand(t *testing.T) { 498 c := initArgs() 499 // normal test 500 cmd := NewDefinitionEditCommand(c) 501 initCommand(cmd) 502 traitName := createTrait(c, t) 503 if err := os.Setenv("EDITOR", "sed -i -e 's/test-trait/TestTrait/g'"); err != nil { 504 t.Fatalf("failed to set editor env: %v", err) 505 } 506 cmd.SetArgs([]string{traitName, "-n", VelaTestNamespace}) 507 if err := cmd.Execute(); err != nil { 508 t.Fatalf("unexpeced error when executing edit command: %v", err) 509 } 510 // test no change 511 cmd = NewDefinitionEditCommand(c) 512 initCommand(cmd) 513 createNamespacedTrait(c, traitName, "default", "", t) 514 if err := os.Setenv("EDITOR", "sed -i -e 's/test-trait-test/TestTrait/g'"); err != nil { 515 t.Fatalf("failed to set editor env: %v", err) 516 } 517 cmd.SetArgs([]string{traitName, "-n", "default"}) 518 if err := cmd.Execute(); err != nil { 519 t.Fatalf("unexpeced error when executing edit command: %v", err) 520 } 521 } 522 523 func TestNewDefinitionRenderCommand(t *testing.T) { 524 c := initArgs() 525 // normal test 526 cmd := NewDefinitionRenderCommand(c) 527 initCommand(cmd) 528 _ = os.Setenv(HelmChartFormatEnvName, "true") 529 _, traitFilename := createLocalTrait(t) 530 defer removeFile(traitFilename, t) 531 cmd.SetArgs([]string{traitFilename}) 532 if err := cmd.Execute(); err != nil { 533 t.Fatalf("unexpeced error when executing redner command: %v", err) 534 } 535 // directory read/write test 536 _ = os.Setenv(HelmChartFormatEnvName, "system") 537 dirname := createLocalTraits(t) 538 defer removeDir(dirname, t) 539 outputDir, err := os.MkdirTemp(os.TempDir(), "vela-def-tests-output-*") 540 if err != nil { 541 t.Fatalf("failed to create temporary output dir: %v", err) 542 } 543 defer removeDir(outputDir, t) 544 cmd = NewDefinitionRenderCommand(c) 545 initCommand(cmd) 546 cmd.SetArgs([]string{dirname, "-o", outputDir, "--message", "Author: KubeVela"}) 547 if err := cmd.Execute(); err != nil { 548 t.Fatalf("unexpeced error when executing render command: %v", err) 549 } 550 // directory read/print test 551 _ = os.WriteFile(filepath.Join(dirname, "temp.json"), []byte("hello"), 0600) 552 _ = os.WriteFile(filepath.Join(dirname, "temp.cue"), []byte("hello"), 0600) 553 cmd = NewDefinitionRenderCommand(c) 554 initCommand(cmd) 555 cmd.SetArgs([]string{dirname}) 556 if err := cmd.Execute(); err != nil { 557 t.Fatalf("unexpeced error when executing render command: %v", err) 558 } 559 } 560 561 func TestNewDefinitionApplyCommand(t *testing.T) { 562 c := initArgs() 563 ioStreams := util.IOStreams{In: os.Stdin, Out: bytes.NewBuffer(nil), ErrOut: bytes.NewBuffer(nil)} 564 // dry-run test 565 cmd := NewDefinitionApplyCommand(c, ioStreams) 566 initCommand(cmd) 567 _, traitFilename := createLocalTrait(t) 568 defer removeFile(traitFilename, t) 569 cmd.SetArgs([]string{traitFilename, "--dry-run"}) 570 if err := cmd.Execute(); err != nil { 571 t.Fatalf("unexpeced error when executing apply command: %v", err) 572 } 573 // normal test and reapply 574 cmd = NewDefinitionApplyCommand(c, ioStreams) 575 initCommand(cmd) 576 cmd.SetArgs([]string{traitFilename}) 577 for i := 0; i < 2; i++ { 578 if err := cmd.Execute(); err != nil { 579 t.Fatalf("unexpeced error when executing apply command: %v", err) 580 } 581 } 582 } 583 584 func TestNewDefinitionDelCommand(t *testing.T) { 585 c := initArgs() 586 cmd := NewDefinitionDelCommand(c) 587 initCommand(cmd) 588 traitName := createTrait(c, t) 589 reader := strings.NewReader("yes\n") 590 cmd.SetIn(reader) 591 cmd.SetArgs([]string{traitName, "-n", VelaTestNamespace}) 592 if err := cmd.Execute(); err != nil { 593 t.Fatalf("unexpeced error when executing del command: %v", err) 594 } 595 obj := &v1beta1.TraitDefinition{} 596 client, err := c.GetClient() 597 if err != nil { 598 t.Fatalf("failed to get client: %v", err) 599 } 600 if err := client.Get(context.Background(), types.NamespacedName{ 601 Namespace: VelaTestNamespace, 602 Name: traitName, 603 }, obj); !errors.IsNotFound(err) { 604 t.Fatalf("should not found target definition %s, err: %v", traitName, err) 605 } 606 if err := cmd.Execute(); err == nil { 607 t.Fatalf("should encounter not found error, but no error found") 608 } 609 } 610 611 func TestNewDefinitionVetCommand(t *testing.T) { 612 c := initArgs() 613 cmd := NewDefinitionValidateCommand(c) 614 initCommand(cmd) 615 _, traitFilename := createLocalTrait(t) 616 _, traitFilename2 := createLocalTrait(t) 617 _, traitFilename3 := createLocalTrait(t) 618 defer removeFile(traitFilename, t) 619 cmd.SetArgs([]string{traitFilename}) 620 if err := cmd.Execute(); err != nil { 621 t.Fatalf("unexpeced error when executing vet command: %v", err) 622 } 623 cmd.SetArgs([]string{traitFilename, traitFilename2, traitFilename3}) 624 if err := cmd.Execute(); err != nil { 625 t.Fatalf("unexpeced error when executing vet command: %v", err) 626 } 627 bs, err := os.ReadFile(traitFilename) 628 if err != nil { 629 t.Fatalf("failed to read trait file %s: %v", traitFilename, err) 630 } 631 bs = []byte(string(bs) + "abc:{xa}") 632 if err = os.WriteFile(traitFilename, bs, 0600); err != nil { 633 t.Fatalf("failed to modify trait file %s: %v", traitFilename, err) 634 } 635 if err = cmd.Execute(); err == nil { 636 t.Fatalf("expect validation failed but error not found") 637 } 638 cmd.SetArgs([]string{traitFilename, traitFilename2, traitFilename3}) 639 if err = cmd.Execute(); err == nil { 640 t.Fatalf("expect validation failed but error not found") 641 } 642 cmd.SetArgs([]string{"./test-data/defvet"}) 643 if err = cmd.Execute(); err != nil { 644 t.Fatalf("unexpeced error when executing vet command: %v", err) 645 } 646 } 647 648 func TestNewDefinitionGenAPICommand(t *testing.T) { 649 c := initArgs() 650 cmd := NewDefinitionGenAPICommand(c) 651 initCommand(cmd) 652 internalDefPath := "../../vela-templates/definitions/internal/" 653 654 cmd.SetArgs([]string{"-f", internalDefPath, "-o", "../vela-sdk-gen", "--init", "--verbose"}) 655 if err := cmd.Execute(); err != nil { 656 t.Fatalf("unexpeced error when executing genapi command: %v", err) 657 } 658 } 659 660 // re-use the provider testdata 661 const providerTestDataPath = "../cuegen/generators/provider/testdata" 662 663 func TestNewDefinitionGenCUECommand(t *testing.T) { 664 c := initArgs() 665 got := bytes.NewBuffer(nil) 666 cmd := NewDefinitionGenCUECommand(c, util.IOStreams{Out: got}) 667 initCommand(cmd) 668 669 cmd.SetArgs([]string{ 670 "-t", genTypeProvider, 671 "--types", "*k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.Unstructured=ellipsis", 672 "--types", "*k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.UnstructuredList=ellipsis", 673 filepath.Join(providerTestDataPath, "valid.go"), 674 }) 675 676 require.NoError(t, cmd.Execute()) 677 678 expected, err := os.ReadFile(filepath.Join(providerTestDataPath, "valid.cue")) 679 require.NoError(t, err) 680 681 assert.Equal(t, string(expected), got.String()) 682 } 683 684 func TestNewDefinitionGenDocCommand(t *testing.T) { 685 c := initArgs() 686 got := bytes.NewBuffer(nil) 687 cmd := NewDefinitionGenDocCommand(c, util.IOStreams{Out: got}) 688 initCommand(cmd) 689 690 cmd.SetArgs([]string{ 691 "-t", genTypeProvider, 692 filepath.Join(providerTestDataPath, "valid.cue"), 693 }) 694 695 require.NoError(t, cmd.Execute()) 696 697 expected, err := os.ReadFile(filepath.Join(providerTestDataPath, "valid.md")) 698 require.NoError(t, err) 699 700 assert.Equal(t, string(expected), got.String()) 701 }