mirror of https://github.com/kubevela/kubevela.git
771 lines
16 KiB
Go
771 lines
16 KiB
Go
/*
|
|
Copyright 2022 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 usecase
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
. "github.com/agiledragon/gomonkey/v2"
|
|
terraformtypes "github.com/oam-dev/terraform-controller/api/types"
|
|
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta1"
|
|
"gotest.tools/assert"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/rest"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
|
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
|
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
|
"github.com/oam-dev/kubevela/apis/types"
|
|
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
|
apis "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
|
"github.com/oam-dev/kubevela/pkg/definition"
|
|
"github.com/oam-dev/kubevela/pkg/multicluster"
|
|
)
|
|
|
|
func TestListConfigTypes(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
def1 := &v1beta1.ComponentDefinition{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "ComponentDefinition",
|
|
APIVersion: "core.oam.dev/v1beta1",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "def1",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Labels: map[string]string{
|
|
definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig,
|
|
definitionType: types.TerraformProvider,
|
|
},
|
|
},
|
|
}
|
|
def2 := &v1beta1.ComponentDefinition{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "ComponentDefinition",
|
|
APIVersion: "core.oam.dev/v1beta1",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "def2",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Annotations: map[string]string{
|
|
definitionAlias: "Def2",
|
|
},
|
|
Labels: map[string]string{
|
|
definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig,
|
|
},
|
|
},
|
|
}
|
|
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(def1, def2).Build()
|
|
|
|
patches := ApplyFunc(multicluster.GetMulticlusterKubernetesClient, func() (client.Client, *rest.Config, error) {
|
|
return k8sClient, nil, nil
|
|
})
|
|
defer patches.Reset()
|
|
|
|
h := NewConfigUseCase(nil)
|
|
|
|
type args struct {
|
|
h ConfigHandler
|
|
}
|
|
|
|
type want struct {
|
|
configTypes []*apis.ConfigType
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
testcases := []struct {
|
|
name string
|
|
args args
|
|
want want
|
|
}{
|
|
{
|
|
name: "success",
|
|
args: args{
|
|
h: h,
|
|
},
|
|
want: want{
|
|
configTypes: []*apis.ConfigType{
|
|
{
|
|
Name: "def2",
|
|
Alias: "Def2",
|
|
Definitions: []string{"def2"},
|
|
},
|
|
{
|
|
Alias: "Terraform Cloud Provider",
|
|
Name: types.TerraformProvider,
|
|
Definitions: []string{
|
|
"def1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got, err := tc.args.h.ListConfigTypes(ctx, "")
|
|
if tc.want.errMsg != "" || err != nil {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
assert.DeepEqual(t, got, tc.want.configTypes)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetConfigType(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
def2 := &v1beta1.ComponentDefinition{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "ComponentDefinition",
|
|
APIVersion: "core.oam.dev/v1beta1",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "def2",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Annotations: map[string]string{
|
|
definitionAlias: "Def2",
|
|
},
|
|
Labels: map[string]string{
|
|
definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig,
|
|
},
|
|
},
|
|
}
|
|
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(def2).Build()
|
|
|
|
patches := ApplyFunc(multicluster.GetMulticlusterKubernetesClient, func() (client.Client, *rest.Config, error) {
|
|
return k8sClient, nil, nil
|
|
})
|
|
defer patches.Reset()
|
|
|
|
h := NewConfigUseCase(nil)
|
|
|
|
type args struct {
|
|
h ConfigHandler
|
|
name string
|
|
}
|
|
|
|
type want struct {
|
|
configType *apis.ConfigType
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
testcases := []struct {
|
|
name string
|
|
args args
|
|
want want
|
|
}{
|
|
{
|
|
name: "success",
|
|
args: args{
|
|
h: h,
|
|
name: "def2",
|
|
},
|
|
want: want{
|
|
configType: &apis.ConfigType{
|
|
Alias: "Def2",
|
|
Name: "def2",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "error",
|
|
args: args{
|
|
h: h,
|
|
name: "def99",
|
|
},
|
|
want: want{
|
|
errMsg: "failed to get config type",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got, err := tc.args.h.GetConfigType(ctx, tc.args.name)
|
|
if tc.want.errMsg != "" || err != nil {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
assert.DeepEqual(t, got, tc.want.configType)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCreateConfig(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
|
|
k8sClient := fake.NewClientBuilder().WithScheme(s).Build()
|
|
|
|
h := &configUseCaseImpl{kubeClient: k8sClient}
|
|
|
|
type args struct {
|
|
h ConfigHandler
|
|
req apis.CreateConfigRequest
|
|
}
|
|
|
|
type want struct {
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
properties, err := json.Marshal(map[string]interface{}{
|
|
"name": "default",
|
|
})
|
|
assert.NilError(t, err)
|
|
|
|
testcases := []struct {
|
|
name string
|
|
args args
|
|
want want
|
|
}{
|
|
{
|
|
name: "delete config when it's not ready",
|
|
args: args{
|
|
h: h,
|
|
req: apis.CreateConfigRequest{
|
|
Name: "a",
|
|
ComponentType: "b",
|
|
Project: "c",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "create terraform-alibaba config",
|
|
args: args{
|
|
h: h,
|
|
req: apis.CreateConfigRequest{
|
|
Name: "n1",
|
|
ComponentType: "terraform-alibaba",
|
|
Project: "p1",
|
|
Properties: string(properties),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := tc.args.h.CreateConfig(ctx, tc.args.req)
|
|
if tc.want.errMsg != "" || err != nil {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetConfigs(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
terraformapi.AddToScheme(s)
|
|
createdTime, _ := time.Parse(time.UnixDate, "Wed Apr 7 11:06:39 PST 2022")
|
|
|
|
provider1 := &terraformapi.Provider{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "provider1",
|
|
Namespace: "default",
|
|
CreationTimestamp: metav1.NewTime(createdTime),
|
|
},
|
|
Status: terraformapi.ProviderStatus{
|
|
State: terraformtypes.ProviderIsReady,
|
|
},
|
|
}
|
|
|
|
provider2 := &terraformapi.Provider{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "provider2",
|
|
Namespace: "default",
|
|
CreationTimestamp: metav1.NewTime(createdTime),
|
|
},
|
|
Status: terraformapi.ProviderStatus{
|
|
State: terraformtypes.ProviderIsNotReady,
|
|
},
|
|
}
|
|
|
|
provider3 := &terraformapi.Provider{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "provider3",
|
|
Namespace: "default",
|
|
},
|
|
}
|
|
|
|
app1 := &v1beta1.Application{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "provider3",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Labels: map[string]string{
|
|
types.LabelConfigType: "terraform-alibaba",
|
|
},
|
|
CreationTimestamp: metav1.NewTime(createdTime),
|
|
},
|
|
Status: common.AppStatus{
|
|
Phase: common.ApplicationRendering,
|
|
},
|
|
}
|
|
|
|
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(provider1, provider2, provider3, app1).Build()
|
|
|
|
h := &configUseCaseImpl{kubeClient: k8sClient}
|
|
|
|
type args struct {
|
|
configType string
|
|
h ConfigHandler
|
|
}
|
|
|
|
type want struct {
|
|
configs []*apis.Config
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
testcases := []struct {
|
|
name string
|
|
args args
|
|
want want
|
|
}{
|
|
{
|
|
name: "success",
|
|
args: args{
|
|
configType: types.TerraformProvider,
|
|
h: h,
|
|
},
|
|
want: want{
|
|
configs: []*apis.Config{
|
|
{
|
|
Name: "provider1",
|
|
CreatedTime: &createdTime,
|
|
Status: "Ready",
|
|
},
|
|
{
|
|
Name: "provider2",
|
|
CreatedTime: &createdTime,
|
|
Status: "Not ready",
|
|
},
|
|
{
|
|
Name: "provider3",
|
|
CreatedTime: &createdTime,
|
|
Status: "Not ready",
|
|
ConfigType: "terraform-alibaba",
|
|
ApplicationStatus: common.ApplicationRendering,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got, err := tc.args.h.GetConfigs(ctx, tc.args.configType)
|
|
if tc.want.errMsg != "" || err != nil {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
assert.DeepEqual(t, got, tc.want.configs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMergeTargets(t *testing.T) {
|
|
currentTargets := []ApplicationDeployTarget{
|
|
{
|
|
Namespace: "n1",
|
|
Clusters: []string{"c1", "c2"},
|
|
}, {
|
|
Namespace: "n2",
|
|
Clusters: []string{"c3"},
|
|
},
|
|
}
|
|
targets := []*model.ClusterTarget{
|
|
{
|
|
Namespace: "n3",
|
|
ClusterName: "c4",
|
|
}, {
|
|
Namespace: "n1",
|
|
ClusterName: "c5",
|
|
},
|
|
{
|
|
Namespace: "n2",
|
|
ClusterName: "c3",
|
|
},
|
|
}
|
|
|
|
expected := []ApplicationDeployTarget{
|
|
{
|
|
Namespace: "n1",
|
|
Clusters: []string{"c1", "c2", "c5"},
|
|
}, {
|
|
Namespace: "n2",
|
|
Clusters: []string{"c3"},
|
|
}, {
|
|
Namespace: "n3",
|
|
Clusters: []string{"c4"},
|
|
},
|
|
}
|
|
|
|
got := mergeTargets(currentTargets, targets)
|
|
|
|
for i, g := range got {
|
|
clusters := g.Clusters
|
|
sort.SliceStable(clusters, func(i, j int) bool {
|
|
return clusters[i] < clusters[j]
|
|
})
|
|
got[i].Clusters = clusters
|
|
}
|
|
assert.DeepEqual(t, expected, got)
|
|
}
|
|
|
|
func TestConvert(t *testing.T) {
|
|
targets := []*model.ClusterTarget{
|
|
{
|
|
Namespace: "n3",
|
|
ClusterName: "c4",
|
|
}, {
|
|
Namespace: "n1",
|
|
ClusterName: "c5",
|
|
},
|
|
{
|
|
Namespace: "n2",
|
|
ClusterName: "c3",
|
|
},
|
|
{
|
|
Namespace: "n3",
|
|
ClusterName: "c5",
|
|
},
|
|
}
|
|
|
|
expected := []ApplicationDeployTarget{
|
|
{
|
|
Namespace: "n3",
|
|
Clusters: []string{"c4", "c5"},
|
|
},
|
|
{
|
|
Namespace: "n1",
|
|
Clusters: []string{"c5"},
|
|
}, {
|
|
Namespace: "n2",
|
|
Clusters: []string{"c3"},
|
|
},
|
|
}
|
|
|
|
got := convertClusterTargets(targets)
|
|
|
|
for i, g := range got {
|
|
clusters := g.Clusters
|
|
sort.SliceStable(clusters, func(i, j int) bool {
|
|
return clusters[i] < clusters[j]
|
|
})
|
|
got[i].Clusters = clusters
|
|
}
|
|
assert.DeepEqual(t, expected, got)
|
|
}
|
|
|
|
func TestDestroySyncConfigsApp(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
app1 := &v1beta1.Application{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "config-sync-p1",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
},
|
|
}
|
|
k8sClient1 := fake.NewClientBuilder().WithScheme(s).WithObjects(app1).Build()
|
|
|
|
k8sClient2 := fake.NewClientBuilder().Build()
|
|
|
|
type args struct {
|
|
project string
|
|
k8sClient client.Client
|
|
}
|
|
|
|
type want struct {
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
testcases := map[string]struct {
|
|
args args
|
|
want want
|
|
}{
|
|
"found": {
|
|
args: args{
|
|
project: "p1",
|
|
k8sClient: k8sClient1,
|
|
},
|
|
},
|
|
"not found": {
|
|
args: args{
|
|
project: "p1",
|
|
k8sClient: k8sClient2,
|
|
},
|
|
want: want{
|
|
errMsg: "no kind is registered for the type v1beta1.Application",
|
|
},
|
|
},
|
|
}
|
|
for name, tc := range testcases {
|
|
t.Run(name, func(t *testing.T) {
|
|
err := destroySyncConfigsApp(ctx, tc.args.k8sClient, tc.args.project)
|
|
if err != nil || tc.want.errMsg != "" {
|
|
if !strings.Contains(err.Error(), tc.want.errMsg) {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSyncConfigs(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
secret1 := &corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "s1",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Labels: map[string]string{
|
|
types.LabelConfigCatalog: types.VelaCoreConfig,
|
|
types.LabelConfigProject: "p1",
|
|
types.LabelConfigSyncToMultiCluster: "true",
|
|
},
|
|
},
|
|
}
|
|
|
|
policies := []ApplicationDeployTarget{{
|
|
Namespace: "n9",
|
|
Clusters: []string{"c19"},
|
|
}}
|
|
properties, _ := json.Marshal(policies)
|
|
app1 := &v1beta1.Application{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "config-sync-p2",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
},
|
|
Spec: v1beta1.ApplicationSpec{
|
|
Policies: []v1beta1.AppPolicy{{
|
|
Name: "c19",
|
|
Type: "topology",
|
|
Properties: &runtime.RawExtension{Raw: properties},
|
|
}},
|
|
},
|
|
}
|
|
|
|
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(secret1, app1).Build()
|
|
|
|
type args struct {
|
|
project string
|
|
targets []*model.ClusterTarget
|
|
}
|
|
|
|
type want struct {
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
testcases := []struct {
|
|
name string
|
|
args args
|
|
want want
|
|
}{
|
|
{
|
|
name: "create",
|
|
args: args{
|
|
project: "p1",
|
|
targets: []*model.ClusterTarget{{
|
|
ClusterName: "c1",
|
|
Namespace: "n1",
|
|
}},
|
|
},
|
|
},
|
|
{
|
|
name: "update",
|
|
args: args{
|
|
project: "p2",
|
|
targets: []*model.ClusterTarget{{
|
|
ClusterName: "c1",
|
|
Namespace: "n1",
|
|
}},
|
|
},
|
|
},
|
|
{
|
|
name: "skip config sync",
|
|
args: args{
|
|
project: "p3",
|
|
targets: []*model.ClusterTarget{{
|
|
ClusterName: "c1",
|
|
Namespace: "n1",
|
|
}},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := SyncConfigs(ctx, k8sClient, tc.args.project, tc.args.targets)
|
|
if tc.want.errMsg != "" || err != nil {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteConfig(t *testing.T) {
|
|
s := runtime.NewScheme()
|
|
v1beta1.AddToScheme(s)
|
|
corev1.AddToScheme(s)
|
|
terraformapi.AddToScheme(s)
|
|
provider1 := &terraformapi.Provider{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "p1",
|
|
Namespace: "default",
|
|
},
|
|
}
|
|
|
|
provider2 := &terraformapi.Provider{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "p2",
|
|
Namespace: "default",
|
|
},
|
|
}
|
|
|
|
provider3 := &terraformapi.Provider{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "p3",
|
|
Namespace: "default",
|
|
},
|
|
}
|
|
|
|
app1 := &v1beta1.Application{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "config-terraform-provider-p1",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Labels: map[string]string{
|
|
types.LabelConfigType: "terraform-alibaba",
|
|
},
|
|
},
|
|
}
|
|
|
|
app2 := &v1beta1.Application{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "p2",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
Labels: map[string]string{
|
|
types.LabelConfigType: "terraform-alibaba",
|
|
},
|
|
},
|
|
}
|
|
|
|
normalApp := &v1beta1.Application{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "a9",
|
|
Namespace: types.DefaultKubeVelaNS,
|
|
},
|
|
}
|
|
|
|
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(provider1, provider2, provider3, app1, app2, normalApp).Build()
|
|
|
|
h := &configUseCaseImpl{kubeClient: k8sClient}
|
|
|
|
type args struct {
|
|
configType string
|
|
name string
|
|
h ConfigHandler
|
|
}
|
|
|
|
type want struct {
|
|
errMsg string
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
testcases := []struct {
|
|
name string
|
|
args args
|
|
want want
|
|
}{
|
|
{
|
|
name: "delete a legacy terraform provider",
|
|
args: args{
|
|
configType: "terraform-alibaba",
|
|
name: "p1",
|
|
h: h,
|
|
},
|
|
want: want{},
|
|
},
|
|
{
|
|
name: "delete a terraform provider",
|
|
args: args{
|
|
configType: "terraform-alibaba",
|
|
name: "p2",
|
|
h: h,
|
|
},
|
|
want: want{},
|
|
},
|
|
{
|
|
name: "delete a terraform provider, but its application not found",
|
|
args: args{
|
|
configType: "terraform-alibaba",
|
|
name: "p3",
|
|
h: h,
|
|
},
|
|
want: want{
|
|
errMsg: "could not be disabled because it was created by enabling a Terraform provider or was manually created",
|
|
},
|
|
},
|
|
{
|
|
name: "delete a normal config, but failed",
|
|
args: args{
|
|
configType: "config-image-registry",
|
|
name: "a10",
|
|
h: h,
|
|
},
|
|
want: want{
|
|
errMsg: "not found",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := tc.args.h.DeleteConfig(ctx, tc.args.configType, tc.args.name)
|
|
if tc.want.errMsg != "" || err != nil {
|
|
assert.ErrorContains(t, err, tc.want.errMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|