package phases
import (
"context"
"fmt"
"net/http/httptest"
"testing"
"time"
"github.com/agiledragon/gomonkey/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
agentv1beta1 "gopkg.openfuyao.cn/cluster-api-provider-bke/api/bkeagent/v1beta1"
confv1beta1 "gopkg.openfuyao.cn/cluster-api-provider-bke/api/bkecommon/v1beta1"
"gopkg.openfuyao.cn/cluster-api-provider-bke/api/capbke/v1beta1"
bkev1beta1 "gopkg.openfuyao.cn/cluster-api-provider-bke/api/capbke/v1beta1"
bkeaddon "gopkg.openfuyao.cn/cluster-api-provider-bke/common/cluster/addon"
bkenode "gopkg.openfuyao.cn/cluster-api-provider-bke/common/cluster/node"
"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/certs"
"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/command"
"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/kube"
"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/mergecluster"
"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/phaseframe"
"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/phaseframe/phaseutil"
"gopkg.openfuyao.cn/cluster-api-provider-bke/testutils"
"gopkg.openfuyao.cn/cluster-api-provider-bke/utils/bkeagent/pkiutil"
"gopkg.openfuyao.cn/cluster-api-provider-bke/utils/capbke/clusterutil"
"gopkg.openfuyao.cn/cluster-api-provider-bke/utils/capbke/constant"
"gopkg.openfuyao.cn/cluster-api-provider-bke/utils/capbke/label"
"gopkg.openfuyao.cn/cluster-api-provider-bke/utils/capbke/nodeutil"
bkelog "gopkg.openfuyao.cn/cluster-api-provider-bke/utils/log"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/record"
v1beta12 "sigs.k8s.io/cluster-api/api/v1beta1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
ctrlfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
)
var initCxt = context.Background()
var initNewBkeCluster v1beta1.BKECluster
var initOldBkeCluster v1beta1.BKECluster
var initCluster v1beta12.Cluster
var initPhaseContext *phaseframe.PhaseContext
var initLog *v1beta1.BKELogger
var initClient *testutils.BocloudFakeManager
var initScheme *runtime.Scheme
var initRestConfig *rest.Config
var initTServer *httptest.Server
func initNewBkeClusterFun() {
initNewBkeCluster = v1beta1.BKECluster{
ObjectMeta: metav1.ObjectMeta{
Name: "bkecluster",
Namespace: "kube-system",
Annotations: map[string]string{},
UID: "newxasdfawefraqwerqwer",
OwnerReferences: []metav1.OwnerReference{
{Kind: "Cluster", Name: initCluster.Name,
APIVersion: fmt.Sprintf("%s/%s", v1beta1.GroupVersion.Group, v1beta1.GroupVersion.Version),
},
},
},
Spec: confv1beta1.BKEClusterSpec{
ControlPlaneEndpoint: confv1beta1.APIEndpoint{Host: "127.0.0.1", Port: 6443},
ClusterConfig: &confv1beta1.BKEConfig{
Cluster: confv1beta1.Cluster{
ImageRepo: confv1beta1.Repo{Domain: "deploy.bocloud.k8s", Port: "40443", Prefix: "kubernetes"},
KubernetesVersion: "v1.29.2",
OpenFuyaoVersion: "v2.1.0",
},
Addons: nil, CustomExtra: nil,
},
},
Status: confv1beta1.BKEClusterStatus{
ClusterStatus: v1beta1.ClusterDeleting,
PhaseStatus: confv1beta1.PhaseStatus{{Status: v1beta1.PhaseSucceeded}},
KubernetesVersion: "v1.24.1",
},
}
}
func initOldBkeClusterFun() {
initOldBkeCluster = v1beta1.BKECluster{
ObjectMeta: metav1.ObjectMeta{
Name: "bkecluster",
Namespace: "kube-system",
UID: "oldxasdfawefraqwerqwer",
OwnerReferences: []metav1.OwnerReference{
{
Kind: "Cluster",
Name: initCluster.Name,
APIVersion: fmt.Sprintf("%s/%s", v1beta12.GroupVersion.Group, v1beta12.GroupVersion.Version),
},
},
},
Spec: confv1beta1.BKEClusterSpec{
ClusterConfig: &confv1beta1.BKEConfig{
Cluster: confv1beta1.Cluster{
ImageRepo: confv1beta1.Repo{
Domain: "deploy.bocloud.k8s",
Port: "40443",
Prefix: "kubernetes",
},
KubernetesVersion: "v1.24.17",
},
},
},
}
}
func initClusterFun() {
initCluster = v1beta12.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: "bkecluster", Namespace: "kube-system",
UID: "xasdfawefraqwerqwer",
},
Status: v1beta12.ClusterStatus{
Phase: string(v1beta12.ClusterPhaseFailed),
Conditions: v1beta12.Conditions{{Type: v1beta12.ControlPlaneInitializedCondition, Status: corev1.ConditionTrue}},
},
}
}
func InitinitPhaseContextFun() {
GenClient()
initLog = &v1beta1.BKELogger{
Recorder: record.NewBroadcaster().NewRecorder(initScheme,
corev1.EventSource{Component: "ensure"},
),
NormalLogger: testutils.NewLog(),
EventBinder: &initNewBkeCluster,
}
initPhaseContext = &phaseframe.PhaseContext{
BKECluster: &initNewBkeCluster,
Scheme: initScheme,
Cluster: &initCluster,
Context: context.Background(),
Log: initLog,
}
if initClient != nil {
initPhaseContext.Client = initClient.GetClient()
initPhaseContext.RestConfig = initClient.GetConfig()
}
}
func GenClient() {
initNewBkeClusterFun()
initOldBkeClusterFun()
initClusterFun()
command := initCommand()
nodes := initNodes()
kubeConfigSecret := initKubeconfigSecret()
localKubeconfigSecret := kubeConfigSecret.DeepCopy()
localKubeconfigSecret.SetName(constant.LocalKubeConfigName)
localKubeconfigSecret.SetNamespace(metav1.NamespaceSystem)
initClient, initScheme = testutils.TestGetManagerClient([]func(*runtime.Scheme) error{corev1.AddToScheme,
v1beta1.AddToScheme, v1beta12.AddToScheme, agentv1beta1.AddToScheme},
&initOldBkeCluster, &initCluster, kubeConfigSecret, nodes, localKubeconfigSecret, command)
}
func initKubeconfigSecret() *corev1.Secret {
if initTServer != nil {
initTServer.Close()
}
initRestConfig, initTServer = testutils.TestGetK8sServerHttp(nil)
rconfigBytes, _ := testutils.RestConfigToKubeConfig(initRestConfig, "asdf")
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-kubeconfig", initCluster.Name),
Namespace: initCluster.Namespace,
},
Data: map[string][]byte{
"value": rconfigBytes,
},
}
return &secret
}
func initNodes() *corev1.Node {
return &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: "node1",
Labels: map[string]string{
corev1.LabelHostname: "", label.NodeRoleMasterLabel: "",
},
},
Status: corev1.NodeStatus{
NodeInfo: corev1.NodeSystemInfo{
KernelVersion: "v1.29.1",
},
Addresses: []corev1.NodeAddress{
{Address: "127.0.0.1"},
},
Conditions: []corev1.NodeCondition{{Type: corev1.NodeReady, Status: corev1.ConditionTrue}},
},
}
}
func initCommand() *agentv1beta1.Command {
return &agentv1beta1.Command{
ObjectMeta: metav1.ObjectMeta{
Name: command.K8sEnvCommandName,
Namespace: initCluster.Namespace,
Labels: map[string]string{
corev1.LabelHostname: "",
label.NodeRoleMasterLabel: "",
},
},
}
}
func TestEnsureAddonDeploy(t *testing.T) {
InitinitPhaseContextFun()
t.Run("EnsureAddonDeploy", func(t *testing.T) {
pp := NewEnsureAddonDeploy(initPhaseContext)
if _, err := pp.Execute(); err != nil {
t.Log(err)
}
deepBkeCluster := initNewBkeCluster.DeepCopy()
pp.NeedExecute(&initOldBkeCluster, deepBkeCluster)
if initPhaseContext != nil {
initPhaseContext.Cluster = nil
}
pp = NewEnsureAddonDeploy(initPhaseContext)
pp.NeedExecute(&initOldBkeCluster, deepBkeCluster)
deepBkeCluster.DeletionTimestamp = &metav1.Time{Time: time.Now()}
pp.NeedExecute(&initOldBkeCluster, deepBkeCluster)
})
}
func newLocalAndPatchCMs(version string) (*corev1.ConfigMap, *corev1.ConfigMap) {
bkeCMKey := "patch." + version
patchCMKey := "cm." + version
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "bke-config",
Namespace: "cluster-system",
},
Data: map[string]string{
bkeCMKey: patchCMKey,
},
}
patchCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: patchCMKey,
Namespace: "openfuyao-patch",
},
Data: map[string]string{
version: "new-patch-content",
},
}
return localCM, patchCM
}
func TestEnsureAddonDeployDistributePatchCMFailGetLocalCM(t *testing.T) {
InitinitPhaseContextFun()
if initClient == nil {
t.Fatal("initClient is nil")
}
fakeClient := initClient.GetClient()
version := "v2.1.0"
patchCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: "openfuyao-patch",
Name: fmt.Sprintf("cm.%s", version),
},
Data: map[string]string{version: "new-patch-content"},
}
require.NoError(t, fakeClient.Create(context.Background(), patchCM))
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok, "NewEnsureAddonDeploy should return *EnsureAddonDeploy")
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
err := pp.distributePatchCM()
require.Error(t, err)
assert.Contains(t, err.Error(), "get cm failed")
}
func TestEnsureAddonDeployDistributePatchCMFailGetPatchCM(t *testing.T) {
InitinitPhaseContextFun()
version := "v2.1.0"
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: "cluster-system",
Name: "bke-config",
},
Data: map[string]string{fmt.Sprintf("patch.%s", version): "some-data"},
}
if initClient == nil {
t.Fatal("initClient is nil")
}
fakeClient := initClient.GetClient()
require.NoError(t, fakeClient.Create(context.Background(), localCM))
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok, "NewEnsureAddonDeploy should return *EnsureAddonDeploy")
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
err := pp.distributePatchCM()
require.Error(t, err)
assert.Contains(t, err.Error(), "get patch cm failed")
}
func TestEnsureAddonDeployDistributePatchCMSSuccessCreate(t *testing.T) {
InitinitPhaseContextFun()
version := "v2.1.0"
localCM, patchCM := newLocalAndPatchCMs(version)
if initClient == nil {
t.Fatal("initClient is nil")
}
fakeClient := initClient.GetClient()
require.NoError(t, fakeClient.Create(context.Background(), localCM))
require.NoError(t, fakeClient.Create(context.Background(), patchCM))
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok, "NewEnsureAddonDeploy should return *EnsureAddonDeploy")
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
err := pp.distributePatchCM()
require.NoError(t, err)
remoteCM, err := fakeRemoteClient.CoreV1().ConfigMaps(constant.OpenFuyaoSystemController).Get(
context.Background(),
"patch-config",
metav1.GetOptions{},
)
require.NoError(t, err)
assert.Equal(t, "new-patch-content", remoteCM.Data["patch-data"])
}
func TestEnsureAddonDeployDistributePatchCMSuccessUpdate(t *testing.T) {
InitinitPhaseContextFun()
version := "v2.1.0"
localCM, patchCM := newLocalAndPatchCMs(version)
if initClient == nil {
t.Fatal("initClient is nil")
}
fakeClient := initClient.GetClient()
require.NoError(t, fakeClient.Create(context.Background(), localCM))
require.NoError(t, fakeClient.Create(context.Background(), patchCM))
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
existingCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "patch-config",
Namespace: constant.OpenFuyaoSystemController,
},
Data: map[string]string{
"patch-data": "old-content",
},
}
_, err := fakeRemoteClient.CoreV1().ConfigMaps(constant.OpenFuyaoSystemController).Create(
context.Background(),
existingCM,
metav1.CreateOptions{},
)
require.NoError(t, err)
err = pp.distributePatchCM()
require.NoError(t, err)
remoteCM, err := fakeRemoteClient.CoreV1().ConfigMaps(constant.OpenFuyaoSystemController).Get(
context.Background(),
"patch-config",
metav1.GetOptions{},
)
require.NoError(t, err)
assert.Equal(t, "new-patch-content", remoteCM.Data["patch-data"])
}
func TestCreateCommandSpec(t *testing.T) {
commands := []agentv1beta1.ExecCommand{
{ID: "1", Command: []string{"echo", "test"}},
{ID: "2", Command: []string{"ls", "-la"}},
}
spec := createCommandSpec(commands)
assert.NotNil(t, spec)
assert.Len(t, spec.Commands, 2)
assert.Equal(t, []string{"echo", "test"}, spec.Commands[0].Command)
}
func TestValidateAndPrepare_NoContinue(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
result := pp.validateAndPrepare(ValidateAndPrepareParams{Ctx: initPhaseContext})
assert.False(t, result.Continue)
}
func TestGetClient_Success(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
client := pp.getClient()
assert.NotNil(t, client)
}
func TestGetClient_Nil(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
pp.mockClient = nil
pp.remoteClient = nil
client := pp.getClient()
assert.Nil(t, client)
}
func TestValidateAndPrepareResult_Structure(t *testing.T) {
result := ValidateAndPrepareResult{
AddonsT: []*bkeaddon.AddonTransfer{},
BKECluster: &v1beta1.BKECluster{},
Continue: true,
}
assert.NotNil(t, result.BKECluster)
assert.True(t, result.Continue)
assert.Empty(t, result.AddonsT)
}
func TestAddonBeforeCreateCustomOperate_Default(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "unknown-addon"}
err := pp.addonBeforeCreateCustomOperate(addon)
assert.NoError(t, err)
}
func TestProcessAddonParams_Structure(t *testing.T) {
params := ProcessAddonParams{
AddonT: &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test"},
},
BKECluster: &v1beta1.BKECluster{},
}
assert.NotNil(t, params.AddonT)
assert.NotNil(t, params.BKECluster)
assert.Equal(t, "test", params.AddonT.Addon.Name)
}
func TestUpdateAddonStatusParams_Structure(t *testing.T) {
params := UpdateAddonStatusParams{
AddonT: &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test"},
},
NewestBKECluster: &v1beta1.BKECluster{},
}
assert.NotNil(t, params.AddonT)
assert.NotNil(t, params.NewestBKECluster)
}
func TestProcessAddonResult_Structure(t *testing.T) {
result := ProcessAddonResult{
NewestBKECluster: &v1beta1.BKECluster{},
Continue: true,
Error: nil,
}
assert.NotNil(t, result.NewestBKECluster)
assert.True(t, result.Continue)
assert.NoError(t, result.Error)
}
func TestEnsureAddonDeploy_Structure(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
assert.NotNil(t, pp)
assert.NotNil(t, pp.BasePhase)
}
func TestProcessAddon_CreateAddon(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestUpdateAddonStatus_RemoveAddon(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestUpdateAddonStatus_CreateAddon(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestHandleEtcdBackup_Error(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{
Name: "etcdbackup",
Param: map[string]string{"backupDir": "/tmp/etcd-backup"},
}
err := pp.handleEtcdBackup(addon)
assert.Error(t, err)
}
func TestHandleBeyondELB_EmptyConfig(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
err := pp.handleBeyondELB()
assert.NoError(t, err)
}
func TestHandleClusterAPI_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateChartRefToBKECluster_NoChartAddons(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
err := pp.createChartRefToBKECluster()
assert.NoError(t, err)
}
func TestCreateChartAddonCMRefToBKECluster_NilRef(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := confv1beta1.Product{
Name: "test-addon",
ValuesConfigMapRef: nil,
}
err := pp.createChartAddonCMRefToBKECluster(addon)
assert.NoError(t, err)
}
func TestCreateChartRepoSecretRefToBKECluster_NoSecrets(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
err := pp.createChartRepoSecretRefToBKECluster()
assert.NoError(t, err)
}
func TestHandleGPUManager_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestAddControlPlaneLabels_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestHandleOpenFuyaoSystemController_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateEtcdBackupDir_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateEtcdCertSecret_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateBeyondELBVIP_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestLabelNodesForELB_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateClusterAPILocalkubeconfigSecret_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateClusterAPILeastPrivilegeKubeConfigSecret_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateClusterAPIBkeconfigCm_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestCreateClusterAPIPatchconfigCm_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestMarkBKEAgentSwitchPending_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestReCreateKubeSchedulerStaticPodYaml_Error(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestDownloadCalicoCtl_Error(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "prepareDownloadCalicoCtlParams", func(_ *EnsureAddonDeploy, _ string) PrepareDownloadCalicoCtlParamsResult {
return PrepareDownloadCalicoCtlParamsResult{
Ctx: context.Background(),
Client: initClient.GetClient(),
BKECluster: &initNewBkeCluster,
Scheme: initScheme,
Log: initLog,
CalicoCtlUrl: "http://example.com/calicoctl",
}
})
patches.ApplyPrivateMethod(pp, "createDownloadCommand", func(_ *EnsureAddonDeploy, _ CreateDownloadCommandParams) CreateDownloadCommandResult {
return CreateDownloadCommandResult{
DownloadCommand: command.Custom{},
}
})
patches.ApplyPrivateMethod(pp, "executeDownloadCommand", func(_ *EnsureAddonDeploy, _ ExecuteDownloadCommandParams) ExecuteDownloadCommandResult {
return ExecuteDownloadCommandResult{
Error: fmt.Errorf("download failed"),
}
})
err := pp.downloadCalicoCtl("v3.26.0")
assert.Error(t, err)
}
func TestDownloadCalicoCtl_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "prepareDownloadCalicoCtlParams", func(_ *EnsureAddonDeploy, _ string) PrepareDownloadCalicoCtlParamsResult {
return PrepareDownloadCalicoCtlParamsResult{
Ctx: context.Background(),
Client: initClient.GetClient(),
BKECluster: &initNewBkeCluster,
Scheme: initScheme,
Log: initLog,
CalicoCtlUrl: "http://example.com/calicoctl",
}
})
patches.ApplyPrivateMethod(pp, "createDownloadCommand", func(_ *EnsureAddonDeploy, _ CreateDownloadCommandParams) CreateDownloadCommandResult {
return CreateDownloadCommandResult{
DownloadCommand: command.Custom{},
}
})
patches.ApplyPrivateMethod(pp, "executeDownloadCommand", func(_ *EnsureAddonDeploy, _ ExecuteDownloadCommandParams) ExecuteDownloadCommandResult {
return ExecuteDownloadCommandResult{
Error: nil,
}
})
err := pp.downloadCalicoCtl("v3.26.0")
assert.NoError(t, err)
}
func TestPrepareDownloadCalicoCtlParams(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
result := pp.prepareDownloadCalicoCtlParams("v3.26.0")
assert.NotNil(t, result)
}
func TestCreateDownloadCommand(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
params := CreateDownloadCommandParams{
Ctx: context.Background(),
Client: initClient.GetClient(),
BKECluster: &initNewBkeCluster,
Scheme: initScheme,
CalicoCtlUrl: "http://example.com/calicoctl",
}
result := pp.createDownloadCommand(params)
assert.NotNil(t, result)
}
func TestExecuteDownloadCommand(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
downloadCmd := &command.Custom{}
params := ExecuteDownloadCommandParams{
DownloadCommand: downloadCmd,
Log: initLog,
BKECluster: &initNewBkeCluster,
}
result := pp.executeDownloadCommand(params)
assert.NotNil(t, result)
}
func TestAddonAfterCreateCustomOperate_Calico(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "calico", Version: "v3.26.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
pp.addonAfterCreateCustomOperate(addon, bkeCluster)
}
func TestLabelAndSaveNodes_Empty(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
params := LabelAndSaveNodesParams{
LabelNodes: []corev1.Node{},
Ctx: context.Background(),
Client: nil,
Log: initLog,
}
err := pp.labelAndSaveNodes(params)
assert.NoError(t, err)
}
func TestSaveAddonManifestsPostHook(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
err := pp.saveAddonManifestsPostHook(pp, nil)
assert.NoError(t, err)
}
func TestGenerateCommandsForAddonObjects(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{
Addon: addon,
Operate: bkeaddon.CreateAddon,
}
recorder := kube.NewAddonRecorder(addonT)
params := GenerateCommandsForAddonObjectsParams{
Recorder: recorder,
}
result := pp.generateCommandsForAddonObjects(params)
assert.NotNil(t, result)
assert.Empty(t, result.Commands)
}
func TestAddonBeforeCreateCustomOperate_EtcdBackup(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{
Name: "etcdbackup",
Param: map[string]string{"backupDir": "/tmp/backup"},
}
err := pp.addonBeforeCreateCustomOperate(addon)
assert.Error(t, err)
}
func TestAddonBeforeCreateCustomOperate_BeyondELB(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "beyondELB"}
err := pp.addonBeforeCreateCustomOperate(addon)
assert.NoError(t, err)
}
func TestAddonAfterCreateCustomOperate_Default(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "unknown-addon"}
bkeCluster := initNewBkeCluster.DeepCopy()
pp.addonAfterCreateCustomOperate(addon, bkeCluster)
}
func TestCreateChartAddonCMRefToBKECluster_WithRef(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
addon := confv1beta1.Product{
Name: "test-addon",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "test-cm",
Namespace: "test-ns",
},
}
err := pp.createChartAddonCMRefToBKECluster(addon)
assert.Error(t, err)
}
func TestCreateChartRepoSecretRefToBKECluster_WithAuthSecret(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
initPhaseContext.BKECluster.Spec.ClusterConfig.Cluster.ChartRepo.AuthSecretRef = &confv1beta1.AuthSecretRef{
Name: "auth-secret",
Namespace: "test-ns",
}
err := pp.createChartRepoSecretRefToBKECluster()
assert.Error(t, err)
}
func TestPrepareDownloadCalicoCtlParams_Success(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
result := pp.prepareDownloadCalicoCtlParams("v3.26.0")
assert.NotNil(t, result)
assert.NotNil(t, result.Ctx)
assert.NotNil(t, result.Client)
assert.NotNil(t, result.BKECluster)
assert.NotNil(t, result.Scheme)
assert.NotNil(t, result.Log)
}
func TestCreateDownloadCommand_Success(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
params := CreateDownloadCommandParams{
Ctx: context.Background(),
Client: initClient.GetClient(),
BKECluster: &initNewBkeCluster,
Scheme: initScheme,
CalicoCtlUrl: "http://example.com/calicoctl",
}
result := pp.createDownloadCommand(params)
assert.NotNil(t, result)
}
func TestExecuteDownloadCommand_Success(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
downloadCmd := &command.Custom{}
params := ExecuteDownloadCommandParams{
DownloadCommand: downloadCmd,
Log: initLog,
BKECluster: &initNewBkeCluster,
}
result := pp.executeDownloadCommand(params)
assert.NotNil(t, result)
assert.Error(t, result.Error)
}
func TestSaveAddonManifestsPostHook_WithError(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
err := pp.saveAddonManifestsPostHook(pp, fmt.Errorf("test error"))
assert.NoError(t, err)
}
func TestGenerateCommandsForAddonObjects_WithRecorder(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{
Addon: addon,
Operate: bkeaddon.CreateAddon,
}
recorder := kube.NewAddonRecorder(addonT)
params := GenerateCommandsForAddonObjectsParams{
Recorder: recorder,
}
result := pp.generateCommandsForAddonObjects(params)
assert.NotNil(t, result)
}
func TestReconcileAddon_WithPausedCluster(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.Pause = true
patches.ApplyFunc(bkeaddon.CompareBKEConfigAddon, func(_ []confv1beta1.Product, _ []confv1beta1.Product) ([]*bkeaddon.AddonTransfer, bool) {
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
return []*bkeaddon.AddonTransfer{addonT}, true
})
err := pp.reconcileAddon()
assert.NoError(t, err)
}
func TestReconcileAddon_WithBlockingError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.Pause = false
patches.ApplyFunc(bkeaddon.CompareBKEConfigAddon, func(_ []confv1beta1.Product, _ []confv1beta1.Product) ([]*bkeaddon.AddonTransfer, bool) {
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0", Block: true}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
return []*bkeaddon.AddonTransfer{addonT}, true
})
patches.ApplyPrivateMethod(pp, "processAddon", func(_ *EnsureAddonDeploy, _ ProcessAddonParams) ProcessAddonResult {
return ProcessAddonResult{Error: fmt.Errorf("blocking error"), Continue: false}
})
err := pp.reconcileAddon()
assert.Error(t, err)
}
func TestExecute_Success(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestExecute_RemoteClientError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(kube.NewRemoteClientByBKECluster, func(_ context.Context, _ client.Client, _ *v1beta1.BKECluster) (kube.RemoteKubeClient, error) {
return nil, fmt.Errorf("failed to create remote client")
})
result, err := pp.Execute()
assert.Error(t, err)
assert.Equal(t, ctrl.Result{}, result)
}
func TestExecute_ReconcileError(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestNeedExecute_WithAddons(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
oldCluster := initOldBkeCluster.DeepCopy()
newCluster := initNewBkeCluster.DeepCopy()
newCluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{Name: "test-addon", Version: "v1.0.0"},
}
result := pp.NeedExecute(oldCluster, newCluster)
assert.False(t, result)
}
func TestNeedExecute_NoAddons(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
oldCluster := initOldBkeCluster.DeepCopy()
newCluster := initNewBkeCluster.DeepCopy()
newCluster.Spec.ClusterConfig.Addons = nil
patches.ApplyMethod(initPhaseContext, "GetBKENodes", func(_ *phaseframe.PhaseContext) (v1beta1.BKENodes, error) {
return v1beta1.BKENodes{}, nil
})
result := pp.NeedExecute(oldCluster, newCluster)
assert.False(t, result)
}
func TestValidateAndPrepare_WithAddons(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(bkeaddon.CompareBKEConfigAddon, func(_ []confv1beta1.Product, _ []confv1beta1.Product) ([]*bkeaddon.AddonTransfer, bool) {
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
return []*bkeaddon.AddonTransfer{addonT}, true
})
params := ValidateAndPrepareParams{Ctx: initPhaseContext}
result := pp.validateAndPrepare(params)
assert.True(t, result.Continue)
assert.NotEmpty(t, result.AddonsT)
}
func TestCreateEtcdBackupDir_WithValidDir(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestHandleEtcdBackup_WithBackupDir(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestHandleBeyondELB_WithVIPAndNodes(t *testing.T) {
t.Skip("Skipping due to complex dependencies")
}
func TestUpdateAddonStatus_RemoveAddon_WithMock(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
bkeCluster.Status.AddonStatus = []confv1beta1.Product{*addon}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.RemoveAddon}
recorder := kube.NewAddonRecorder(addonT)
recorders := []*kube.AddonRecorder{}
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return nil
})
params := UpdateAddonStatusParams{
AddonT: addonT, NewestBKECluster: bkeCluster, AddonRecorder: recorder,
AddonRecorders: &recorders, Client: initClient.GetClient(), Ctx: initPhaseContext, Log: initLog,
}
err := pp.updateAddonStatus(params)
assert.NoError(t, err)
assert.Empty(t, bkeCluster.Status.AddonStatus)
}
func TestUpdateAddonStatus_CreateAddon_WithMock(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
recorder := kube.NewAddonRecorder(addonT)
recorders := []*kube.AddonRecorder{}
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return nil
})
params := UpdateAddonStatusParams{
AddonT: addonT, NewestBKECluster: bkeCluster, AddonRecorder: recorder,
AddonRecorders: &recorders, Client: initClient.GetClient(), Ctx: initPhaseContext, Log: initLog,
}
err := pp.updateAddonStatus(params)
assert.NoError(t, err)
assert.Len(t, bkeCluster.Status.AddonStatus, 1)
assert.Len(t, recorders, 1)
}
func TestUpdateAddonStatus_UpdateAddon_WithMock(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v2.0.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
bkeCluster.Status.AddonStatus = []confv1beta1.Product{{Name: "test-addon", Version: "v1.0.0"}}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.UpdateAddon}
recorder := kube.NewAddonRecorder(addonT)
recorders := []*kube.AddonRecorder{}
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return nil
})
params := UpdateAddonStatusParams{
AddonT: addonT, NewestBKECluster: bkeCluster, AddonRecorder: recorder,
AddonRecorders: &recorders, Client: initClient.GetClient(), Ctx: initPhaseContext, Log: initLog,
}
err := pp.updateAddonStatus(params)
assert.NoError(t, err)
assert.Equal(t, "v2.0.0", bkeCluster.Status.AddonStatus[0].Version)
}
func TestProcessAddon_CreateAddon_WithMock(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestProcessAddon_BlockingError_WithMock(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestProcessAddon_NonBlockingError_WithMock(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestFindMatchingNodes_Success(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestFindMatchingNodes_GetNodesError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return nil, fmt.Errorf("failed to get nodes")
})
params := FindMatchingNodesParams{
LbNodes: []string{"192.168.1.1"},
}
nodes, err := pp.findMatchingNodes(params)
assert.Error(t, err)
assert.Nil(t, nodes)
}
func TestFindMatchingNodes_MatchByHostname(t *testing.T) {
t.Skip("Requires complex mocking of RemoteKubeClient interface")
}
func TestLabelAndSaveNodes_WithNodes(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
params := LabelAndSaveNodesParams{
LabelNodes: []corev1.Node{},
Ctx: context.Background(),
Client: nil,
Log: initLog,
}
err := pp.labelAndSaveNodes(params)
assert.NoError(t, err)
}
func TestProcessAddon_GetNodesError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return nil, fmt.Errorf("failed to get nodes")
})
params := ProcessAddonParams{
AddonT: addonT,
BKECluster: &initNewBkeCluster,
TargetClusterClient: nil,
Client: initClient.GetClient(),
Ctx: initPhaseContext,
Log: initLog,
}
result := pp.processAddon(params)
assert.Error(t, result.Error)
assert.False(t, result.Continue)
}
func TestProcessAddon_BeforeCreateError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "etcdbackup", Version: "v1.0.0", Param: map[string]string{"backupDir": "/tmp"}}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
params := ProcessAddonParams{
AddonT: addonT,
BKECluster: &initNewBkeCluster,
TargetClusterClient: nil,
Client: initClient.GetClient(),
Ctx: initPhaseContext,
Log: initLog,
}
result := pp.processAddon(params)
assert.Error(t, result.Error)
assert.False(t, result.Continue)
}
func TestCreateChartRefToBKECluster_WithChartAddons(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
initPhaseContext.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{
Name: "test-chart",
Version: "v1.0.0",
Type: "chart",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "test-cm",
Namespace: "test-ns",
},
},
}
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cm",
Namespace: "test-ns",
},
Data: map[string]string{
"values": "test-values",
},
}
err := initClient.GetClient().Create(context.Background(), cm)
require.NoError(t, err)
err = pp.createChartRefToBKECluster()
if err != nil {
t.Logf("Expected error: %v", err)
}
}
func TestHandleGPUManager_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
patches.ApplyPrivateMethod(pp, "reCreateKubeSchedulerStaticPodYaml", func(_ *EnsureAddonDeploy) error {
return nil
})
err := pp.handleGPUManager()
assert.NoError(t, err)
}
func TestHandleGPUManager_ErrorDuplicate(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "reCreateKubeSchedulerStaticPodYaml", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to recreate static pod yaml")
})
err := pp.handleGPUManager()
assert.Error(t, err)
}
func TestAddonAfterCreateCustomOperate_Calico_WithVersion(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "calico", Version: "v3.27.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
patches.ApplyPrivateMethod(pp, "downloadCalicoCtl", func(_ *EnsureAddonDeploy, _ string) error {
return nil
})
pp.addonAfterCreateCustomOperate(addon, bkeCluster)
}
func TestReconcileAddon_WithNonBlockingError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.Pause = false
patches.ApplyFunc(bkeaddon.CompareBKEConfigAddon, func(_ []confv1beta1.Product, _ []confv1beta1.Product) ([]*bkeaddon.AddonTransfer, bool) {
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0", Block: false}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
return []*bkeaddon.AddonTransfer{addonT}, true
})
patches.ApplyPrivateMethod(pp, "processAddon", func(_ *EnsureAddonDeploy, _ ProcessAddonParams) ProcessAddonResult {
return ProcessAddonResult{Error: fmt.Errorf("non-blocking error"), Continue: false}
})
err := pp.reconcileAddon()
assert.Error(t, err)
}
func TestGetClient_WithMockClient(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeClient := fake.NewSimpleClientset()
pp.mockClient = fakeClient
client := pp.getClient()
assert.Equal(t, fakeClient, client)
}
func TestGetClient_WithRemoteClient(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
pp.mockClient = nil
pp.remoteClient = nil
cl := pp.getClient()
assert.Nil(t, cl)
}
func TestDistributePatchCM_NoOpenFuyaoVersion(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.ClusterConfig.Cluster.OpenFuyaoVersion = ""
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
err := pp.distributePatchCM()
assert.Error(t, err)
}
func TestHandleOpenFuyaoSystemController_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
patches.ApplyPrivateMethod(pp, "addControlPlaneLabels", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "distributePatchCM", func(_ *EnsureAddonDeploy) error {
return nil
})
err := pp.handleOpenFuyaoSystemController()
assert.NoError(t, err)
}
func TestHandleOpenFuyaoSystemController_DistributePatchCMError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "addControlPlaneLabels", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "distributePatchCM", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to distribute patch cm")
})
err := pp.handleOpenFuyaoSystemController()
assert.Error(t, err)
}
func TestHandleClusterAPI_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPILeastPrivilegeKubeConfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "markBKEAgentSwitchPending", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIBkeconfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIHealthCheckConfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIPatchconfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createChartRefToBKECluster", func(_ *EnsureAddonDeploy) error {
return nil
})
err := pp.handleClusterAPI()
assert.NoError(t, err)
}
func TestHandleClusterAPI_LocalKubeconfigError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to create kubeconfig secret")
})
err := pp.handleClusterAPI()
assert.Error(t, err)
}
func TestHandleClusterAPI_LeastPrivilegeError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPILeastPrivilegeKubeConfigSecret", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to create least privilege kubeconfig")
})
err := pp.handleClusterAPI()
assert.Error(t, err)
}
func TestHandleClusterAPI_MarkBKEAgentError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPILeastPrivilegeKubeConfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "markBKEAgentSwitchPending", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to mark switch pending")
})
err := pp.handleClusterAPI()
assert.Error(t, err)
}
func TestHandleClusterAPI_BkeconfigCmError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPILeastPrivilegeKubeConfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "markBKEAgentSwitchPending", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIBkeconfigCm", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to create bke config cm")
})
err := pp.handleClusterAPI()
assert.Error(t, err)
}
func TestHandleClusterAPI_PatchconfigCmError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPILeastPrivilegeKubeConfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "markBKEAgentSwitchPending", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIBkeconfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIHealthCheckConfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIPatchconfigCm", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to create patch config cm")
})
err := pp.handleClusterAPI()
assert.Error(t, err)
}
func TestHandleClusterAPI_ChartRefError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createClusterAPILocalkubeconfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPILeastPrivilegeKubeConfigSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "markBKEAgentSwitchPending", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIBkeconfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIHealthCheckConfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createClusterAPIPatchconfigCm", func(_ *EnsureAddonDeploy) error {
return nil
})
patches.ApplyPrivateMethod(pp, "createChartRefToBKECluster", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("failed to create chart ref")
})
err := pp.handleClusterAPI()
assert.Error(t, err)
}
func TestMarkBKEAgentSwitchPending_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return nil
})
err := pp.markBKEAgentSwitchPending()
assert.NoError(t, err)
}
func TestMarkBKEAgentSwitchPending_SyncError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return fmt.Errorf("sync error")
})
err := pp.markBKEAgentSwitchPending()
assert.Error(t, err)
}
func TestCreateClusterAPIBkeconfigCm_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GetRemoteBKEConfigCM, func(_ context.Context, _ *kubernetes.Clientset) (*corev1.ConfigMap, error) {
return &corev1.ConfigMap{}, nil
})
err := pp.createClusterAPIBkeconfigCm()
assert.NoError(t, err)
}
func TestCreateClusterAPIBkeconfigCm_NilConfigMigrate(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GetRemoteBKEConfigCM, func(_ context.Context, _ *kubernetes.Clientset) (*corev1.ConfigMap, error) {
return nil, nil
})
patches.ApplyFunc(phaseutil.MigrateBKEConfigCM, func(_ context.Context, _ client.Client, _ *kubernetes.Clientset) error {
return nil
})
err := pp.createClusterAPIBkeconfigCm()
assert.NoError(t, err)
}
func TestCreateClusterAPIBkeconfigCm_GetError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GetRemoteBKEConfigCM, func(_ context.Context, _ *kubernetes.Clientset) (*corev1.ConfigMap, error) {
return nil, fmt.Errorf("get error")
})
err := pp.createClusterAPIBkeconfigCm()
assert.Error(t, err)
}
func TestCreateClusterAPIPatchconfigCm_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.MigratePatchConfigCM, func(_ context.Context, _ client.Client, _ *kubernetes.Clientset) error {
return nil
})
err := pp.createClusterAPIPatchconfigCm()
assert.NoError(t, err)
}
func TestCreateClusterAPIPatchconfigCm_MigrateError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.MigratePatchConfigCM, func(_ context.Context, _ client.Client, _ *kubernetes.Clientset) error {
return fmt.Errorf("migrate error")
})
err := pp.createClusterAPIPatchconfigCm()
assert.Error(t, err)
}
func TestCreateClusterAPILocalkubeconfigSecret_AlreadyExists(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
assert.Panics(t, func() {
_ = pp.createClusterAPILocalkubeconfigSecret()
})
}
func TestCreateClusterAPILocalkubeconfigSecret_NilRemoteClient(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
assert.Panics(t, func() {
_ = pp.createClusterAPILocalkubeconfigSecret()
})
}
func TestCreateClusterAPILeastPrivilegeKubeConfigSecret_AlreadyExists(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GetRemoteLocalKubeConfig, func(_ context.Context, _ *kubernetes.Clientset) ([]byte, error) {
return []byte("remote-config"), nil
})
patches.ApplyFunc(phaseutil.GenerateLowPrivilegeKubeConfig, func(_ context.Context, _ client.Client, _ *v1beta1.BKECluster, _ []byte) ([]byte, error) {
return []byte("low-privilege"), nil
})
assert.Panics(t, func() {
_ = pp.createClusterAPILeastPrivilegeKubeConfigSecret()
})
}
func TestCreateClusterAPILeastPrivilegeKubeConfigSecret_GetRemoteError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GetRemoteLocalKubeConfig, func(_ context.Context, _ *kubernetes.Clientset) ([]byte, error) {
return nil, fmt.Errorf("get remote config error")
})
err := pp.createClusterAPILeastPrivilegeKubeConfigSecret()
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to get localkubeconfig")
}
func TestCreateClusterAPILeastPrivilegeKubeConfigSecret_GenerateError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GetRemoteLocalKubeConfig, func(_ context.Context, _ *kubernetes.Clientset) ([]byte, error) {
return []byte("remote-config"), nil
})
patches.ApplyFunc(phaseutil.GenerateLowPrivilegeKubeConfig, func(_ context.Context, _ client.Client, _ *v1beta1.BKECluster, _ []byte) ([]byte, error) {
return nil, fmt.Errorf("generate error")
})
err := pp.createClusterAPILeastPrivilegeKubeConfigSecret()
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to generate least privilege kubeconfig")
}
func TestCreateEtcdCertSecret_AlreadyExists(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "createEtcdCertSecret", func(_ *EnsureAddonDeploy) error {
return nil
})
err := pp.createEtcdCertSecret()
assert.NoError(t, err)
}
func TestCreateEtcdCertSecret_NilRemoteClient(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
assert.Panics(t, func() {
_ = pp.createEtcdCertSecret()
})
}
func TestLabelNodesForELB_Success(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "findMatchingNodes", func(_ *EnsureAddonDeploy, _ FindMatchingNodesParams) ([]corev1.Node, error) {
return []corev1.Node{}, nil
})
patches.ApplyPrivateMethod(pp, "labelAndSaveNodes", func(_ *EnsureAddonDeploy, _ LabelAndSaveNodesParams) error {
return nil
})
err := pp.labelNodesForELB([]string{"192.168.1.1"})
assert.NoError(t, err)
}
func TestLabelNodesForELB_FindError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "findMatchingNodes", func(_ *EnsureAddonDeploy, _ FindMatchingNodesParams) ([]corev1.Node, error) {
return nil, fmt.Errorf("find error")
})
err := pp.labelNodesForELB([]string{"192.168.1.1"})
assert.Error(t, err)
}
func TestAddonBeforeCreateCustomOperate_OpenFuyaoSystemController(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "handleOpenFuyaoSystemController", func(_ *EnsureAddonDeploy) error {
return nil
})
addon := &confv1beta1.Product{Name: constant.OpenFuyaoSystemController}
err := pp.addonBeforeCreateCustomOperate(addon)
assert.NoError(t, err)
}
func TestAddonBeforeCreateCustomOperate_GPUManager(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "handleGPUManager", func(_ *EnsureAddonDeploy) error {
return nil
})
addon := &confv1beta1.Product{Name: "gpu-manager"}
err := pp.addonBeforeCreateCustomOperate(addon)
assert.NoError(t, err)
}
func TestAddonBeforeCreateCustomOperate_ClusterAPI(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "handleClusterAPI", func(_ *EnsureAddonDeploy) error {
return nil
})
addon := &confv1beta1.Product{Name: "cluster-api"}
err := pp.addonBeforeCreateCustomOperate(addon)
assert.NoError(t, err)
}
func TestAddonAfterCreateCustomOperate_OpenFuyaoSystemController(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GenerateDefaultUserInfo, func(_ dynamic.Interface, _ phaseutil.UserInfoConfig) (string, []byte, error) {
return "admin", []byte("password123"), nil
})
addon := &confv1beta1.Product{Name: constant.OpenFuyaoSystemController}
bkeCluster := initNewBkeCluster.DeepCopy()
pp.addonAfterCreateCustomOperate(addon, bkeCluster)
}
func TestAddonAfterCreateCustomOperate_OpenFuyaoSystemController_Error(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GenerateDefaultUserInfo, func(_ dynamic.Interface, _ phaseutil.UserInfoConfig) (string, []byte, error) {
return "", nil, fmt.Errorf("generate error")
})
addon := &confv1beta1.Product{Name: constant.OpenFuyaoSystemController}
bkeCluster := initNewBkeCluster.DeepCopy()
pp.addonAfterCreateCustomOperate(addon, bkeCluster)
}
func TestAddonAfterCreateCustomOperate_OpenFuyaoSystemController_EmptyPasswd(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyFunc(phaseutil.GenerateDefaultUserInfo, func(_ dynamic.Interface, _ phaseutil.UserInfoConfig) (string, []byte, error) {
return "admin", []byte{}, nil
})
addon := &confv1beta1.Product{Name: constant.OpenFuyaoSystemController}
bkeCluster := initNewBkeCluster.DeepCopy()
pp.addonAfterCreateCustomOperate(addon, bkeCluster)
}
func TestGenerateCommandsForAddonObjects_WithNamespaced(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
recorder := kube.NewAddonRecorder(addonT)
recorder.AddonObjects = append(recorder.AddonObjects, &kube.AddonObject{
Kind: "Deployment",
Name: "test-deploy",
NameSpace: "default",
})
recorder.AddonObjects = append(recorder.AddonObjects, &kube.AddonObject{
Kind: "ClusterRole",
Name: "test-role",
})
params := GenerateCommandsForAddonObjectsParams{Recorder: recorder}
result := pp.generateCommandsForAddonObjects(params)
assert.Len(t, result.Commands, 2)
assert.Contains(t, result.Commands[0].Command[0], "-n default")
assert.NotContains(t, result.Commands[1].Command[0], "-n ")
}
func TestSaveAddonManifestsPostHook_WithRecorders(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
recorder := kube.NewAddonRecorder(addonT)
recorder.AddonObjects = append(recorder.AddonObjects, &kube.AddonObject{
Kind: "Deployment", Name: "test", NameSpace: "default",
})
pp.addonRecorders = []*kube.AddonRecorder{recorder}
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return bkenode.Nodes{}, nil
})
err := pp.saveAddonManifestsPostHook(pp, nil)
assert.NoError(t, err)
}
func TestSaveAddonManifestsPostHook_GetNodesError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
recorder := kube.NewAddonRecorder(addonT)
recorder.AddonObjects = append(recorder.AddonObjects, &kube.AddonObject{
Kind: "Deployment", Name: "test", NameSpace: "default",
})
pp.addonRecorders = []*kube.AddonRecorder{recorder}
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return nil, fmt.Errorf("get nodes error")
})
err := pp.saveAddonManifestsPostHook(pp, nil)
assert.Error(t, err)
}
func TestUpdateAddonStatus_UpgradeAddon_WithMock(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v3.0.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
bkeCluster.Status.AddonStatus = []confv1beta1.Product{{Name: "test-addon", Version: "v2.0.0"}}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.UpgradeAddon}
recorder := kube.NewAddonRecorder(addonT)
recorders := []*kube.AddonRecorder{}
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return nil
})
params := UpdateAddonStatusParams{
AddonT: addonT, NewestBKECluster: bkeCluster, AddonRecorder: recorder,
AddonRecorders: &recorders, Client: initClient.GetClient(), Ctx: initPhaseContext, Log: initLog,
}
err := pp.updateAddonStatus(params)
assert.NoError(t, err)
assert.Equal(t, "v3.0.0", bkeCluster.Status.AddonStatus[0].Version)
}
func TestUpdateAddonStatus_DefaultOperate_WithMock(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: "unknown"}
recorder := kube.NewAddonRecorder(addonT)
recorders := []*kube.AddonRecorder{}
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return nil
})
params := UpdateAddonStatusParams{
AddonT: addonT, NewestBKECluster: bkeCluster, AddonRecorder: recorder,
AddonRecorders: &recorders, Client: initClient.GetClient(), Ctx: initPhaseContext, Log: initLog,
}
err := pp.updateAddonStatus(params)
assert.NoError(t, err)
assert.Len(t, recorders, 1)
}
func TestUpdateAddonStatus_SyncError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
bkeCluster := initNewBkeCluster.DeepCopy()
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
recorder := kube.NewAddonRecorder(addonT)
recorders := []*kube.AddonRecorder{}
patches.ApplyFunc(mergecluster.SyncStatusUntilComplete, func(c any, bkeCluster *v1beta1.BKECluster, patchs ...mergecluster.PatchFunc) error {
return fmt.Errorf("sync error")
})
params := UpdateAddonStatusParams{
AddonT: addonT, NewestBKECluster: bkeCluster, AddonRecorder: recorder,
AddonRecorders: &recorders, Client: initClient.GetClient(), Ctx: initPhaseContext, Log: initLog,
}
err := pp.updateAddonStatus(params)
assert.Error(t, err)
}
func TestReconcileAddon_NoContinue(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
err := pp.reconcileAddon()
assert.NoError(t, err)
}
func TestReconcileAddon_SuccessWithUpdateStatus(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.Pause = false
addon := &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"}
addonT := &bkeaddon.AddonTransfer{Addon: addon, Operate: bkeaddon.CreateAddon}
patches.ApplyFunc(bkeaddon.CompareBKEConfigAddon, func(_ []confv1beta1.Product, _ []confv1beta1.Product) ([]*bkeaddon.AddonTransfer, bool) {
return []*bkeaddon.AddonTransfer{addonT}, true
})
patches.ApplyPrivateMethod(pp, "processAddon", func(_ *EnsureAddonDeploy, _ ProcessAddonParams) ProcessAddonResult {
return ProcessAddonResult{NewestBKECluster: initPhaseContext.BKECluster, Continue: true}
})
patches.ApplyPrivateMethod(pp, "updateAddonStatus", func(_ *EnsureAddonDeploy, _ UpdateAddonStatusParams) error {
return nil
})
err := pp.reconcileAddon()
assert.NoError(t, err)
}
func TestCreateChartAddonCMRefToBKECluster_CreateSuccess(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "values-cm", Namespace: "kube-system"},
Data: map[string]string{"values": "test-data"},
}
require.NoError(t, initClient.GetClient().Create(context.Background(), localCM))
addon := confv1beta1.Product{
Name: "test-addon",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "values-cm",
Namespace: "kube-system",
},
}
err := pp.createChartAddonCMRefToBKECluster(addon)
assert.NoError(t, err)
}
func TestCreateChartAddonCMRefToBKECluster_DefaultNamespace(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "values-cm",
Namespace: initNewBkeCluster.Namespace,
},
Data: map[string]string{"values": "test-data"},
}
require.NoError(t, initClient.GetClient().Create(context.Background(), localCM))
addon := confv1beta1.Product{
Name: "test-addon",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "values-cm",
Namespace: "",
},
}
err := pp.createChartAddonCMRefToBKECluster(addon)
assert.NoError(t, err)
}
func TestCreateChartRepoSecretRefToBKECluster_WithTlsSecret(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
tlsSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "tls-secret", Namespace: "kube-system"},
Data: map[string][]byte{"tls": []byte("cert-data")},
}
require.NoError(t, initClient.GetClient().Create(context.Background(), tlsSecret))
initPhaseContext.BKECluster.Spec.ClusterConfig.Cluster.ChartRepo.AuthSecretRef = nil
initPhaseContext.BKECluster.Spec.ClusterConfig.Cluster.ChartRepo.TlsSecretRef = &confv1beta1.TlsSecretRef{
Name: "tls-secret",
Namespace: "kube-system",
}
err := pp.createChartRepoSecretRefToBKECluster()
assert.NoError(t, err)
}
func TestHandleOpenFuyaoSystemController_AddControlPlaneLabelsError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "addControlPlaneLabels", func(_ *EnsureAddonDeploy) error {
return fmt.Errorf("add labels error")
})
err := pp.handleOpenFuyaoSystemController()
assert.Error(t, err)
}
func TestNeedExecute_DefaultNeedExecuteFalse(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
oldCluster := initOldBkeCluster.DeepCopy()
newCluster := initNewBkeCluster.DeepCopy()
result := pp.NeedExecute(oldCluster, newCluster)
assert.False(t, result)
}
func TestCreateBaseCommand_AllParams(t *testing.T) {
baseCmd := createBaseCommand(CreateBaseCommandParams{
Ctx: context.Background(),
NameSpace: "test-ns",
Client: nil,
Scheme: nil,
OwnerObj: nil,
ClusterName: "test-cluster",
Unique: true,
RemoveAfterWait: true,
})
assert.Equal(t, "test-ns", baseCmd.NameSpace)
assert.Equal(t, "test-cluster", baseCmd.ClusterName)
assert.True(t, baseCmd.Unique)
assert.True(t, baseCmd.RemoveAfterWait)
}
func TestHandleBeyondELB_WithVIPNoNodes(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{
Name: "beyondELB",
Param: map[string]string{
"ingressVIP": "10.10.10.1",
},
},
}
err := pp.handleBeyondELB()
assert.NoError(t, err)
}
func TestDistributePatchCM_MissingPatchKey(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
version := "v2.1.0"
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "bke-config", Namespace: "cluster-system"},
Data: map[string]string{"wrong-key": "value"},
}
require.NoError(t, initClient.GetClient().Create(context.Background(), localCM))
initPhaseContext.BKECluster.Spec.ClusterConfig.Cluster.OpenFuyaoVersion = version
err := pp.distributePatchCM()
assert.Error(t, err)
assert.Contains(t, err.Error(), "not found in local config")
}
func TestDistributePatchCM_MissingVersionInPatchCM(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
fakeRemoteClient := fake.NewSimpleClientset()
pp.mockClient = fakeRemoteClient
version := "v2.1.0"
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "bke-config", Namespace: "cluster-system"},
Data: map[string]string{fmt.Sprintf("patch.%s", version): "data"},
}
patchCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("cm.%s", version),
Namespace: "openfuyao-patch",
},
Data: map[string]string{"wrong-version": "content"},
}
require.NoError(t, initClient.GetClient().Create(context.Background(), localCM))
require.NoError(t, initClient.GetClient().Create(context.Background(), patchCM))
initPhaseContext.BKECluster.Spec.ClusterConfig.Cluster.OpenFuyaoVersion = version
err := pp.distributePatchCM()
assert.Error(t, err)
assert.Contains(t, err.Error(), "not found in patch config")
}
func TestAddControlPlaneLabels_Success(t *testing.T) {
t.Skip("Requires complex mocking of targetClusterClient interface")
}
func TestFindMatchingNodes_WithMatchingNodes(t *testing.T) {
t.Skip("Requires complex mocking of targetClusterClient interface")
}
func TestLabelAndSaveNodes_Empty2(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
params := LabelAndSaveNodesParams{
LabelNodes: []corev1.Node{},
Ctx: context.Background(),
Client: nil,
Log: initLog,
}
err := pp.labelAndSaveNodes(params)
assert.NoError(t, err)
}
func TestProcessAddon_InstallAddonError(t *testing.T) {
t.Skip("Requires complex mocking of targetClusterClient.InstallAddon")
}
func TestProcessAddon_GetNewestBKEClusterError(t *testing.T) {
t.Skip("Requires complex mocking of targetClusterClient.InstallAddon")
}
func TestExecuteDownloadCommand_NewError(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
params := ExecuteDownloadCommandParams{
DownloadCommand: nil,
Log: initLog,
BKECluster: &initNewBkeCluster,
}
assert.Panics(t, func() {
pp.executeDownloadCommand(params)
})
}
func TestReCreateKubeSchedulerStaticPodYaml_CommandError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return nil, fmt.Errorf("get nodes error")
})
err := pp.reCreateKubeSchedulerStaticPodYaml()
assert.Error(t, err)
}
func TestCreateEtcdBackupDir_GetNodesError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return nil, fmt.Errorf("get nodes error")
})
err := pp.createEtcdBackupDir("/tmp/backup")
assert.Error(t, err)
}
func TestHandleBeyondELB_GetIngressConfigError(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
initPhaseContext.BKECluster.Spec.ClusterConfig.Addons = nil
err := pp.handleBeyondELB()
assert.NoError(t, err)
}
func TestHandleEtcdBackup_CreateDirError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
addon := &confv1beta1.Product{
Name: "etcdbackup",
Param: map[string]string{"backupDir": "/tmp/backup"},
}
patches.ApplyMethod(initPhaseContext, "GetNodes", func(_ *phaseframe.PhaseContext) (bkenode.Nodes, error) {
return nil, fmt.Errorf("get nodes error")
})
err := pp.handleEtcdBackup(addon)
assert.Error(t, err)
}
func TestPrepareDownloadCalicoCtlParams_WithNodes(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
result := pp.prepareDownloadCalicoCtlParams("v3.26.0")
assert.NotEmpty(t, result.CalicoCtlUrl)
}
func TestCreateChartRefToBKECluster_WithChartAddonsError(t *testing.T) {
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
pp.mockClient = fake.NewSimpleClientset()
initPhaseContext.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{Name: "test-chart", Version: "v1.0.0", Type: "chart"},
}
err := pp.createChartRefToBKECluster()
_ = err
}
func TestFindMatchingNodes_ListNodesError(t *testing.T) {
t.Skip("Requires complex mocking of targetClusterClient interface")
}
func TestLabelNodesForELB_LabelAndSaveError(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
InitinitPhaseContextFun()
ppAny := NewEnsureAddonDeploy(initPhaseContext)
pp, ok := ppAny.(*EnsureAddonDeploy)
require.True(t, ok)
patches.ApplyPrivateMethod(pp, "findMatchingNodes", func(_ *EnsureAddonDeploy, _ FindMatchingNodesParams) ([]corev1.Node, error) {
return nil, fmt.Errorf("find error")
})
err := pp.labelNodesForELB([]string{"192.168.1.1"})
assert.Error(t, err)
}
type testMockRemoteClient struct {
kube.RemoteKubeClient
listNodesResult *corev1.NodeList
listNodesErr error
}
func (m *testMockRemoteClient) ListNodes(option *metav1.ListOptions) (*corev1.NodeList, error) {
if m.listNodesErr != nil {
return nil, m.listNodesErr
}
return m.listNodesResult, nil
}
func adScheme(t *testing.T) *runtime.Scheme {
t.Helper()
scheme := runtime.NewScheme()
require.NoError(t, bkev1beta1.AddToScheme(scheme))
require.NoError(t, agentv1beta1.AddToScheme(scheme))
require.NoError(t, corev1.AddToScheme(scheme))
return scheme
}
func newAddonDeployCov(t *testing.T, bkeCluster *bkev1beta1.BKECluster, objs ...client.Object) *EnsureAddonDeploy {
t.Helper()
scheme := adScheme(t)
builder := ctrlfake.NewClientBuilder().WithScheme(scheme)
if bkeCluster != nil {
builder = builder.WithObjects(bkeCluster)
}
for _, o := range objs {
builder = builder.WithObjects(o)
}
ctx := &phaseframe.PhaseContext{
Context: context.Background(),
BKECluster: bkeCluster,
Client: builder.Build(),
Scheme: scheme,
Log: bkev1beta1.NewBKELogger(nil, &fakeRecorder{}, bkeCluster),
}
return &EnsureAddonDeploy{BasePhase: phaseframe.BasePhase{Ctx: ctx}}
}
func adClusterWithConfig() *bkev1beta1.BKECluster {
return &bkev1beta1.BKECluster{
ObjectMeta: metav1.ObjectMeta{Name: "ad-c1", Namespace: "ad-ns"},
Spec: confv1beta1.BKEClusterSpec{
ControlPlaneEndpoint: confv1beta1.APIEndpoint{Host: "10.0.0.1", Port: 6443},
ClusterConfig: &confv1beta1.BKEConfig{
Cluster: confv1beta1.Cluster{
KubernetesVersion: "v1.29.2",
OpenFuyaoVersion: "v2.1.0",
Kubelet: &confv1beta1.Kubelet{ManifestsDir: "/etc/kubernetes/manifests"},
},
},
},
}
}
type adStubRemoteClient struct {
kube.RemoteKubeClient
listNodesResult *corev1.NodeList
listNodesErr error
installErr error
installCalled bool
}
func (s *adStubRemoteClient) ListNodes(_ *metav1.ListOptions) (*corev1.NodeList, error) {
if s.listNodesErr != nil {
return nil, s.listNodesErr
}
return s.listNodesResult, nil
}
func (s *adStubRemoteClient) InstallAddon(_ *bkev1beta1.BKECluster, _ *bkeaddon.AddonTransfer, _ *kube.AddonRecorder, _ client.Client, _ bkenode.Nodes) error {
s.installCalled = true
return s.installErr
}
func (s *adStubRemoteClient) SetLogger(_ *bkelog.Logger) {}
func (s *adStubRemoteClient) SetBKELogger(_ *bkev1beta1.BKELogger) {}
func (s *adStubRemoteClient) KubeClient() (*kubernetes.Clientset, dynamic.Interface) {
return nil, nil
}
func adPatchGetNodes(patches *gomonkey.Patches, nodes bkenode.Nodes, err error) {
patches.ApplyFunc((*nodeutil.NodeFetcher).FetchNodesForCluster,
func(_ *nodeutil.NodeFetcher, _ context.Context, _, _ string) (*nodeutil.FetchResult, error) {
return &nodeutil.FetchResult{Nodes: nodes}, err
})
}
func adNode(name string, addrs ...corev1.NodeAddress) *corev1.Node {
if len(addrs) == 0 {
addrs = []corev1.NodeAddress{{Type: corev1.NodeInternalIP, Address: "10.0.0.1"}}
}
return &corev1.Node{
ObjectMeta: metav1.ObjectMeta{Name: name, Labels: map[string]string{}},
Status: corev1.NodeStatus{Addresses: addrs},
}
}
func TestAddonDeployCovAddControlPlaneLabels(t *testing.T) {
t.Run("list nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.targetClusterClient = &adStubRemoteClient{listNodesErr: assertErr("list nodes failed")}
err := e.addControlPlaneLabels()
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to list nodes")
})
t.Run("get nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{}}
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
err := e.addControlPlaneLabels()
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get nodes")
})
t.Run("no matching nodes returns nil", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{
Items: []corev1.Node{*adNode("remote-node")},
}}
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "different-host", Role: []string{"master"}}}, nil)
require.NoError(t, e.addControlPlaneLabels())
})
t.Run("match and label success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{
Items: []corev1.Node{*adNode("node1")},
}}
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
e.mockClient = fake.NewSimpleClientset(adNode("node1"))
require.NoError(t, e.addControlPlaneLabels())
})
t.Run("update error propagates", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{
Items: []corev1.Node{*adNode("node1")},
}}
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
e.mockClient = fake.NewSimpleClientset()
err := e.addControlPlaneLabels()
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to set control-plane label")
})
}
func TestAddonDeployCovCreateBeyondELBVIP(t *testing.T) {
t.Run("empty vip returns nil", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
require.NoError(t, e.createBeyondELBVIP("", []string{"10.0.0.1"}))
})
t.Run("get nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
err := e.createBeyondELBVIP("10.10.10.1", []string{"10.0.0.1"})
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get nodes")
})
t.Run("no ingress node set", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
err := e.createBeyondELBVIP("10.10.10.1", []string{"10.0.0.99"})
require.Error(t, err)
assert.Contains(t, err.Error(), "no ingress node set for beyondELB")
})
t.Run("HA New error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.HA).New, func(_ *command.HA) error {
return assertErr("ha new failed")
})
err := e.createBeyondELBVIP("10.10.10.1", []string{"10.0.0.1"})
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to create beyondELB VIP command")
})
t.Run("HA Wait error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.HA).New, func(h *command.HA) error {
h.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.HA).Wait, func(_ *command.HA) (error, []string, []string) {
return assertErr("ha wait failed"), nil, nil
})
err := e.createBeyondELBVIP("10.10.10.1", []string{"10.0.0.1"})
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to create beyondELB VIP")
})
t.Run("HA Wait failed nodes", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.HA).New, func(h *command.HA) error {
h.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.HA).Wait, func(_ *command.HA) (error, []string, []string) {
return nil, nil, []string{"node1"}
})
patches.ApplyFunc(phaseutil.LogCommandFailed,
func(_ agentv1beta1.Command, _ []string, _ *bkev1beta1.BKELogger, _ string) (map[string][]string, error) {
return map[string][]string{}, nil
})
patches.ApplyFunc(phaseutil.MarkNodeStatusByCommandErrs,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster, _ map[string][]string) {})
err := e.createBeyondELBVIP("10.10.10.1", []string{"10.0.0.1"})
require.Error(t, err)
assert.Contains(t, err.Error(), "VIPCommand run failed")
})
t.Run("HA Wait success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.HA).New, func(h *command.HA) error {
h.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.HA).Wait, func(_ *command.HA) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
require.NoError(t, e.createBeyondELBVIP("10.10.10.1", []string{"10.0.0.1"}))
})
}
func TestAddonDeployCovHandleBeyondELB(t *testing.T) {
t.Run("empty vip and nodes returns nil", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{Name: "beyondELB", Param: map[string]string{}},
}
require.NoError(t, e.handleBeyondELB())
})
t.Run("create VIP error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{Name: "beyondELB", Param: map[string]string{"lbVIP": "10.10.10.1", "lbNodes": "10.0.0.1"}},
}
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
err := e.handleBeyondELB()
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get nodes")
})
t.Run("vip success then label nodes no match returns nil", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{Name: "beyondELB", Param: map[string]string{"lbVIP": "10.10.10.1", "lbNodes": "10.0.0.1"}},
}
patches.ApplyFunc(clusterutil.GetIngressConfig, func(_ []confv1beta1.Product) (string, []string) {
return "10.10.10.1", []string{"10.0.0.1"}
})
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.HA).New, func(h *command.HA) error {
h.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.HA).Wait, func(_ *command.HA) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{}}
require.NoError(t, e.handleBeyondELB())
})
t.Run("label nodes error returns error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{
{Name: "beyondELB", Param: map[string]string{"lbVIP": "10.10.10.1", "lbNodes": "10.0.0.1"}},
}
patches.ApplyFunc(clusterutil.GetIngressConfig, func(_ []confv1beta1.Product) (string, []string) {
return "10.10.10.1", []string{"10.0.0.1"}
})
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.HA).New, func(h *command.HA) error {
h.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.HA).Wait, func(_ *command.HA) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
patches.ApplyPrivateMethod(e, "findMatchingNodes", func(_ *EnsureAddonDeploy, _ FindMatchingNodesParams) ([]corev1.Node, error) {
return nil, assertErr("find matching failed")
})
err := e.handleBeyondELB()
require.Error(t, err)
assert.Contains(t, err.Error(), "find matching failed")
})
}
func TestAddonDeployCovFindMatchingNodes(t *testing.T) {
t.Run("get nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
nodes, err := e.findMatchingNodes(FindMatchingNodesParams{LbNodes: []string{"10.0.0.1"}})
require.Error(t, err)
assert.Nil(t, nodes)
})
t.Run("list remote nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1"}}, nil)
e.targetClusterClient = &adStubRemoteClient{listNodesErr: assertErr("list remote failed")}
nodes, err := e.findMatchingNodes(FindMatchingNodesParams{LbNodes: []string{"10.0.0.1"}})
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to list remote nodes")
assert.Nil(t, nodes)
})
t.Run("match by internal IP", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1"}}, nil)
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{
Items: []corev1.Node{*adNode("node1",
corev1.NodeAddress{Type: corev1.NodeInternalIP, Address: "10.0.0.1"})},
}}
nodes, err := e.findMatchingNodes(FindMatchingNodesParams{LbNodes: []string{"10.0.0.1"}})
require.NoError(t, err)
assert.Len(t, nodes, 1)
})
t.Run("match by hostname", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.2", Hostname: "node1"}}, nil)
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{
Items: []corev1.Node{*adNode("node1",
corev1.NodeAddress{Type: corev1.NodeHostName, Address: "node1"})},
}}
nodes, err := e.findMatchingNodes(FindMatchingNodesParams{LbNodes: []string{"10.0.0.2"}})
require.NoError(t, err)
assert.Len(t, nodes, 1)
})
t.Run("no match returns empty", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1"}}, nil)
e.targetClusterClient = &adStubRemoteClient{listNodesResult: &corev1.NodeList{
Items: []corev1.Node{*adNode("other",
corev1.NodeAddress{Type: corev1.NodeInternalIP, Address: "10.0.0.99"})},
}}
nodes, err := e.findMatchingNodes(FindMatchingNodesParams{LbNodes: []string{"10.0.0.1"}})
require.NoError(t, err)
assert.Empty(t, nodes)
})
}
func TestAddonDeployCovLabelAndSaveNodes(t *testing.T) {
t.Run("empty nodes returns nil", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
params := LabelAndSaveNodesParams{
LabelNodes: []corev1.Node{},
Ctx: context.Background(),
Log: e.Ctx.Log,
}
require.NoError(t, e.labelAndSaveNodes(params))
})
t.Run("label success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
params := LabelAndSaveNodesParams{
LabelNodes: []corev1.Node{*adNode("node1")},
Ctx: context.Background(),
Client: fake.NewSimpleClientset(adNode("node1")),
Log: e.Ctx.Log,
}
require.NoError(t, e.labelAndSaveNodes(params))
})
t.Run("get node error returns failure", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
params := LabelAndSaveNodesParams{
LabelNodes: []corev1.Node{*adNode("missing")},
Ctx: context.Background(),
Client: fake.NewSimpleClientset(),
Log: e.Ctx.Log,
}
err := e.labelAndSaveNodes(params)
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to set beyondELB label")
})
}
func TestAddonDeployCovExecuteDownloadCommand(t *testing.T) {
t.Run("New error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc((*command.Custom).New, func(_ *command.Custom) error {
return assertErr("new failed")
})
params := ExecuteDownloadCommandParams{
DownloadCommand: &command.Custom{},
Log: e.Ctx.Log,
BKECluster: e.Ctx.BKECluster,
}
result := e.executeDownloadCommand(params)
require.Error(t, result.Error)
assert.Contains(t, result.Error.Error(), "create download calicoctl command failed")
})
t.Run("Wait error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return assertErr("wait failed"), nil, nil
})
params := ExecuteDownloadCommandParams{
DownloadCommand: &command.Custom{},
Log: e.Ctx.Log,
BKECluster: e.Ctx.BKECluster,
}
result := e.executeDownloadCommand(params)
require.Error(t, result.Error)
assert.Contains(t, result.Error.Error(), "wait download calicoctl command failed")
})
t.Run("Wait failed nodes", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, nil, []string{"node1"}
})
patches.ApplyFunc(phaseutil.LogCommandFailed,
func(_ agentv1beta1.Command, _ []string, _ *bkev1beta1.BKELogger, _ string) (map[string][]string, error) {
return map[string][]string{}, nil
})
patches.ApplyFunc(phaseutil.MarkNodeStatusByCommandErrs,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster, _ map[string][]string) {})
params := ExecuteDownloadCommandParams{
DownloadCommand: &command.Custom{},
Log: e.Ctx.Log,
BKECluster: e.Ctx.BKECluster,
}
result := e.executeDownloadCommand(params)
require.Error(t, result.Error)
assert.Contains(t, result.Error.Error(), "download calicoctl command run failed")
})
t.Run("Wait success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
params := ExecuteDownloadCommandParams{
DownloadCommand: &command.Custom{},
Log: e.Ctx.Log,
BKECluster: e.Ctx.BKECluster,
}
result := e.executeDownloadCommand(params)
require.NoError(t, result.Error)
})
}
func TestAddonDeployCovProcessAddon(t *testing.T) {
t.Run("create addon before-create error", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
addonT := &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "etcdbackup", Param: map[string]string{"backupDir": "/tmp"}},
Operate: bkeaddon.CreateAddon,
}
params := ProcessAddonParams{
AddonT: addonT, BKECluster: e.Ctx.BKECluster,
Client: e.Ctx.Client, Ctx: e.Ctx, Log: e.Ctx.Log,
}
result := e.processAddon(params)
require.Error(t, result.Error)
assert.False(t, result.Continue)
})
t.Run("create addon success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
stub := &adStubRemoteClient{installErr: nil}
patches.ApplyFunc(mergecluster.GetCombinedBKECluster,
func(_ context.Context, _ client.Client, _, _ string) (*bkev1beta1.BKECluster, error) {
return e.Ctx.BKECluster, nil
})
addonT := &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"},
Operate: bkeaddon.CreateAddon,
}
params := ProcessAddonParams{
AddonT: addonT, BKECluster: e.Ctx.BKECluster, TargetClusterClient: stub,
Client: e.Ctx.Client, Ctx: e.Ctx, Log: e.Ctx.Log,
}
result := e.processAddon(params)
require.NoError(t, result.Error)
assert.True(t, result.Continue)
assert.True(t, stub.installCalled)
})
t.Run("install blocking error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1"}}, nil)
stub := &adStubRemoteClient{installErr: assertErr("install failed")}
patches.ApplyFunc(mergecluster.GetCombinedBKECluster,
func(_ context.Context, _ client.Client, _, _ string) (*bkev1beta1.BKECluster, error) {
return e.Ctx.BKECluster, nil
})
addonT := &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0", Block: true},
Operate: bkeaddon.UpdateAddon,
}
params := ProcessAddonParams{
AddonT: addonT, BKECluster: e.Ctx.BKECluster, TargetClusterClient: stub,
Client: e.Ctx.Client, Ctx: e.Ctx, Log: e.Ctx.Log,
}
result := e.processAddon(params)
require.Error(t, result.Error)
assert.False(t, result.Continue)
})
t.Run("install non-blocking error continues", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1"}}, nil)
stub := &adStubRemoteClient{installErr: assertErr("install failed")}
patches.ApplyFunc(mergecluster.GetCombinedBKECluster,
func(_ context.Context, _ client.Client, _, _ string) (*bkev1beta1.BKECluster, error) {
return e.Ctx.BKECluster, nil
})
addonT := &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0", Block: false},
Operate: bkeaddon.UpgradeAddon,
}
params := ProcessAddonParams{
AddonT: addonT, BKECluster: e.Ctx.BKECluster, TargetClusterClient: stub,
Client: e.Ctx.Client, Ctx: e.Ctx, Log: e.Ctx.Log,
}
result := e.processAddon(params)
require.NoError(t, result.Error)
assert.True(t, result.Continue)
assert.NotNil(t, result.NewestBKECluster)
})
t.Run("get newest bkecluster error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1"}}, nil)
stub := &adStubRemoteClient{installErr: nil}
patches.ApplyFunc(mergecluster.GetCombinedBKECluster,
func(_ context.Context, _ client.Client, _, _ string) (*bkev1beta1.BKECluster, error) {
return nil, assertErr("get newest failed")
})
addonT := &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"},
Operate: bkeaddon.UpdateAddon,
}
params := ProcessAddonParams{
AddonT: addonT, BKECluster: e.Ctx.BKECluster, TargetClusterClient: stub,
Client: e.Ctx.Client, Ctx: e.Ctx, Log: e.Ctx.Log,
}
result := e.processAddon(params)
require.Error(t, result.Error)
assert.False(t, result.Continue)
})
t.Run("get nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
addonT := &bkeaddon.AddonTransfer{
Addon: &confv1beta1.Product{Name: "test-addon", Version: "v1.0.0"},
Operate: bkeaddon.UpdateAddon,
}
params := ProcessAddonParams{
AddonT: addonT, BKECluster: e.Ctx.BKECluster, TargetClusterClient: &adStubRemoteClient{},
Client: e.Ctx.Client, Ctx: e.Ctx, Log: e.Ctx.Log,
}
result := e.processAddon(params)
require.Error(t, result.Error)
assert.False(t, result.Continue)
})
}
func TestAddonDeployCovCreateEtcdCertSecret(t *testing.T) {
t.Run("secret already exists", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
existing := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "etcd-backup-secrets", Namespace: "kube-system"}}
e.mockClient = fake.NewSimpleClientset(existing)
require.NoError(t, e.createEtcdCertSecret())
})
t.Run("get cert content error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
patches.ApplyFunc((*certs.BKEKubernetesCertGetter).GetCertContent,
func(_ *certs.BKEKubernetesCertGetter, _ *pkiutil.BKECert) (*certs.CertContent, error) {
return nil, assertErr("cert content failed")
})
err := e.createEtcdCertSecret()
require.Error(t, err)
assert.Contains(t, err.Error(), "cert content failed")
})
t.Run("create success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
patches.ApplyFunc((*certs.BKEKubernetesCertGetter).GetCertContent,
func(_ *certs.BKEKubernetesCertGetter, _ *pkiutil.BKECert) (*certs.CertContent, error) {
return &certs.CertContent{Key: "k", Cert: "c"}, nil
})
require.NoError(t, e.createEtcdCertSecret())
})
}
func TestAddonDeployCovCreateClusterAPILocalkubeconfigSecret(t *testing.T) {
t.Run("secret already exists", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
existing := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: constant.LocalKubeConfigName, Namespace: "kube-system"}}
e.mockClient = fake.NewSimpleClientset(existing)
require.NoError(t, e.createClusterAPILocalkubeconfigSecret())
})
t.Run("get kubeconfig error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
patches.ApplyFunc((*certs.BKEKubernetesCertGetter).GetTargetClusterKubeconfig,
func(_ *certs.BKEKubernetesCertGetter) (string, error) {
return "", assertErr("kubeconfig failed")
})
err := e.createClusterAPILocalkubeconfigSecret()
require.Error(t, err)
assert.Contains(t, err.Error(), "kubeconfig failed")
})
t.Run("create success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
patches.ApplyFunc((*certs.BKEKubernetesCertGetter).GetTargetClusterKubeconfig,
func(_ *certs.BKEKubernetesCertGetter) (string, error) {
return "kubeconfig-content", nil
})
require.NoError(t, e.createClusterAPILocalkubeconfigSecret())
})
}
func TestAddonDeployCovCreateClusterAPILeastPrivilegeKubeConfigSecret(t *testing.T) {
t.Run("secret already exists", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
existing := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: constant.LeastPrivilegeKubeConfigName, Namespace: metav1.NamespaceSystem}}
e.mockClient = fake.NewSimpleClientset(existing)
patches.ApplyFunc(phaseutil.GetRemoteLocalKubeConfig,
func(_ context.Context, _ *kubernetes.Clientset) ([]byte, error) { return []byte("remote"), nil })
patches.ApplyFunc(phaseutil.GenerateLowPrivilegeKubeConfig,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster, _ []byte) ([]byte, error) {
return []byte("low-priv"), nil
})
require.NoError(t, e.createClusterAPILeastPrivilegeKubeConfigSecret())
})
t.Run("create success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
patches.ApplyFunc(phaseutil.GetRemoteLocalKubeConfig,
func(_ context.Context, _ *kubernetes.Clientset) ([]byte, error) { return []byte("remote"), nil })
patches.ApplyFunc(phaseutil.GenerateLowPrivilegeKubeConfig,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster, _ []byte) ([]byte, error) {
return []byte("low-priv"), nil
})
require.NoError(t, e.createClusterAPILeastPrivilegeKubeConfigSecret())
})
}
func TestAddonDeployCovReCreateKubeSchedulerStaticPodYaml(t *testing.T) {
t.Run("get nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
err := e.reCreateKubeSchedulerStaticPodYaml()
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get nodes")
})
t.Run("New error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Cluster.Kubelet.ManifestsDir = "/etc/kubernetes/manifests"
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(_ *command.Custom) error {
return assertErr("new failed")
})
err := e.reCreateKubeSchedulerStaticPodYaml()
require.Error(t, err)
assert.Contains(t, err.Error(), "create recreate kube-scheduler static pod yaml command failed")
})
t.Run("Wait error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Cluster.Kubelet.ManifestsDir = "/etc/kubernetes/manifests"
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return assertErr("wait failed"), nil, nil
})
err := e.reCreateKubeSchedulerStaticPodYaml()
require.Error(t, err)
assert.Contains(t, err.Error(), "wait recreate kube-scheduler static pod yaml command failed")
})
t.Run("Wait failed nodes", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Cluster.Kubelet.ManifestsDir = "/etc/kubernetes/manifests"
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, nil, []string{"node1"}
})
patches.ApplyFunc(phaseutil.LogCommandFailed,
func(_ agentv1beta1.Command, _ []string, _ *bkev1beta1.BKELogger, _ string) (map[string][]string, error) {
return map[string][]string{}, nil
})
patches.ApplyFunc(phaseutil.MarkNodeStatusByCommandErrs,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster, _ map[string][]string) {})
err := e.reCreateKubeSchedulerStaticPodYaml()
require.Error(t, err)
assert.Contains(t, err.Error(), "recreate kube-scheduler static pod yaml command run failed")
})
t.Run("Wait success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
e.Ctx.BKECluster.Spec.ClusterConfig.Cluster.Kubelet.ManifestsDir = "/etc/kubernetes/manifests"
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"master"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
require.NoError(t, e.reCreateKubeSchedulerStaticPodYaml())
})
}
func TestAddonDeployCovCreateEtcdBackupDir(t *testing.T) {
t.Run("get nodes error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
err := e.createEtcdBackupDir("/tmp/backup")
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get nodes")
})
t.Run("New error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"etcd"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(_ *command.Custom) error {
return assertErr("new failed")
})
err := e.createEtcdBackupDir("/tmp/backup")
require.Error(t, err)
assert.Contains(t, err.Error(), "create create-etcd-backup-dir command failed")
})
t.Run("Wait error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"etcd"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return assertErr("wait failed"), nil, nil
})
err := e.createEtcdBackupDir("/tmp/backup")
require.Error(t, err)
assert.Contains(t, err.Error(), "create create-etcd-backup-dir command failed")
})
t.Run("Wait failed nodes", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"etcd"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, nil, []string{"node1"}
})
patches.ApplyFunc(phaseutil.LogCommandFailed,
func(_ agentv1beta1.Command, _ []string, _ *bkev1beta1.BKELogger, _ string) (map[string][]string, error) {
return map[string][]string{}, nil
})
patches.ApplyFunc(phaseutil.MarkNodeStatusByCommandErrs,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster, _ map[string][]string) {})
err := e.createEtcdBackupDir("/tmp/backup")
require.Error(t, err)
assert.Contains(t, err.Error(), "createDirCommand run failed")
})
t.Run("Wait success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"etcd"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
require.NoError(t, e.createEtcdBackupDir("/tmp/backup"))
})
}
func TestAddonDeployCovHandleEtcdBackup(t *testing.T) {
t.Run("create dir error via get nodes", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, nil, assertErr("get nodes failed"))
addon := &confv1beta1.Product{Name: "etcdbackup", Param: map[string]string{"backupDir": "/tmp/backup"}}
err := e.handleEtcdBackup(addon)
require.Error(t, err)
})
t.Run("cert secret create success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
adPatchGetNodes(patches, bkenode.Nodes{{IP: "10.0.0.1", Hostname: "node1", Role: []string{"etcd"}}}, nil)
patches.ApplyFunc((*command.Custom).New, func(c *command.Custom) error {
c.Command = &agentv1beta1.Command{}
return nil
})
patches.ApplyFunc((*command.Custom).Wait, func(_ *command.Custom) (error, []string, []string) {
return nil, []string{"node1"}, nil
})
existing := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "etcd-backup-secrets", Namespace: "kube-system"}}
e.mockClient = fake.NewSimpleClientset(existing)
addon := &confv1beta1.Product{Name: "etcdbackup", Param: map[string]string{"backupDir": "/tmp/backup"}}
require.NoError(t, e.handleEtcdBackup(addon))
})
}
func TestAddonDeployCovExecute(t *testing.T) {
t.Run("reconcile success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc(kube.NewRemoteClientByBKECluster,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster) (kube.RemoteKubeClient, error) {
return &adStubRemoteClient{}, nil
})
patches.ApplyPrivateMethod(e, "reconcileAddon", func(_ *EnsureAddonDeploy) error { return nil })
result, err := e.Execute()
require.NoError(t, err)
assert.Equal(t, ctrl.Result{}, result)
})
t.Run("remote client error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc(kube.NewRemoteClientByBKECluster,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster) (kube.RemoteKubeClient, error) {
return nil, assertErr("remote client failed")
})
result, err := e.Execute()
require.Error(t, err)
assert.Equal(t, ctrl.Result{}, result)
})
t.Run("reconcile error", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
patches.ApplyFunc(kube.NewRemoteClientByBKECluster,
func(_ context.Context, _ client.Client, _ *bkev1beta1.BKECluster) (kube.RemoteKubeClient, error) {
return &adStubRemoteClient{}, nil
})
patches.ApplyPrivateMethod(e, "reconcileAddon", func(_ *EnsureAddonDeploy) error {
return assertErr("reconcile failed")
})
result, err := e.Execute()
require.Error(t, err)
assert.Equal(t, ctrl.Result{}, result)
})
}
func TestAddonDeployCovCreateChartAddonCMRefUpdate(t *testing.T) {
t.Run("update existing remote cm", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "values-cm", Namespace: "ad-ns"},
Data: map[string]string{"values": "new-data"},
}
require.NoError(t, e.Ctx.Client.Create(context.Background(), localCM))
existingRemote := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "values-cm", Namespace: "ad-ns"},
Data: map[string]string{"values": "old-data"},
}
e.mockClient = fake.NewSimpleClientset(existingRemote)
addon := confv1beta1.Product{
Name: "chart-addon",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "values-cm",
Namespace: "ad-ns",
},
}
require.NoError(t, e.createChartAddonCMRefToBKECluster(addon))
got, err := e.mockClient.CoreV1().ConfigMaps("ad-ns").Get(context.Background(), "values-cm", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "new-data", got.Data["values"])
})
t.Run("create remote cm success", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
e := newAddonDeployCov(t, adClusterWithConfig())
localCM := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "values-cm", Namespace: "ad-ns"},
Data: map[string]string{"values": "data"},
}
require.NoError(t, e.Ctx.Client.Create(context.Background(), localCM))
e.mockClient = fake.NewSimpleClientset()
addon := confv1beta1.Product{
Name: "chart-addon",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "values-cm",
Namespace: "ad-ns",
},
}
require.NoError(t, e.createChartAddonCMRefToBKECluster(addon))
})
t.Run("get local cm error", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
addon := confv1beta1.Product{
Name: "chart-addon",
ValuesConfigMapRef: &confv1beta1.ValuesConfigMapRef{
Name: "missing-cm",
Namespace: "ad-ns",
},
}
err := e.createChartAddonCMRefToBKECluster(addon)
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get local values.yaml configmap")
})
}
func TestAddonDeployCovCreateChartRepoSecretRefUpdate(t *testing.T) {
t.Run("update existing remote secret", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
localSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "auth-secret", Namespace: "ad-ns"},
Data: map[string][]byte{"user": []byte("new")},
}
require.NoError(t, e.Ctx.Client.Create(context.Background(), localSecret))
existingRemote := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "auth-secret", Namespace: "ad-ns"},
Data: map[string][]byte{"user": []byte("old")},
}
e.mockClient = fake.NewSimpleClientset(existingRemote)
e.Ctx.BKECluster.Spec.ClusterConfig.Cluster.ChartRepo.AuthSecretRef = &confv1beta1.AuthSecretRef{
Name: "auth-secret", Namespace: "ad-ns",
}
require.NoError(t, e.createChartRepoSecretRefToBKECluster())
got, err := e.mockClient.CoreV1().Secrets("ad-ns").Get(context.Background(), "auth-secret", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "new", string(got.Data["user"]))
})
t.Run("get local secret error", func(t *testing.T) {
e := newAddonDeployCov(t, adClusterWithConfig())
e.mockClient = fake.NewSimpleClientset()
e.Ctx.BKECluster.Spec.ClusterConfig.Cluster.ChartRepo.AuthSecretRef = &confv1beta1.AuthSecretRef{
Name: "missing-secret", Namespace: "ad-ns",
}
err := e.createChartRepoSecretRefToBKECluster()
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to get local repo secret")
})
}
func TestAddonDeployCovNeedExecute(t *testing.T) {
t.Run("no nodes with addons returns true and sets waiting", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
cluster := adClusterWithConfig()
cluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{{Name: "a", Version: "v1"}}
e := newAddonDeployCov(t, cluster)
patches.ApplyFunc(bkeaddon.CompareBKEConfigAddon,
func(_ []confv1beta1.Product, _ []confv1beta1.Product) ([]*bkeaddon.AddonTransfer, bool) {
return nil, true
})
oldC := cluster.DeepCopy()
newC := cluster.DeepCopy()
_ = e.NeedExecute(oldC, newC)
})
t.Run("get bkenodes error warns and continues", func(t *testing.T) {
patches := gomonkey.NewPatches()
defer patches.Reset()
cluster := adClusterWithConfig()
cluster.Spec.ClusterConfig.Addons = []confv1beta1.Product{{Name: "a", Version: "v1"}}
e := newAddonDeployCov(t, cluster)
patches.ApplyFunc((*nodeutil.NodeFetcher).GetBKENodesWrapper,
func(_ *nodeutil.NodeFetcher, _ context.Context, _, _ string) (bkev1beta1.BKENodes, error) {
return nil, assertErr("bkenodes failed")
})
oldC := cluster.DeepCopy()
newC := cluster.DeepCopy()
_ = e.NeedExecute(oldC, newC)
})
}