github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/apis/workloads/v1alpha1/replicatedstatemachine_webhook_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 v1alpha1
    21  
    22  import (
    23  	. "github.com/onsi/ginkgo/v2"
    24  	. "github.com/onsi/gomega"
    25  
    26  	corev1 "k8s.io/api/core/v1"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  
    29  	"github.com/1aal/kubeblocks/pkg/constant"
    30  )
    31  
    32  var _ = Describe("ReplicatedStateMachine Webhook", func() {
    33  	Context("spec validation", func() {
    34  		const name = "test-replicated-state-machine"
    35  		var rsm *ReplicatedStateMachine
    36  
    37  		BeforeEach(func() {
    38  			commonLabels := map[string]string{
    39  				constant.AppManagedByLabelKey:   constant.AppName,
    40  				constant.AppNameLabelKey:        "ClusterDefName",
    41  				constant.AppComponentLabelKey:   "CompDefName",
    42  				constant.AppInstanceLabelKey:    "clusterName",
    43  				constant.KBAppComponentLabelKey: "componentName",
    44  			}
    45  			replicas := int32(1)
    46  			rsm = &ReplicatedStateMachine{
    47  				ObjectMeta: metav1.ObjectMeta{
    48  					Name:      name,
    49  					Namespace: testCtx.DefaultNamespace,
    50  				},
    51  				Spec: ReplicatedStateMachineSpec{
    52  					Replicas: &replicas,
    53  					Selector: &metav1.LabelSelector{
    54  						MatchLabels: commonLabels,
    55  					},
    56  					Service: &corev1.Service{},
    57  					RoleProbe: &RoleProbe{
    58  						CustomHandler: []Action{
    59  							{
    60  								Image:   "foo",
    61  								Command: []string{"bar"},
    62  							},
    63  						},
    64  					},
    65  					Template: corev1.PodTemplateSpec{
    66  						ObjectMeta: metav1.ObjectMeta{
    67  							Labels: commonLabels,
    68  						},
    69  						Spec: corev1.PodSpec{
    70  							Containers: []corev1.Container{
    71  								{
    72  									Name:  "foo",
    73  									Image: "bar",
    74  								},
    75  							},
    76  						},
    77  					},
    78  				},
    79  			}
    80  		})
    81  
    82  		It("should return an error if no leader set", func() {
    83  			rsm.Spec.Roles = []ReplicaRole{
    84  				{
    85  					Name:       "leader",
    86  					IsLeader:   false,
    87  					AccessMode: ReadWriteMode,
    88  				},
    89  			}
    90  			err := k8sClient.Create(ctx, rsm)
    91  			Expect(err).ShouldNot(BeNil())
    92  			Expect(err.Error()).Should(ContainSubstring("leader is required"))
    93  		})
    94  
    95  		It("should return an error if servicePort not provided", func() {
    96  			rsm.Spec.Roles = []ReplicaRole{
    97  				{
    98  					Name:       "leader",
    99  					IsLeader:   true,
   100  					AccessMode: ReadWriteMode,
   101  				},
   102  			}
   103  			err := k8sClient.Create(ctx, rsm)
   104  			Expect(err).ShouldNot(BeNil())
   105  			Expect(err.Error()).Should(ContainSubstring("servicePort must provide"))
   106  		})
   107  
   108  		It("should succeed if spec is well defined", func() {
   109  			rsm.Spec.Roles = []ReplicaRole{
   110  				{
   111  					Name:       "leader",
   112  					IsLeader:   true,
   113  					AccessMode: ReadWriteMode,
   114  				},
   115  			}
   116  			rsm.Spec.Service.Spec.Ports = []corev1.ServicePort{
   117  				{
   118  					Name:     "foo",
   119  					Protocol: "tcp",
   120  					Port:     12345,
   121  				},
   122  			}
   123  			Expect(k8sClient.Create(ctx, rsm)).Should(Succeed())
   124  			Expect(k8sClient.Delete(ctx, rsm)).Should(Succeed())
   125  		})
   126  	})
   127  })