Files
kubevela/pkg/policy/envbinding/patch_test.go
2022-01-18 12:58:50 +08:00

571 lines
15 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 envbinding
import (
"testing"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/oam/util"
)
func Test_EnvBindApp_GenerateConfiguredApplication(t *testing.T) {
testCases := map[string]struct {
baseApp *v1beta1.Application
envName string
envPatch v1alpha1.EnvPatch
expectedApp *v1beta1.Application
selector *v1alpha1.EnvSelector
}{
"normal-test": {
baseApp: baseApp,
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []v1alpha1.EnvTraitPatch{{
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "newTestsvc.example.com",
}),
}},
}},
},
expectedApp: &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
"port": 8000,
}),
Traits: []common.ApplicationTrait{{
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "newTestsvc.example.com",
"http": map[string]interface{}{
"/": 8000,
},
}),
}},
}},
},
},
},
"add-component": {
baseApp: baseApp,
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "express-server",
Type: "webservice",
Traits: []v1alpha1.EnvTraitPatch{{
Type: "labels",
Properties: util.Object2RawExtension(map[string]interface{}{
"test": "label",
}),
}},
}, {
Name: "new-server",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
"cmd": []string{"sleep", "1000"},
}),
Traits: []v1alpha1.EnvTraitPatch{{
Type: "labels",
Properties: util.Object2RawExtension(map[string]interface{}{
"test": "label",
}),
}},
}},
},
expectedApp: &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
"port": 8000,
}),
Traits: []common.ApplicationTrait{{
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "testsvc.example.com",
"http": map[string]interface{}{
"/": 8000,
},
}),
}, {
Type: "labels",
Properties: util.Object2RawExtension(map[string]interface{}{
"test": "label",
}),
}},
}, {
Name: "new-server",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
"cmd": []string{"sleep", "1000"},
}),
Traits: []common.ApplicationTrait{{
Type: "labels",
Properties: util.Object2RawExtension(map[string]interface{}{
"test": "label",
}),
}},
}},
},
},
},
"disable-trait": {
baseApp: baseApp,
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "express-server",
Type: "webservice",
Traits: []v1alpha1.EnvTraitPatch{{
Type: "ingress-1-20",
Disable: true,
}},
}},
},
expectedApp: &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
"port": 8000,
}),
Traits: []common.ApplicationTrait{},
}},
},
},
},
"component-selector": {
baseApp: baseApp,
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "new-server",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
}},
},
selector: &v1alpha1.EnvSelector{
Components: []string{"new-server"},
},
expectedApp: &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "new-server",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
}},
},
},
},
"empty-component-selector": {
baseApp: baseApp,
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "new-server",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
}},
},
selector: &v1alpha1.EnvSelector{
Components: []string{},
},
expectedApp: &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{},
},
},
},
"patch-external-revision": {
baseApp: baseApp,
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "express-server",
Type: "webservice",
ExternalRevision: "external-rev",
}},
},
expectedApp: &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
"port": 8000,
}),
ExternalRevision: "external-rev",
Traits: []common.ApplicationTrait{{
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "testsvc.example.com",
"http": map[string]interface{}{
"/": 8000,
},
}),
}},
}},
},
},
},
"patch-all-comp": {
baseApp: &v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a.example.com",
}),
}, {
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a-1-20.example.com",
}),
}},
}, {
Name: "express-worker",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
}},
},
},
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "",
Type: "",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []v1alpha1.EnvTraitPatch{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}},
}},
},
expectedApp: &v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}, {
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a-1-20.example.com",
}),
}},
}, {
Name: "express-worker",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}},
}},
},
},
},
"patch-type-comp": {
baseApp: &v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a.example.com",
}),
}, {
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a-1-20.example.com",
}),
}},
}, {
Name: "express-worker",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
}},
},
},
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []v1alpha1.EnvTraitPatch{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}},
}},
},
expectedApp: &v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}, {
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a-1-20.example.com",
}),
}},
}, {
Name: "express-worker",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
}},
},
},
},
"patch-without-type-specified": {
baseApp: &v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a.example.com",
}),
}, {
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a-1-20.example.com",
}),
}},
}, {
Name: "express-worker",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
}},
},
},
envName: "prod",
envPatch: v1alpha1.EnvPatch{
Components: []v1alpha1.EnvComponentPatch{{
Name: "express-worker",
Type: "",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []v1alpha1.EnvTraitPatch{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}},
}},
},
expectedApp: &v1beta1.Application{
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a.example.com",
}),
}, {
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "a-1-20.example.com",
}),
}},
}, {
Name: "express-worker",
Type: "worker",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "busybox",
}),
Traits: []common.ApplicationTrait{{
Type: "ingress",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "b.example.com",
}),
}},
}},
},
},
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
app, err := PatchApplication(tc.baseApp, &tc.envPatch, tc.selector)
r := require.New(t)
r.NoError(err)
r.Equal(tc.expectedApp, app)
})
}
}
var baseApp = &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1beta1",
Kind: "Application",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{{
Name: "express-server",
Type: "webservice",
Properties: util.Object2RawExtension(map[string]interface{}{
"image": "crccheck/hello-world",
"port": 8000,
}),
Traits: []common.ApplicationTrait{{
Type: "ingress-1-20",
Properties: util.Object2RawExtension(map[string]interface{}{
"domain": "testsvc.example.com",
"http": map[string]interface{}{
"/": 8000,
},
}),
}},
}},
},
}