github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controller/model/transform_utils_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 model 21 22 import ( 23 "context" 24 "time" 25 26 . "github.com/onsi/ginkgo/v2" 27 . "github.com/onsi/gomega" 28 29 "github.com/go-logr/logr" 30 "github.com/golang/mock/gomock" 31 apps "k8s.io/api/apps/v1" 32 corev1 "k8s.io/api/core/v1" 33 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 34 "k8s.io/client-go/tools/record" 35 "sigs.k8s.io/controller-runtime/pkg/client" 36 37 "github.com/1aal/kubeblocks/pkg/controller/builder" 38 roclient "github.com/1aal/kubeblocks/pkg/controller/client" 39 "github.com/1aal/kubeblocks/pkg/controller/graph" 40 testutil "github.com/1aal/kubeblocks/pkg/testutil/k8s" 41 ) 42 43 var _ = Describe("transform utils test", func() { 44 const ( 45 namespace = "foo" 46 name = "bar" 47 ) 48 49 Context("FindRootVertex function", func() { 50 It("should work well", func() { 51 dag := graph.NewDAG() 52 _, err := FindRootVertex(dag) 53 Expect(err).ShouldNot(BeNil()) 54 Expect(err.Error()).Should(ContainSubstring("root vertex not found")) 55 56 root := builder.NewStatefulSetBuilder(namespace, name).GetObject() 57 obj0 := builder.NewPodBuilder(namespace, name+"-0").GetObject() 58 obj1 := builder.NewPodBuilder(namespace, name+"-1").GetObject() 59 obj2 := builder.NewPodBuilder(namespace, name+"-2").GetObject() 60 dag.AddVertex(&ObjectVertex{Obj: root}) 61 dag.AddConnectRoot(&ObjectVertex{Obj: obj0}) 62 dag.AddConnectRoot(&ObjectVertex{Obj: obj1}) 63 dag.AddConnectRoot(&ObjectVertex{Obj: obj2}) 64 65 rootVertex, err := FindRootVertex(dag) 66 Expect(err).Should(BeNil()) 67 Expect(rootVertex.Obj).Should(Equal(root)) 68 }) 69 }) 70 71 Context("IsOwnerOf function", func() { 72 It("should work well", func() { 73 ownerAPIVersion := "apps/v1" 74 ownerKind := "StatefulSet" 75 objectName := name + "-0" 76 owner := builder.NewStatefulSetBuilder(namespace, name).GetObject() 77 object := builder.NewPodBuilder(namespace, objectName). 78 SetOwnerReferences(ownerAPIVersion, ownerKind, owner). 79 GetObject() 80 Expect(IsOwnerOf(owner, object)).Should(BeTrue()) 81 82 }) 83 }) 84 85 Context("NewRequeueError function", func() { 86 It("should work well", func() { 87 after := 17 * time.Second 88 reason := "something really bad happens" 89 err := NewRequeueError(after, reason) 90 reqErr, ok := err.(RequeueError) 91 Expect(ok).Should(BeTrue()) 92 Expect(reqErr.RequeueAfter()).Should(Equal(after)) 93 Expect(reqErr.Reason()).Should(Equal(reason)) 94 Expect(err.Error()).Should(ContainSubstring("requeue after:")) 95 }) 96 }) 97 98 Context("test IsObjectDoing", func() { 99 It("should work well", func() { 100 object := &apps.StatefulSet{} 101 By("set generation equal") 102 object.Generation = 1 103 object.Status.ObservedGeneration = 1 104 Expect(IsObjectUpdating(object)).Should(BeFalse()) 105 Expect(IsObjectStatusUpdating(object)).Should(BeTrue()) 106 107 By("set generation not equal") 108 object.Generation = 2 109 object.Status.ObservedGeneration = 1 110 Expect(IsObjectUpdating(object)).Should(BeTrue()) 111 112 By("set deletionTimestamp") 113 ts := metav1.NewTime(time.Now()) 114 object.DeletionTimestamp = &ts 115 Expect(IsObjectDeleting(object)).Should(BeTrue()) 116 117 By("set fields not exist") 118 object2 := &corev1.Secret{} 119 Expect(IsObjectUpdating(object2)).Should(BeFalse()) 120 }) 121 }) 122 123 Context("ReadCacheSnapshot function", func() { 124 It("should work well", func() { 125 controller, k8sMock := testutil.SetupK8sMock() 126 defer controller.Finish() 127 128 root := builder.NewStatefulSetBuilder(namespace, name).GetObject() 129 obj0 := builder.NewPodBuilder(namespace, name+"-0").GetObject() 130 obj1 := builder.NewPodBuilder(namespace, name+"-1").GetObject() 131 obj2 := builder.NewPodBuilder(namespace, name+"-2").GetObject() 132 133 k8sMock.EXPECT(). 134 List(gomock.Any(), &corev1.PodList{}, gomock.Any()). 135 DoAndReturn(func(_ context.Context, list *corev1.PodList, _ ...client.ListOption) error { 136 Expect(list).ShouldNot(BeNil()) 137 list.Items = []corev1.Pod{*obj0, *obj1, *obj2} 138 return nil 139 }).Times(1) 140 transCtx := &testTransCtx{ 141 Context: context.Background(), 142 GraphClient: NewGraphClient(k8sMock), 143 } 144 snapshot, err := ReadCacheSnapshot(transCtx, root, nil, &corev1.PodList{}) 145 Expect(err).Should(BeNil()) 146 Expect(snapshot).Should(HaveLen(3)) 147 objList := []*corev1.Pod{obj0, obj1, obj2} 148 for _, pod := range objList { 149 gvk, err := GetGVKName(pod) 150 Expect(err).Should(BeNil()) 151 obj, ok := snapshot[*gvk] 152 Expect(ok).Should(BeTrue()) 153 p, ok := obj.(*corev1.Pod) 154 Expect(ok).Should(BeTrue()) 155 Expect(p).Should(Equal(pod)) 156 } 157 }) 158 }) 159 }) 160 161 type testTransCtx struct { 162 context.Context 163 GraphClient 164 } 165 166 var _ graph.TransformContext = &testTransCtx{} 167 168 func (t *testTransCtx) GetContext() context.Context { 169 return t.Context 170 } 171 172 func (t *testTransCtx) GetClient() roclient.ReadonlyClient { 173 return t.GraphClient 174 } 175 176 func (t *testTransCtx) GetRecorder() record.EventRecorder { 177 // TODO implement me 178 panic("implement me") 179 } 180 181 func (t *testTransCtx) GetLogger() logr.Logger { 182 // TODO implement me 183 panic("implement me") 184 }