mirror of https://github.com/kubevela/kubevela.git
480 lines
11 KiB
Go
480 lines
11 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 cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/getkin/kin-openapi/openapi3"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
pkgaddon "github.com/oam-dev/kubevela/pkg/addon"
|
|
"github.com/oam-dev/kubevela/pkg/utils/common"
|
|
"github.com/oam-dev/kubevela/pkg/utils/util"
|
|
)
|
|
|
|
func TestParseMap(t *testing.T) {
|
|
testcase := []struct {
|
|
args []string
|
|
res map[string]interface{}
|
|
nilError bool
|
|
}{
|
|
{
|
|
args: []string{"key1=value1"},
|
|
res: map[string]interface{}{
|
|
"key1": "value1",
|
|
},
|
|
nilError: true,
|
|
},
|
|
{
|
|
args: []string{"dbUrl=mongodb=mgset-58800212"},
|
|
res: map[string]interface{}{
|
|
"dbUrl": "mongodb=mgset-58800212",
|
|
},
|
|
nilError: true,
|
|
},
|
|
{
|
|
args: []string{"imagePullSecrets={a,b,c}"},
|
|
res: map[string]interface{}{
|
|
"imagePullSecrets": []interface{}{
|
|
"a", "b", "c",
|
|
},
|
|
},
|
|
nilError: true,
|
|
},
|
|
{
|
|
args: []string{"image.repo=www.test.com", "image.tag=1.1"},
|
|
res: map[string]interface{}{
|
|
"image": map[string]interface{}{
|
|
"repo": "www.test.com",
|
|
"tag": "1.1",
|
|
},
|
|
},
|
|
nilError: true,
|
|
},
|
|
{
|
|
args: []string{"local=true"},
|
|
res: map[string]interface{}{
|
|
"local": true,
|
|
},
|
|
nilError: true,
|
|
},
|
|
{
|
|
args: []string{"replicas=3"},
|
|
res: map[string]interface{}{
|
|
"replicas": int64(3),
|
|
},
|
|
nilError: true,
|
|
},
|
|
}
|
|
for _, s := range testcase {
|
|
r, err := parseAddonArgsToMap(s.args)
|
|
if s.nilError {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, s.res, r)
|
|
} else {
|
|
assert.Error(t, err, fmt.Sprintf("%v should be error case", s.args))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAddonEnableCmdWithErrLocalPath(t *testing.T) {
|
|
testcase := []struct {
|
|
args []string
|
|
errMsg string
|
|
}{
|
|
{
|
|
args: []string{"./a_local_path"},
|
|
errMsg: "addon directory ./a_local_path not found in local",
|
|
},
|
|
{
|
|
args: []string{"a_local_path/"},
|
|
errMsg: "addon directory a_local_path/ not found in local",
|
|
},
|
|
}
|
|
|
|
ioStream := util.IOStreams{}
|
|
commandArgs := common.Args{}
|
|
cmd := NewAddonEnableCommand(commandArgs, ioStream)
|
|
|
|
for _, s := range testcase {
|
|
cmd.SetArgs(s.args)
|
|
err := cmd.Execute()
|
|
assert.Error(t, err, s.errMsg)
|
|
}
|
|
}
|
|
|
|
var _ = Describe("Test AddonRegistry Cmd", func() {
|
|
It("Test AddonRegistryAddCmd", func() {
|
|
testAddonRegistryAddCmd()
|
|
})
|
|
})
|
|
|
|
func testAddonRegistryAddCmd() {
|
|
testcase := []struct {
|
|
args []string
|
|
errMsg string
|
|
result *pkgaddon.Registry
|
|
}{
|
|
{
|
|
args: []string{"noAuthRegistry", "--type=helm", "--endpoint=http://127.0.0.1/chartrepo/oam"},
|
|
errMsg: "fail to add no auth addon registry",
|
|
},
|
|
{
|
|
args: []string{"basicAuthRegistry", "--type=helm", "--endpoint=http://127.0.0.1/chartrepo/oam", "--username=hello", "--password=word"},
|
|
errMsg: "fail to add basis auth addon registry",
|
|
},
|
|
{
|
|
args: []string{"skipTlsRegistry", "--type=helm", "--endpoint=https://127.0.0.1/chartrepo/oam", "--insecureSkipTLS=true"},
|
|
},
|
|
}
|
|
|
|
ioStream := util.IOStreams{}
|
|
commandArgs := common.Args{}
|
|
commandArgs.SetClient(k8sClient)
|
|
|
|
cmd := NewAddAddonRegistryCommand(commandArgs, ioStream)
|
|
|
|
for _, s := range testcase {
|
|
cmd.SetArgs(s.args)
|
|
err := cmd.Execute()
|
|
Expect(err).Should(BeNil(), s.errMsg)
|
|
}
|
|
}
|
|
|
|
func TestAddonUpgradeCmdWithErrLocalPath(t *testing.T) {
|
|
testcase := []struct {
|
|
args []string
|
|
errMsg string
|
|
}{
|
|
{
|
|
args: []string{"./a_local_path"},
|
|
errMsg: "addon directory ./a_local_path not found in local",
|
|
},
|
|
{
|
|
args: []string{"a_local_path/"},
|
|
errMsg: "addon directory a_local_path/ not found in local",
|
|
},
|
|
}
|
|
|
|
ioStream := util.IOStreams{}
|
|
commandArgs := common.Args{}
|
|
cmd := NewAddonUpgradeCommand(commandArgs, ioStream)
|
|
|
|
for _, s := range testcase {
|
|
cmd.SetArgs(s.args)
|
|
err := cmd.Execute()
|
|
assert.Error(t, err, s.errMsg)
|
|
}
|
|
}
|
|
|
|
func TestTransCluster(t *testing.T) {
|
|
testcase := []struct {
|
|
str string
|
|
res []string
|
|
}{
|
|
{
|
|
str: "{cluster1, cluster2}",
|
|
res: []string{"cluster1", "cluster2"},
|
|
},
|
|
{
|
|
str: "{cluster1,cluster2}",
|
|
res: []string{"cluster1", "cluster2"},
|
|
},
|
|
{
|
|
str: "{cluster1, cluster2 }",
|
|
res: []string{"cluster1", "cluster2"},
|
|
},
|
|
}
|
|
for _, s := range testcase {
|
|
assert.Equal(t, transClusters(s.str), s.res)
|
|
}
|
|
}
|
|
|
|
func TestGenerateAvailableVersions(t *testing.T) {
|
|
type testcase struct {
|
|
inVersion string
|
|
versions []string
|
|
}
|
|
testcases := []struct {
|
|
c testcase
|
|
res string
|
|
}{
|
|
{
|
|
c: testcase{
|
|
inVersion: "1.2.1",
|
|
versions: []string{"1.2.1"},
|
|
},
|
|
res: fmt.Sprintf("[%s]", color.New(color.Bold, color.FgGreen).Sprintf("1.2.1")),
|
|
},
|
|
{
|
|
c: testcase{
|
|
inVersion: "1.2.1",
|
|
versions: []string{"1.2.3", "1.2.2", "1.2.1"},
|
|
},
|
|
res: fmt.Sprintf("[%s, 1.2.3, 1.2.2]", color.New(color.Bold, color.FgGreen).Sprintf("1.2.1")),
|
|
},
|
|
{
|
|
c: testcase{
|
|
inVersion: "1.2.1",
|
|
versions: []string{"1.2.3", "1.2.2", "1.2.1", "1.2.0"},
|
|
},
|
|
res: fmt.Sprintf("[%s, 1.2.3, 1.2.2, ...]", color.New(color.Bold, color.FgGreen).Sprintf("1.2.1")),
|
|
},
|
|
}
|
|
for _, s := range testcases {
|
|
re := genAvailableVersionInfo(s.c.versions, s.c.inVersion, 3)
|
|
assert.Equal(t, re, s.res)
|
|
}
|
|
}
|
|
|
|
func TestLimitStringLength(t *testing.T) {
|
|
type testcase struct {
|
|
testString string
|
|
lengthLimit int
|
|
}
|
|
|
|
testcases := []struct {
|
|
c testcase
|
|
res string
|
|
}{
|
|
// len = limit
|
|
{
|
|
c: testcase{
|
|
testString: "4444",
|
|
lengthLimit: 4,
|
|
},
|
|
res: "4444",
|
|
},
|
|
// len > limit
|
|
{
|
|
c: testcase{
|
|
testString: "3333",
|
|
lengthLimit: 3,
|
|
},
|
|
res: "333...",
|
|
},
|
|
// len < limit
|
|
{
|
|
c: testcase{
|
|
testString: "22",
|
|
lengthLimit: 3,
|
|
},
|
|
res: "22",
|
|
},
|
|
// limit = 0
|
|
{
|
|
c: testcase{
|
|
testString: "000",
|
|
lengthLimit: 0,
|
|
},
|
|
res: "000",
|
|
},
|
|
// limit < 0
|
|
{
|
|
c: testcase{
|
|
testString: "000",
|
|
lengthLimit: -1,
|
|
},
|
|
res: "000",
|
|
},
|
|
}
|
|
|
|
for _, s := range testcases {
|
|
re := limitStringLength(s.c.testString, s.c.lengthLimit)
|
|
assert.Equal(t, re, s.res)
|
|
}
|
|
}
|
|
|
|
func TestAddonPackageCmdWithInvalidArgs(t *testing.T) {
|
|
testcase := []struct {
|
|
args []string
|
|
msg string
|
|
}{
|
|
{
|
|
args: []string{},
|
|
msg: "must specify addon directory path",
|
|
},
|
|
{
|
|
args: []string{"./a_local_path"},
|
|
msg: "fail to package",
|
|
},
|
|
{
|
|
args: []string{"a_local_path/"},
|
|
msg: "fail to package",
|
|
},
|
|
}
|
|
|
|
commandArgs := common.Args{}
|
|
cmd := NewAddonPackageCommand(commandArgs)
|
|
|
|
for _, s := range testcase {
|
|
cmd.SetArgs(s.args)
|
|
err := cmd.Execute()
|
|
assert.ErrorContains(t, err, s.msg)
|
|
}
|
|
}
|
|
|
|
func TestPackageValidAddon(t *testing.T) {
|
|
commandArgs := common.Args{}
|
|
cmd := NewAddonPackageCommand(commandArgs)
|
|
cmd.SetArgs([]string{"./test-data/addon/sample"})
|
|
err := cmd.Execute()
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
_ = os.RemoveAll("sample-1.0.1.tgz")
|
|
}()
|
|
}
|
|
|
|
func TestGenerateParameterString(t *testing.T) {
|
|
testcase := []struct {
|
|
status pkgaddon.Status
|
|
addonPackage *pkgaddon.WholeAddonPackage
|
|
outputs []string
|
|
}{
|
|
{
|
|
status: pkgaddon.Status{},
|
|
addonPackage: &pkgaddon.WholeAddonPackage{
|
|
APISchema: nil,
|
|
},
|
|
outputs: []string{""},
|
|
},
|
|
{
|
|
status: pkgaddon.Status{
|
|
Parameters: map[string]interface{}{
|
|
"database": "kubevela",
|
|
"dbType": "kubeapi",
|
|
},
|
|
},
|
|
addonPackage: &pkgaddon.WholeAddonPackage{
|
|
APISchema: &openapi3.Schema{
|
|
Required: []string{"dbType", "serviceAccountName", "serviceType", "dex"},
|
|
Properties: openapi3.Schemas{
|
|
"database": &openapi3.SchemaRef{
|
|
Value: &openapi3.Schema{
|
|
Description: "Specify the database name, for the kubeapi db type, it represents namespace.",
|
|
Default: nil,
|
|
},
|
|
},
|
|
"dbURL": &openapi3.SchemaRef{
|
|
Value: &openapi3.Schema{
|
|
Description: "Specify the MongoDB URL. it only enabled where DB type is MongoDB.",
|
|
Default: "abc.com",
|
|
},
|
|
},
|
|
"dbType": &openapi3.SchemaRef{
|
|
Value: &openapi3.Schema{
|
|
Description: "Specify the database type, current support KubeAPI(default) and MongoDB.",
|
|
Enum: []interface{}{"kubeapi", "mongodb"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
outputs: []string{
|
|
// dbType
|
|
color.New(color.FgCyan).Sprintf("-> ") +
|
|
color.New(color.Bold).Sprint("dbType") + ": " +
|
|
"Specify the database type, current support KubeAPI(default) and MongoDB.\n" +
|
|
"\tcurrent value: " + color.New(color.FgGreen).Sprint("\"kubeapi\"\n") +
|
|
"\trequired: " + color.GreenString("✔\n") +
|
|
"\toptions: \"kubeapi\", \"mongodb\"\n",
|
|
// dbURL
|
|
color.New(color.FgCyan).Sprintf("-> ") +
|
|
color.New(color.Bold).Sprint("dbURL") + ": " +
|
|
"Specify the MongoDB URL. it only enabled where DB type is MongoDB.\n" +
|
|
"\tdefault: " + "\"abc.com\"\n",
|
|
// database
|
|
color.New(color.FgCyan).Sprintf("-> ") +
|
|
color.New(color.Bold).Sprint("database") + ": " +
|
|
"Specify the database name, for the kubeapi db type, it represents namespace.\n" +
|
|
"\tcurrent value: " + color.New(color.FgGreen).Sprint("\"kubevela\""),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, s := range testcase {
|
|
res := generateParameterString(s.status, s.addonPackage)
|
|
for _, o := range s.outputs {
|
|
assert.Contains(t, res, o)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func TestNewAddonCreateCommand(t *testing.T) {
|
|
cmd := NewAddonInitCommand()
|
|
cmd.SetArgs([]string{})
|
|
err := cmd.Execute()
|
|
assert.ErrorContains(t, err, "required")
|
|
|
|
cmd.SetArgs([]string{"--chart", "a", "--helm-repo", "https://some.com", "--chart-version", "c"})
|
|
err = cmd.Execute()
|
|
assert.ErrorContains(t, err, "required")
|
|
|
|
cmd.SetArgs([]string{"test-addon", "--chart", "a", "--helm-repo", "https://some.com", "--chart-version", "c"})
|
|
err = cmd.Execute()
|
|
assert.NoError(t, err)
|
|
_ = os.RemoveAll("test-addon")
|
|
|
|
cmd.SetArgs([]string{"test-addon"})
|
|
err = cmd.Execute()
|
|
assert.NoError(t, err)
|
|
_ = os.RemoveAll("test-addon")
|
|
|
|
}
|
|
|
|
func TestCheckSpecifyRegistry(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
registry string
|
|
addonName string
|
|
hasError bool
|
|
}{
|
|
{
|
|
name: "fluxcd",
|
|
registry: "",
|
|
addonName: "fluxcd",
|
|
hasError: false,
|
|
},
|
|
{
|
|
name: "kubevela/fluxcd",
|
|
registry: "kubevela",
|
|
addonName: "fluxcd",
|
|
hasError: false,
|
|
},
|
|
{
|
|
name: "test/kubevela/fluxcd",
|
|
registry: "",
|
|
addonName: "",
|
|
hasError: true,
|
|
},
|
|
}
|
|
for _, testCase := range testCases {
|
|
r, n, err := splitSpecifyRegistry(testCase.name)
|
|
assert.Equal(t, err != nil, testCase.hasError)
|
|
assert.Equal(t, r, testCase.registry)
|
|
assert.Equal(t, n, testCase.addonName)
|
|
}
|
|
}
|