github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controllerutil/volume_util_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 controllerutil 21 22 import ( 23 . "github.com/onsi/ginkgo/v2" 24 . "github.com/onsi/gomega" 25 26 appsv1 "k8s.io/api/apps/v1" 27 corev1 "k8s.io/api/core/v1" 28 29 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 30 ) 31 32 var _ = Describe("lifecycle_utils", func() { 33 34 Context("has the checkAndUpdatePodVolumes function which generates Pod Volumes for mounting ConfigMap objects", func() { 35 var sts appsv1.StatefulSet 36 var volumes map[string]appsv1alpha1.ComponentTemplateSpec 37 BeforeEach(func() { 38 sts = appsv1.StatefulSet{ 39 Spec: appsv1.StatefulSetSpec{ 40 Template: corev1.PodTemplateSpec{ 41 Spec: corev1.PodSpec{ 42 Volumes: []corev1.Volume{ 43 { 44 Name: "data", 45 VolumeSource: corev1.VolumeSource{ 46 EmptyDir: &corev1.EmptyDirVolumeSource{}, 47 }, 48 }, 49 }, 50 Containers: []corev1.Container{ 51 { 52 Name: "mysql", 53 Image: "docker.io/apecloud/apecloud-mysql-server:latest", 54 ImagePullPolicy: "IfNotPresent", 55 VolumeMounts: []corev1.VolumeMount{ 56 { 57 Name: "data", 58 MountPath: "/data", 59 }, 60 }, 61 }, 62 }, 63 }, 64 }, 65 }, 66 } 67 volumes = make(map[string]appsv1alpha1.ComponentTemplateSpec) 68 69 }) 70 71 It("should succeed in corner case where input volumes is nil, which means no volume is added", func() { 72 ps := &sts.Spec.Template.Spec 73 err := CreateOrUpdatePodVolumes(ps, volumes) 74 Expect(err).Should(BeNil()) 75 Expect(len(ps.Volumes)).To(Equal(1)) 76 }) 77 78 It("should succeed in normal test case, where one volume is added", func() { 79 volumes["my_config"] = appsv1alpha1.ComponentTemplateSpec{ 80 Name: "myConfig", 81 TemplateRef: "myConfig", 82 VolumeName: "myConfigVolume", 83 } 84 ps := &sts.Spec.Template.Spec 85 err := CreateOrUpdatePodVolumes(ps, volumes) 86 Expect(err).Should(BeNil()) 87 Expect(len(ps.Volumes)).To(Equal(2)) 88 }) 89 90 It("should succeed in normal test case, where two volumes are added", func() { 91 volumes["my_config"] = appsv1alpha1.ComponentTemplateSpec{ 92 Name: "myConfig", 93 TemplateRef: "myConfig", 94 VolumeName: "myConfigVolume", 95 } 96 volumes["my_config1"] = appsv1alpha1.ComponentTemplateSpec{ 97 Name: "myConfig", 98 TemplateRef: "myConfig", 99 VolumeName: "myConfigVolume2", 100 } 101 ps := &sts.Spec.Template.Spec 102 err := CreateOrUpdatePodVolumes(ps, volumes) 103 Expect(err).Should(BeNil()) 104 Expect(len(ps.Volumes)).To(Equal(3)) 105 }) 106 107 It("should fail if updated volume doesn't contain ConfigMap", func() { 108 const ( 109 cmName = "my_config_for_test" 110 replicaVolumeName = "mytest-cm-volume_for_test" 111 ) 112 sts.Spec.Template.Spec.Volumes = append(sts.Spec.Template.Spec.Volumes, 113 corev1.Volume{ 114 Name: replicaVolumeName, 115 VolumeSource: corev1.VolumeSource{ 116 EmptyDir: &corev1.EmptyDirVolumeSource{}, 117 }, 118 }) 119 volumes[cmName] = appsv1alpha1.ComponentTemplateSpec{ 120 Name: "configTplName", 121 TemplateRef: "configTplName", 122 VolumeName: replicaVolumeName, 123 } 124 ps := &sts.Spec.Template.Spec 125 Expect(CreateOrUpdatePodVolumes(ps, volumes)).ShouldNot(Succeed()) 126 }) 127 128 It("should succeed if updated volume contains ConfigMap", func() { 129 const ( 130 cmName = "my_config_for_isv" 131 replicaVolumeName = "mytest-cm-volume_for_isv" 132 ) 133 134 // mock clusterdefinition has volume 135 sts.Spec.Template.Spec.Volumes = append(sts.Spec.Template.Spec.Volumes, 136 corev1.Volume{ 137 Name: replicaVolumeName, 138 VolumeSource: corev1.VolumeSource{ 139 ConfigMap: &corev1.ConfigMapVolumeSource{ 140 LocalObjectReference: corev1.LocalObjectReference{Name: "anything"}, 141 }, 142 }, 143 }) 144 145 volumes[cmName] = appsv1alpha1.ComponentTemplateSpec{ 146 Name: "configTplName", 147 TemplateRef: "configTplName", 148 VolumeName: replicaVolumeName, 149 } 150 ps := &sts.Spec.Template.Spec 151 err := CreateOrUpdatePodVolumes(ps, volumes) 152 Expect(err).Should(BeNil()) 153 Expect(len(sts.Spec.Template.Spec.Volumes)).To(Equal(2)) 154 volume := GetVolumeMountName(sts.Spec.Template.Spec.Volumes, cmName) 155 Expect(volume).ShouldNot(BeNil()) 156 Expect(volume.ConfigMap).ShouldNot(BeNil()) 157 Expect(volume.ConfigMap.Name).Should(BeEquivalentTo(cmName)) 158 Expect(volume.Name).Should(BeEquivalentTo(replicaVolumeName)) 159 }) 160 161 }) 162 })