diff --git a/pkg/cmd/spec/generator_test.go b/pkg/cmd/spec/generator_test.go index a0d14ee22..7f11d31e2 100644 --- a/pkg/cmd/spec/generator_test.go +++ b/pkg/cmd/spec/generator_test.go @@ -1,34 +1,49 @@ package spec import ( + "encoding/json" "os" + "reflect" "testing" + "github.com/bytedance/mockey" "github.com/stretchr/testify/require" + kclgo "kcl-lang.io/kcl-go" + + "kusionstack.io/kusion/pkg/generator" + "kusionstack.io/kusion/pkg/generator/kcl" "kusionstack.io/kusion/pkg/models" + appconfigmodel "kusionstack.io/kusion/pkg/models/appconfiguration" + "kusionstack.io/kusion/pkg/projectstack" ) var ( spec1 = ` -- id: apps/v1:Namespace:default +- id: v1:Namespace:default type: Kubernetes attributes: apiVersion: v1 kind: Namespace metadata: name: default + creationTimestamp: null + spec: {} + status: {} ` - specModle1 = &models.Spec{ + specModel1 = &models.Spec{ Resources: []models.Resource{ { - ID: "apps/v1:Namespace:default", + ID: "v1:Namespace:default", Type: "Kubernetes", Attributes: map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", + "spec": make(map[string]interface{}), + "status": make(map[string]interface{}), "metadata": map[string]interface{}{ - "name": "default", + "name": "default", + "creationTimestamp": nil, }, }, }, @@ -36,14 +51,14 @@ var ( } spec2 = ` -- id: apps/v1:Namespace:default +- id: v1:Namespace:default type: Kubernetes attributes: apiVersion: v1 kind: Namespace metadata: name: default -- id: apps/v1:Namespace:kube-system +- id: v1:Namespace:kube-system type: Kubernetes attributes: apiVersion: v1 @@ -52,10 +67,10 @@ var ( name: kube-system ` - specModle2 = &models.Spec{ + specModel2 = &models.Spec{ Resources: []models.Resource{ { - ID: "apps/v1:Namespace:default", + ID: "v1:Namespace:default", Type: "Kubernetes", Attributes: map[string]interface{}{ "apiVersion": "v1", @@ -66,7 +81,7 @@ var ( }, }, { - ID: "apps/v1:Namespace:kube-system", + ID: "v1:Namespace:kube-system", Type: "Kubernetes", Attributes: map[string]interface{}{ "apiVersion": "v1", @@ -92,13 +107,13 @@ func TestGenerateSpecFromFile(t *testing.T) { name: "test1", path: "kusion_spec.yaml", content: spec1, - want: specModle1, + want: specModel1, }, { name: "test2", path: "kusion_spec.yaml", content: spec2, - want: specModle2, + want: specModel2, }, { name: "test3", @@ -122,3 +137,97 @@ func TestGenerateSpecFromFile(t *testing.T) { }) } } + +func TestGenerateSpec(t *testing.T) { + apc := &appconfigmodel.AppConfiguration{} + var apcMap map[string]interface{} + tmp, _ := json.Marshal(apc) + _ = json.Unmarshal(tmp, &apcMap) + + type args struct { + o *generator.Options + project *projectstack.Project + stack *projectstack.Stack + mocker *mockey.MockBuilder + } + tests := []struct { + name string + args args + want *models.Spec + wantErr bool + }{ + { + name: "nil generator", args: struct { + o *generator.Options + project *projectstack.Project + stack *projectstack.Stack + mocker *mockey.MockBuilder + }{ + o: &generator.Options{}, + project: &projectstack.Project{}, + stack: &projectstack.Stack{}, + mocker: mockey.Mock((*kcl.Generator).GenerateSpec).Return(nil, nil), + }, + want: nil, + }, + { + name: "kcl generator", args: struct { + o *generator.Options + project *projectstack.Project + stack *projectstack.Stack + mocker *mockey.MockBuilder + }{ + o: &generator.Options{}, + project: &projectstack.Project{ + ProjectConfiguration: projectstack.ProjectConfiguration{ + Generator: &projectstack.GeneratorConfig{ + Type: projectstack.KCLGenerator, + }, + }, + }, + stack: &projectstack.Stack{}, + mocker: mockey.Mock((*kcl.Generator).GenerateSpec).Return(nil, nil), + }, + want: nil, + }, + { + name: "app generator", args: struct { + o *generator.Options + project *projectstack.Project + stack *projectstack.Stack + mocker *mockey.MockBuilder + }{ + o: &generator.Options{}, + project: &projectstack.Project{ + ProjectConfiguration: projectstack.ProjectConfiguration{ + Name: "default", + Generator: &projectstack.GeneratorConfig{ + Type: projectstack.AppConfigurationGenerator, + }, + }, + }, + stack: &projectstack.Stack{}, + mocker: mockey.Mock(kcl.Run).Return(&kcl.CompileResult{ + Documents: []kclgo.KCLResult{apcMap}, + }, nil), + }, + want: specModel1, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := tt.args.mocker.Build() + defer m.UnPatch() + + got, err := GenerateSpec(tt.args.o, tt.args.project, tt.args.stack) + if (err != nil) != tt.wantErr { + t.Errorf("GenerateSpec() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GenerateSpec() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/generator/appconfiguration/generators/namespace_generator_test.go b/pkg/generator/appconfiguration/generators/namespace_generator_test.go new file mode 100644 index 000000000..5f9b96806 --- /dev/null +++ b/pkg/generator/appconfiguration/generators/namespace_generator_test.go @@ -0,0 +1,67 @@ +package generators + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "kusionstack.io/kusion/pkg/models" +) + +func Test_namespaceGenerator_Generate(t *testing.T) { + type fields struct { + projectName string + } + type args struct { + spec *models.Spec + } + tests := []struct { + name string + fields fields + args args + want *models.Spec + wantErr bool + }{ + { + name: "namespace", + fields: fields{ + projectName: "fake-project", + }, + args: args{ + spec: &models.Spec{}, + }, + want: &models.Spec{ + Resources: []models.Resource{ + { + ID: "v1:Namespace:fake-project", + Type: "Kubernetes", + Attributes: map[string]interface{}{ + "apiVersion": "v1", + "kind": "Namespace", + "metadata": map[string]interface{}{ + "creationTimestamp": nil, + "name": "fake-project", + }, + "spec": make(map[string]interface{}), + "status": make(map[string]interface{}), + }, + DependsOn: nil, + Extensions: nil, + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &namespaceGenerator{ + projectName: tt.fields.projectName, + } + if err := g.Generate(tt.args.spec); (err != nil) != tt.wantErr { + t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr) + } + require.Equal(t, tt.want, tt.args.spec) + }) + } +}