github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controller/configuration/operator_test.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package configuration
    21  
    22  import (
    23  	. "github.com/onsi/ginkgo/v2"
    24  	. "github.com/onsi/gomega"
    25  
    26  	"github.com/golang/mock/gomock"
    27  	appsv1 "k8s.io/api/apps/v1"
    28  	corev1 "k8s.io/api/core/v1"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	"sigs.k8s.io/controller-runtime/pkg/client"
    31  
    32  	appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1"
    33  	cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core"
    34  	cfgutil "github.com/1aal/kubeblocks/pkg/configuration/util"
    35  	"github.com/1aal/kubeblocks/pkg/controller/builder"
    36  	"github.com/1aal/kubeblocks/pkg/controller/component"
    37  	"github.com/1aal/kubeblocks/pkg/controller/factory"
    38  	intctrlutil "github.com/1aal/kubeblocks/pkg/controllerutil"
    39  	testapps "github.com/1aal/kubeblocks/pkg/testutil/apps"
    40  	testutil "github.com/1aal/kubeblocks/pkg/testutil/k8s"
    41  )
    42  
    43  var _ = Describe("ConfigurationOperatorTest", func() {
    44  
    45  	var clusterObj *appsv1alpha1.Cluster
    46  	var clusterVersionObj *appsv1alpha1.ClusterVersion
    47  	var clusterDefObj *appsv1alpha1.ClusterDefinition
    48  	var clusterComponent *component.SynthesizedComponent
    49  	var configMapObj *corev1.ConfigMap
    50  	var scriptsObj *corev1.ConfigMap
    51  	var configConstraint *appsv1alpha1.ConfigConstraint
    52  	var configurationObj *appsv1alpha1.Configuration
    53  	var k8sMockClient *testutil.K8sClientMockHelper
    54  
    55  	mockStatefulSet := func() *appsv1.StatefulSet {
    56  		envConfig := factory.BuildEnvConfig(clusterObj, clusterComponent)
    57  		stsObj, err := factory.BuildSts(intctrlutil.RequestCtx{
    58  			Ctx: ctx,
    59  			Log: logger,
    60  		}, clusterObj, clusterComponent, envConfig.Name)
    61  		Expect(err).Should(Succeed())
    62  		return stsObj
    63  	}
    64  
    65  	createConfigReconcileTask := func() *configOperator {
    66  		task := NewConfigReconcileTask(&intctrlutil.ResourceCtx{
    67  			Client:        k8sMockClient.Client(),
    68  			Context:       ctx,
    69  			Namespace:     testCtx.DefaultNamespace,
    70  			ClusterName:   clusterName,
    71  			ComponentName: mysqlCompName,
    72  		},
    73  			clusterObj,
    74  			clusterVersionObj,
    75  			clusterComponent,
    76  			mockStatefulSet(),
    77  			clusterComponent.PodSpec,
    78  			nil)
    79  		return task
    80  	}
    81  
    82  	BeforeEach(func() {
    83  		// Add any setup steps that needs to be executed before each test
    84  		k8sMockClient = testutil.NewK8sMockClient()
    85  		clusterObj, clusterDefObj, clusterVersionObj, _ = newAllFieldsClusterObj(nil, nil, false)
    86  		clusterComponent = newAllFieldsComponent(clusterDefObj, clusterVersionObj)
    87  		configMapObj = testapps.NewConfigMap("default", mysqlConfigName,
    88  			testapps.SetConfigMapData("test", "test"))
    89  		scriptsObj = testapps.NewConfigMap("default", mysqlScriptsConfigName,
    90  			testapps.SetConfigMapData("script.sh", "echo \"hello\""))
    91  		configurationObj = builder.NewConfigurationBuilder(testCtx.DefaultNamespace,
    92  			cfgcore.GenerateComponentConfigurationName(clusterName, mysqlCompName)).
    93  			ClusterRef(clusterName).
    94  			Component(mysqlCompName).
    95  			GetObject()
    96  		configConstraint = &appsv1alpha1.ConfigConstraint{
    97  			ObjectMeta: metav1.ObjectMeta{
    98  				Name: mysqlConfigConstraintName,
    99  			},
   100  			Spec: appsv1alpha1.ConfigConstraintSpec{
   101  				ReloadOptions: &appsv1alpha1.ReloadOptions{
   102  					ShellTrigger: &appsv1alpha1.ShellTrigger{
   103  						Command: []string{"echo", "hello"},
   104  						Sync:    cfgutil.ToPointer(true),
   105  					},
   106  				},
   107  				FormatterConfig: &appsv1alpha1.FormatterConfig{
   108  					Format: appsv1alpha1.Ini,
   109  					FormatterOptions: appsv1alpha1.FormatterOptions{
   110  						IniConfig: &appsv1alpha1.IniConfig{
   111  							SectionName: "mysqld",
   112  						},
   113  					},
   114  				},
   115  			},
   116  		}
   117  	})
   118  
   119  	AfterEach(func() {
   120  		k8sMockClient.Finish()
   121  	})
   122  
   123  	Context("ConfigOperatorTest", func() {
   124  		It("NormalTest", func() {
   125  			k8sMockClient.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult(
   126  				[]client.Object{
   127  					clusterDefObj,
   128  					clusterVersionObj,
   129  					clusterObj,
   130  					clusterObj,
   131  					scriptsObj,
   132  					configMapObj,
   133  					configConstraint,
   134  					configurationObj,
   135  				},
   136  			), testutil.WithAnyTimes()))
   137  			k8sMockClient.MockCreateMethod(testutil.WithCreateReturned(testutil.WithCreatedSucceedResult(), testutil.WithAnyTimes()))
   138  			k8sMockClient.MockPatchMethod(testutil.WithPatchReturned(func(obj client.Object, patch client.Patch) error {
   139  				switch v := obj.(type) {
   140  				case *appsv1alpha1.Configuration:
   141  					if client.ObjectKeyFromObject(obj) == client.ObjectKeyFromObject(configurationObj) {
   142  						configurationObj.Spec = *v.Spec.DeepCopy()
   143  						configurationObj.Status = *v.Status.DeepCopy()
   144  					}
   145  				}
   146  				return nil
   147  			}))
   148  			k8sMockClient.MockStatusMethod().
   149  				EXPECT().
   150  				Patch(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
   151  				Return(nil)
   152  			// DoAndReturn(func(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
   153  			//	return nil
   154  			// })
   155  
   156  			Expect(createConfigReconcileTask().Reconcile()).Should(Succeed())
   157  		})
   158  
   159  		It("EmptyConfigSpecTest", func() {
   160  
   161  			k8sMockClient.MockCreateMethod(testutil.WithCreateReturned(testutil.WithCreatedSucceedResult(), testutil.WithTimes(1)))
   162  			k8sMockClient.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult(
   163  				[]client.Object{
   164  					clusterDefObj,
   165  					clusterVersionObj,
   166  					clusterObj,
   167  					clusterObj,
   168  				},
   169  			), testutil.WithAnyTimes()))
   170  
   171  			clusterComponent.ConfigTemplates = nil
   172  			clusterComponent.ScriptTemplates = nil
   173  			Expect(createConfigReconcileTask().Reconcile()).Should(Succeed())
   174  		})
   175  
   176  	})
   177  
   178  })