mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
* Chore: optimize the package dependces Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: the code style Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: remove the repetitive context Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: change the context key Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: Optimize the e2e test case Signed-off-by: barnettZQG <barnett.zqg@gmail.com> --------- Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
404 lines
13 KiB
Go
404 lines
13 KiB
Go
/*
|
|
Copyright 2021 The KubeVela Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/getkin/kin-openapi/openapi3"
|
|
"github.com/google/go-cmp/cmp"
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
"github.com/stretchr/testify/assert"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"sigs.k8s.io/yaml"
|
|
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
|
"github.com/oam-dev/kubevela/apis/types"
|
|
v1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
|
|
"github.com/oam-dev/kubevela/pkg/oam/util"
|
|
"github.com/oam-dev/kubevela/pkg/utils/schema"
|
|
)
|
|
|
|
var _ = Describe("Test namespace service functions", func() {
|
|
var (
|
|
definitionService *definitionServiceImpl
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
definitionService = &definitionServiceImpl{KubeClient: k8sClient}
|
|
err := k8sClient.Create(context.Background(), &corev1.Namespace{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "vela-system",
|
|
},
|
|
})
|
|
Expect(err).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
|
})
|
|
It("Test ListDefinitions function", func() {
|
|
By("List component definitions")
|
|
webserver, err := os.ReadFile("./testdata/webserver-cd.yaml")
|
|
Expect(err).Should(Succeed())
|
|
var cd v1beta1.ComponentDefinition
|
|
err = yaml.Unmarshal(webserver, &cd)
|
|
Expect(err).Should(Succeed())
|
|
err = k8sClient.Create(context.Background(), &cd)
|
|
Expect(err).Should(Succeed())
|
|
|
|
definitions, err := definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "component"})
|
|
Expect(err).Should(BeNil())
|
|
var selectDefinition *v1.DefinitionBase
|
|
for i, definition := range definitions {
|
|
if definition.WorkloadType == "deployments.apps" {
|
|
selectDefinition = definitions[i]
|
|
}
|
|
}
|
|
Expect(selectDefinition).ShouldNot(BeNil())
|
|
Expect(cmp.Diff(selectDefinition.Name, "webservice-test")).Should(BeEmpty())
|
|
Expect(selectDefinition.Description).ShouldNot(BeEmpty())
|
|
Expect(selectDefinition.Alias).Should(Equal("test-alias"))
|
|
|
|
By("List trait definitions")
|
|
myingress, err := os.ReadFile("./testdata/myingress-td.yaml")
|
|
Expect(err).Should(Succeed())
|
|
var td v1beta1.TraitDefinition
|
|
err = yaml.Unmarshal(myingress, &td)
|
|
Expect(err).Should(Succeed())
|
|
err = k8sClient.Create(context.Background(), &td)
|
|
Expect(err).Should(Succeed())
|
|
traits, err := definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "trait"})
|
|
Expect(err).Should(BeNil())
|
|
// there is already a scaler trait definition in the test env
|
|
Expect(cmp.Diff(len(traits), 2)).Should(BeEmpty())
|
|
Expect(cmp.Diff(traits[0].Name, "myingress")).Should(BeEmpty())
|
|
// The OwnAddon field of myingress should not be fluxcd
|
|
Expect(traits[0].OwnerAddon).Should(Equal("fluxcd"))
|
|
Expect(traits[0].Description).ShouldNot(BeEmpty())
|
|
Expect(traits[0].Trait).ShouldNot(BeNil())
|
|
Expect(traits[0].Alias).Should(Equal("test-alias"))
|
|
|
|
By("List workflow step definitions")
|
|
step, err := os.ReadFile("./testdata/applyapplication-sd.yaml")
|
|
Expect(err).Should(Succeed())
|
|
var sd v1beta1.WorkflowStepDefinition
|
|
err = yaml.Unmarshal(step, &sd)
|
|
Expect(err).Should(Succeed())
|
|
err = k8sClient.Create(context.Background(), &sd)
|
|
Expect(err).Should(Succeed())
|
|
|
|
wfstep, err := definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "workflowstep"})
|
|
Expect(err).Should(BeNil())
|
|
// there is already a deploy workflow step definition in the test env
|
|
Expect(cmp.Diff(len(wfstep), 2)).Should(BeEmpty())
|
|
Expect(cmp.Diff(wfstep[0].Name, "apply-application")).Should(BeEmpty())
|
|
Expect(wfstep[0].Description).ShouldNot(BeEmpty())
|
|
Expect(wfstep[0].WorkflowStep.Schematic).ShouldNot(BeNil())
|
|
Expect(wfstep[0].Alias).Should(Equal("test-alias"))
|
|
|
|
wfstep, err = definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "workflowstep", Scope: "WorkflowRun"})
|
|
Expect(err).Should(BeNil())
|
|
// the definition should be filtered
|
|
Expect(cmp.Diff(len(wfstep), 1)).Should(BeEmpty())
|
|
|
|
step, err = os.ReadFile("./testdata/apply-application-hide.yaml")
|
|
Expect(err).Should(Succeed())
|
|
var sd2 v1beta1.WorkflowStepDefinition
|
|
err = yaml.Unmarshal(step, &sd2)
|
|
Expect(err).Should(Succeed())
|
|
err = k8sClient.Create(context.Background(), &sd2)
|
|
Expect(err).Should(Succeed())
|
|
|
|
allstep, err := definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "workflowstep", QueryAll: true})
|
|
Expect(err).Should(BeNil())
|
|
Expect(cmp.Diff(len(allstep), 3)).Should(BeEmpty())
|
|
|
|
By("List policy definitions")
|
|
var policy = v1beta1.PolicyDefinition{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "health",
|
|
Namespace: "vela-system",
|
|
Annotations: map[string]string{
|
|
"definition.oam.dev/description": "this is a policy definition",
|
|
"definition.oam.dev/alias": "test-alias",
|
|
},
|
|
},
|
|
Spec: v1beta1.PolicyDefinitionSpec{
|
|
ManageHealthCheck: true,
|
|
},
|
|
}
|
|
err = k8sClient.Create(context.Background(), &policy)
|
|
Expect(err).Should(Succeed())
|
|
policies, err := definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "policy"})
|
|
Expect(err).Should(BeNil())
|
|
Expect(cmp.Diff(len(policies), 1)).Should(BeEmpty())
|
|
Expect(cmp.Diff(policies[0].Name, "health")).Should(BeEmpty())
|
|
Expect(policies[0].Description).ShouldNot(BeEmpty())
|
|
Expect(policies[0].Policy.ManageHealthCheck).Should(BeTrue())
|
|
Expect(policies[0].Alias).Should(Equal("test-alias"))
|
|
|
|
By("Filtering list by owner addon")
|
|
list, err := definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "trait", OwnerAddon: "non-existent-addon"})
|
|
Expect(err).Should(Succeed())
|
|
// All results should be filtered out
|
|
Expect(list).Should(HaveLen(0))
|
|
|
|
list, err = definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "trait", OwnerAddon: "fluxcd"})
|
|
Expect(err).Should(Succeed())
|
|
// We should see myingress being kept because fluxcd is its owner
|
|
Expect(len(list) >= 1).Should(Equal(true))
|
|
Expect(list[0].Name).Should(Equal("myingress"))
|
|
})
|
|
|
|
It("Test DetailDefinition function", func() {
|
|
|
|
webserver, err := os.ReadFile("./testdata/apply-object.yaml")
|
|
Expect(err).Should(Succeed())
|
|
var cd v1beta1.WorkflowStepDefinition
|
|
err = yaml.Unmarshal(webserver, &cd)
|
|
Expect(err).Should(Succeed())
|
|
Expect(k8sClient.Create(context.Background(), &cd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
|
|
|
cm := &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "workflowstep-schema-apply-object",
|
|
Namespace: "vela-system",
|
|
},
|
|
Data: map[string]string{
|
|
types.OpenapiV3JSONSchema: `{"properties":{"batchPartition":{"title":"batchPartition","type":"integer"},"volumes": {"description":"Specify volume type, options: pvc, configMap, secret, emptyDir","enum":["pvc","configMap","secret","emptyDir"],"title":"volumes","type":"string"}, "rolloutBatches":{"items":{"properties":{"replicas":{"title":"replicas","type":"integer"}},"required":["replicas"],"type":"object"},"title":"rolloutBatches","type":"array"},"targetRevision":{"title":"targetRevision","type":"string"},"targetSize":{"title":"targetSize","type":"integer"}},"required":["targetRevision","targetSize"],"type":"object"}`,
|
|
},
|
|
}
|
|
err = k8sClient.Create(context.Background(), cm)
|
|
Expect(err).Should(Succeed())
|
|
definitionDetail, err := definitionService.DetailDefinition(context.TODO(), "apply-object", "workflowstep")
|
|
Expect(err).Should(Succeed())
|
|
|
|
schemaFromCM := &openapi3.Schema{}
|
|
err = schemaFromCM.UnmarshalJSON([]byte(cm.Data["openapi-v3-json-schema"]))
|
|
Expect(err).Should(Succeed())
|
|
|
|
Expect(definitionDetail.APISchema).Should(Equal(schemaFromCM))
|
|
Expect(definitionDetail.WorkflowStep).ShouldNot(BeNil())
|
|
})
|
|
|
|
It("Test renderDefaultUISchema", func() {
|
|
schema := &v1.DetailDefinitionResponse{}
|
|
data, err := os.ReadFile("./testdata/api-schema.json")
|
|
Expect(err).Should(Succeed())
|
|
err = json.Unmarshal(data, schema)
|
|
Expect(err).Should(Succeed())
|
|
Expect(cmp.Diff(len(schema.APISchema.Required), 3)).Should(BeEmpty())
|
|
uiSchema := renderDefaultUISchema(schema.APISchema)
|
|
Expect(cmp.Diff(len(uiSchema), 12)).Should(BeEmpty())
|
|
})
|
|
|
|
It("Test patchSchema", func() {
|
|
ddr := &v1.DetailDefinitionResponse{}
|
|
data, err := os.ReadFile("./testdata/api-schema.json")
|
|
Expect(err).Should(Succeed())
|
|
err = json.Unmarshal(data, ddr)
|
|
Expect(err).Should(Succeed())
|
|
Expect(cmp.Diff(len(ddr.APISchema.Required), 3)).Should(BeEmpty())
|
|
defaultschema := renderDefaultUISchema(ddr.APISchema)
|
|
|
|
customschema := []*schema.UIParameter{}
|
|
cdata, err := os.ReadFile("./testdata/ui-custom-schema.yaml")
|
|
Expect(err).Should(Succeed())
|
|
err = yaml.Unmarshal(cdata, &customschema)
|
|
Expect(err).Should(Succeed())
|
|
|
|
uiSchema := patchSchema(defaultschema, customschema)
|
|
Expect(cmp.Diff(len(uiSchema), 12)).Should(BeEmpty())
|
|
Expect(cmp.Diff(uiSchema[7].JSONKey, "livenessProbe")).Should(BeEmpty())
|
|
Expect(cmp.Diff(len(uiSchema[7].SubParameters), 8)).Should(BeEmpty())
|
|
})
|
|
|
|
It("Test sortDefaultUISchema", testSortDefaultUISchema)
|
|
|
|
It("Test update ui schema", func() {
|
|
du := &definitionServiceImpl{
|
|
KubeClient: k8sClient,
|
|
}
|
|
cdata, err := os.ReadFile("./testdata/workflowstep-apply-object.yaml")
|
|
Expect(err).Should(Succeed())
|
|
var schema schema.UISchema
|
|
yaml.Unmarshal(cdata, &schema)
|
|
uiSchema, err := du.AddDefinitionUISchema(context.TODO(), "apply-object", "workflowstep", schema)
|
|
Expect(err).Should(Succeed())
|
|
for _, param := range uiSchema {
|
|
if param.JSONKey == "batchPartition" {
|
|
Expect(len(param.Conditions)).Should(Equal(1))
|
|
Expect(param.Validate.Required).Should(Equal(true))
|
|
Expect(param.Sort).Should(Equal(uint(77)))
|
|
}
|
|
}
|
|
})
|
|
|
|
It("Test update status of the definition", func() {
|
|
du := &definitionServiceImpl{
|
|
KubeClient: k8sClient,
|
|
}
|
|
detail, err := du.UpdateDefinitionStatus(context.TODO(), "apply-object", v1.UpdateDefinitionStatusRequest{
|
|
DefinitionType: "workflowstep",
|
|
HiddenInUI: true,
|
|
})
|
|
Expect(err).Should(Succeed())
|
|
Expect(detail.Status).Should(Equal("disable"))
|
|
|
|
detail, err = du.UpdateDefinitionStatus(context.TODO(), "apply-object", v1.UpdateDefinitionStatusRequest{
|
|
DefinitionType: "workflowstep",
|
|
HiddenInUI: false,
|
|
})
|
|
Expect(err).Should(Succeed())
|
|
Expect(detail.Status).Should(Equal("enable"))
|
|
})
|
|
|
|
})
|
|
|
|
func testSortDefaultUISchema() {
|
|
var params = []*schema.UIParameter{
|
|
{
|
|
Label: "P1",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "P1S1"},
|
|
},
|
|
Sort: 100,
|
|
}, {
|
|
Label: "T2",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "T2S1"},
|
|
{Label: "T2S2"},
|
|
{Label: "T2S3"},
|
|
},
|
|
Sort: 100,
|
|
}, {
|
|
Label: "T3",
|
|
Validate: &schema.Validate{
|
|
Required: false,
|
|
},
|
|
Sort: 100,
|
|
}, {
|
|
Label: "P4",
|
|
Validate: &schema.Validate{
|
|
Required: false,
|
|
},
|
|
Sort: 100,
|
|
}, {
|
|
Label: "T5",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "T5S1"},
|
|
{Label: "T5S2"},
|
|
},
|
|
Sort: 100,
|
|
}, {
|
|
Label: "P6",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "P6S1"},
|
|
{Label: "P6S2"},
|
|
{Label: "P6S3"},
|
|
},
|
|
Sort: 100,
|
|
},
|
|
}
|
|
|
|
var expectedParams = []*schema.UIParameter{
|
|
{
|
|
Label: "P1",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "P1S1"},
|
|
},
|
|
Sort: 100,
|
|
}, {
|
|
Label: "T5",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "T5S1"},
|
|
{Label: "T5S2"},
|
|
},
|
|
Sort: 101,
|
|
}, {
|
|
Label: "P6",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "P6S1"},
|
|
{Label: "P6S2"},
|
|
{Label: "P6S3"},
|
|
},
|
|
Sort: 102,
|
|
}, {
|
|
Label: "T2",
|
|
Validate: &schema.Validate{
|
|
Required: true,
|
|
},
|
|
SubParameters: []*schema.UIParameter{
|
|
{Label: "T2S1"},
|
|
{Label: "T2S2"},
|
|
{Label: "T2S3"},
|
|
},
|
|
Sort: 103,
|
|
}, {
|
|
Label: "P4",
|
|
Validate: &schema.Validate{
|
|
Required: false,
|
|
},
|
|
Sort: 104,
|
|
}, {
|
|
Label: "T3",
|
|
Validate: &schema.Validate{
|
|
Required: false,
|
|
},
|
|
Sort: 105,
|
|
},
|
|
}
|
|
|
|
sortDefaultUISchema(params)
|
|
for i, param := range params {
|
|
Expect(param.Label).Should(Equal(expectedParams[i].Label))
|
|
Expect(param.Sort).Should(Equal(expectedParams[i].Sort))
|
|
}
|
|
}
|
|
|
|
func TestDefinitionQueryOption(t *testing.T) {
|
|
assert.Equal(t, DefinitionQueryOption{
|
|
Type: "workflowstep",
|
|
}.String() == DefinitionQueryOption{
|
|
Type: "workflowstep",
|
|
QueryAll: true,
|
|
}.String(), false)
|
|
}
|