mirror of
https://github.com/kubevela/kubevela.git
synced 2026-05-20 16:23:24 +00:00
535 lines
8.9 KiB
Go
535 lines
8.9 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 sets
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"cuelang.org/go/cue"
|
|
"github.com/bmizerany/assert"
|
|
)
|
|
|
|
func TestPatch(t *testing.T) {
|
|
|
|
testCase := []struct {
|
|
base string
|
|
patch string
|
|
result string
|
|
}{
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
|
patch: `containers: [{name: "x1"},{name: "x2",image: "pause:0.1"}]`,
|
|
result: `containers: [{
|
|
name: "x1"
|
|
}, {
|
|
name: "x2"
|
|
image: "pause:0.1"
|
|
}]
|
|
`,
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
|
patch: `containers: [{name: "x2"},{name: "x1"}]`,
|
|
result: "_|_\n",
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: _|_},{name: "x2"},...]`,
|
|
patch: `containers: [{name: _|_},{name: "x2"}]`,
|
|
result: "_|_\n",
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x2"},{name: "x1"}]`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "x1"
|
|
}, {
|
|
name: "x2"
|
|
}, ...]
|
|
`,
|
|
},
|
|
|
|
{
|
|
base: `containers: [close({namex: "x1"}),...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x2"},{name: "x1"}]`,
|
|
result: "_|_\n",
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x4"},{name: "x3"},{name: "x1"}]`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "x1"
|
|
}, {
|
|
name: "x2"
|
|
}, {
|
|
name: "x4"
|
|
}, {
|
|
name: "x3"
|
|
}, ...]
|
|
`,
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{noname: "x3"},{name: "x1"}]`,
|
|
result: "_|_\n",
|
|
},
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2", envs:[ {name: "OPS",value: string},...]},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x2", envs: [{name: "OPS", value: "OAM"}]}]`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "x1"
|
|
}, {
|
|
name: "x2"
|
|
envs: [{
|
|
name: "OPS"
|
|
value: "OAM"
|
|
}, ...]
|
|
}, ...]
|
|
`,
|
|
},
|
|
{
|
|
base: `containers: [close({name: "x1"}),close({name: "x2", envs:[{name: "OPS",value: string},...]}),...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x2", envs: [close({name: "OPS", value: "OAM"})]}]`,
|
|
result: `// +patchKey=name
|
|
containers: [close({
|
|
name: "x1"
|
|
}), close({
|
|
name: "x2"
|
|
envs: [close({
|
|
name: "OPS"
|
|
value: "OAM"
|
|
}), ...]
|
|
}), ...]
|
|
`,
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2", envs:[ {name: "OPS",value: string},...]},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x2", envs: [{name: "USER", value: "DEV"},{name: "OPS", value: "OAM"}]}]`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "x1"
|
|
}, {
|
|
name: "x2"
|
|
envs: [{
|
|
name: "OPS"
|
|
value: "OAM"
|
|
}, {
|
|
name: "USER"
|
|
value: "DEV"
|
|
}, ...]
|
|
}, ...]
|
|
`,
|
|
},
|
|
|
|
{
|
|
base: `containers: [{name: "x1"},{name: "x2", envs:[ {key: "OPS",value: string},...]},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{name: "x2",
|
|
// +patchKey=key
|
|
envs: [{key: "USER", value: "DEV"},{key: "OPS", value: "OAM"}]}]`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "x1"
|
|
}, {
|
|
name: "x2"
|
|
// +patchKey=key
|
|
envs: [{
|
|
key: "OPS"
|
|
value: "OAM"
|
|
}, {
|
|
key: "USER"
|
|
value: "DEV"
|
|
}, ...]
|
|
}, ...]
|
|
`,
|
|
},
|
|
{
|
|
base: `envFrom: [{
|
|
secretRef: {
|
|
name: "nginx-rds"
|
|
}},...]`,
|
|
patch: `
|
|
// +patchKey=secretRef.name
|
|
envFrom: [{
|
|
secretRef: {
|
|
name: "nginx-redis"
|
|
}},...]
|
|
`,
|
|
result: `// +patchKey=secretRef.name
|
|
envFrom: [{
|
|
secretRef: {
|
|
name: "nginx-rds"
|
|
}
|
|
}, {
|
|
secretRef: {
|
|
name: "nginx-redis"
|
|
}
|
|
}, ...]
|
|
`},
|
|
{
|
|
base: `
|
|
containers: [{
|
|
name: "c1"
|
|
},{
|
|
name: "c2"
|
|
envFrom: [{
|
|
secretRef: {
|
|
name: "nginx-rds"
|
|
}},...]
|
|
},...]`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{
|
|
name: "c2"
|
|
// +patchKey=secretRef.name
|
|
envFrom: [{
|
|
secretRef: {
|
|
name: "nginx-redis"
|
|
}},...]
|
|
}]`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "c1"
|
|
}, {
|
|
name: "c2"
|
|
// +patchKey=secretRef.name
|
|
envFrom: [{
|
|
secretRef: {
|
|
name: "nginx-rds"
|
|
}
|
|
}, {
|
|
secretRef: {
|
|
name: "nginx-redis"
|
|
}
|
|
}, ...]
|
|
}, ...]
|
|
`},
|
|
|
|
{
|
|
base: `
|
|
containers: [{
|
|
volumeMounts: [{name: "k1", path: "p1"},{name: "k1", path: "p2"},...]
|
|
},...]
|
|
volumes: [{name: "x1",value: "v1"},{name: "x2",value: "v2"},...]
|
|
`,
|
|
|
|
patch: `
|
|
// +patchKey=name
|
|
volumes: [{name: "x1",value: "v1"},{name: "x3",value: "x2"}]
|
|
|
|
containers: [{
|
|
volumeMounts: [{name: "k1", path: "p1"},{name: "k1", path: "p2"},{ name:"k2", path: "p3"}]
|
|
},...]`,
|
|
result: `containers: [{
|
|
volumeMounts: [{
|
|
path: "p1"
|
|
name: "k1"
|
|
}, {
|
|
path: "p2"
|
|
name: "k1"
|
|
}, {
|
|
path: "p3"
|
|
name: "k2"
|
|
}]
|
|
}, ...]
|
|
// +patchKey=name
|
|
volumes: [{
|
|
name: "x1"
|
|
value: "v1"
|
|
}, {
|
|
name: "x2"
|
|
value: "v2"
|
|
}, {
|
|
name: "x3"
|
|
value: "x2"
|
|
}, ...]
|
|
`},
|
|
}
|
|
|
|
for i, tcase := range testCase {
|
|
v, _ := StrategyUnify(tcase.base, tcase.patch)
|
|
assert.Equal(t, v, tcase.result, fmt.Sprintf("testPatch for case(no:%d) %s", i, v))
|
|
}
|
|
}
|
|
|
|
func TestStrategyPatch(t *testing.T) {
|
|
testCase := []struct {
|
|
base string
|
|
patch string
|
|
result string
|
|
}{
|
|
{
|
|
base: `
|
|
spec: {
|
|
strategy: {
|
|
type: "rollingUpdate"
|
|
rollingUpdate: maxSurge: "30%"
|
|
}
|
|
}
|
|
`,
|
|
patch: `
|
|
spec: {
|
|
// +patchStrategy=retainKeys
|
|
strategy: type: "recreate"
|
|
}
|
|
`,
|
|
result: `spec: {
|
|
strategy: {
|
|
// +patchStrategy=retainKeys
|
|
type: "recreate"
|
|
}
|
|
}
|
|
`},
|
|
|
|
{
|
|
base: `
|
|
spec: {
|
|
strategy: close({
|
|
type: "rollingUpdate"
|
|
rollingUpdate: maxSurge: "30%"
|
|
})
|
|
}
|
|
`,
|
|
patch: `
|
|
spec: {
|
|
// +patchStrategy=retainKeys
|
|
strategy: type: "recreate"
|
|
}
|
|
`,
|
|
result: `spec: {
|
|
strategy: {
|
|
// +patchStrategy=retainKeys
|
|
type: "recreate"
|
|
}
|
|
}
|
|
`},
|
|
|
|
{
|
|
base: `
|
|
volumes: [{
|
|
name: "test-volume"
|
|
cinder: {
|
|
volumeID: "<volume id>"
|
|
fsType: "ext4"
|
|
}
|
|
}]
|
|
`,
|
|
patch: `
|
|
// +patchStrategy=retainKeys
|
|
// +patchKey=name
|
|
volumes: [
|
|
{
|
|
name: "test-volume"
|
|
configMap: name: "conf-name"
|
|
}]
|
|
`,
|
|
result: `// +patchStrategy=retainKeys
|
|
// +patchKey=name
|
|
volumes: [{
|
|
name: "test-volume"
|
|
configMap: {
|
|
name: "conf-name"
|
|
}
|
|
}]
|
|
`},
|
|
|
|
{
|
|
base: `
|
|
volumes: [{
|
|
name: "empty-volume"
|
|
emptyDir: {}
|
|
},
|
|
{
|
|
name: "test-volume"
|
|
cinder: {
|
|
volumeID: "<volume id>"
|
|
fsType: "ext4"
|
|
}
|
|
}]
|
|
`,
|
|
patch: `
|
|
// +patchStrategy=retainKeys
|
|
// +patchKey=name
|
|
volumes: [
|
|
{
|
|
name: "test-volume"
|
|
configMap: name: "conf-name"
|
|
}]
|
|
`,
|
|
result: `// +patchStrategy=retainKeys
|
|
// +patchKey=name
|
|
volumes: [{
|
|
name: "empty-volume"
|
|
emptyDir: {}
|
|
}, {
|
|
name: "test-volume"
|
|
configMap: {
|
|
name: "conf-name"
|
|
}
|
|
}]
|
|
`},
|
|
|
|
{
|
|
base: `
|
|
containers: [{
|
|
name: "c1"
|
|
image: "image1"
|
|
},
|
|
{
|
|
name: "c2"
|
|
envs:[{name: "e1",value: "v1"}]
|
|
}]
|
|
`,
|
|
patch: `
|
|
// +patchKey=name
|
|
containers: [{
|
|
name: "c2"
|
|
// +patchStrategy=retainKeys
|
|
envs:[{name: "e1",value: "v2"},...]
|
|
}]
|
|
`,
|
|
result: `// +patchKey=name
|
|
containers: [{
|
|
name: "c1"
|
|
image: "image1"
|
|
}, {
|
|
name: "c2"
|
|
// +patchStrategy=retainKeys
|
|
envs: [{
|
|
name: "e1"
|
|
value: "v2"
|
|
}]
|
|
}]
|
|
`},
|
|
|
|
{
|
|
base: `
|
|
spec: containers: [{
|
|
name: "c1"
|
|
image: "image1"
|
|
},
|
|
{
|
|
name: "c2"
|
|
envs:[{name: "e1",value: "v1"}]
|
|
}]
|
|
`,
|
|
patch: `
|
|
// +patchKey=name
|
|
// +patchStrategy=retainKeys
|
|
spec: {
|
|
containers: [{
|
|
name: "c2"
|
|
envs:[{name: "e1",value: "v2"}]
|
|
}]}
|
|
`,
|
|
result: `// +patchKey=name
|
|
// +patchStrategy=retainKeys
|
|
spec: {
|
|
containers: [{
|
|
name: "c2"
|
|
envs: [{
|
|
name: "e1"
|
|
value: "v2"
|
|
}, ...]
|
|
}, ...]
|
|
}
|
|
`}, {
|
|
base: `
|
|
kind: "Old"
|
|
metadata: {
|
|
name: "Old"
|
|
labels: keep: "true"
|
|
}
|
|
`,
|
|
patch: `// +patchStrategy=retainKeys
|
|
kind: "New"
|
|
metadata: {
|
|
// +patchStrategy=retainKeys
|
|
name: "New"
|
|
}
|
|
`,
|
|
result: ` // +patchStrategy=retainKeys
|
|
kind: "New"
|
|
metadata: {
|
|
// +patchStrategy=retainKeys
|
|
name: "New"
|
|
labels: {
|
|
keep: "true"
|
|
}
|
|
}
|
|
`},
|
|
}
|
|
|
|
for i, tcase := range testCase {
|
|
v, _ := StrategyUnify(tcase.base, tcase.patch)
|
|
assert.Equal(t, v, tcase.result, fmt.Sprintf("testPatch for case(no:%d) %s", i, v))
|
|
}
|
|
}
|
|
|
|
func TestParseCommentTags(t *testing.T) {
|
|
temp := `
|
|
// +patchKey=name
|
|
// +testKey1=testValue1
|
|
// +testKey2=testValue2
|
|
// +testKey3 =testValue3
|
|
// +testKey4 = testValue4
|
|
// invalid=x
|
|
// +invalid=x y
|
|
// +invalid
|
|
x: null
|
|
`
|
|
|
|
var r cue.Runtime
|
|
inst, err := r.Compile("-", temp)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
ms := findCommentTag(inst.Lookup("x").Doc())
|
|
assert.Equal(t, ms, map[string]string{
|
|
"patchKey": "name",
|
|
"testKey1": "testValue1",
|
|
"testKey2": "testValue2",
|
|
"testKey3": "testValue3",
|
|
"testKey4": "testValue4",
|
|
})
|
|
}
|