github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/lorry/engines/etcd/suite_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 etcd 21 22 import ( 23 "errors" 24 "net/url" 25 "os" 26 "testing" 27 "time" 28 29 "github.com/go-logr/logr" 30 "github.com/golang/mock/gomock" 31 . "github.com/onsi/ginkgo/v2" 32 . "github.com/onsi/gomega" 33 "github.com/spf13/viper" 34 clientv3 "go.etcd.io/etcd/client/v3" 35 "go.etcd.io/etcd/server/v3/embed" 36 "go.etcd.io/etcd/server/v3/etcdserver/api/v3client" 37 ctrl "sigs.k8s.io/controller-runtime" 38 "sigs.k8s.io/controller-runtime/pkg/log/zap" 39 40 "github.com/1aal/kubeblocks/pkg/lorry/dcs" 41 ) 42 43 const ( 44 etcdStartTimeout = 30 45 ) 46 47 var ( 48 dcsStore dcs.DCS 49 mockDCSStore *dcs.MockDCS 50 etcdServer *EmbeddedETCD 51 ) 52 53 func init() { 54 viper.AutomaticEnv() 55 viper.SetDefault("KB_POD_NAME", "pod-test-0") 56 viper.SetDefault("KB_CLUSTER_COMP_NAME", "cluster-component-test") 57 viper.SetDefault("KB_NAMESPACE", "namespace-test") 58 ctrl.SetLogger(zap.New()) 59 } 60 61 func TestETCDDBManager(t *testing.T) { 62 RegisterFailHandler(Fail) 63 RunSpecs(t, "ETCD DBManager. Suite") 64 } 65 66 var _ = BeforeSuite(func() { 67 // Init mock dcs store 68 InitMockDCSStore() 69 70 // Start ETCD Server 71 // server, err := StartEtcdServer() 72 // Expect(err).Should(BeNil()) 73 // etcdServer = server 74 }) 75 76 var _ = AfterSuite(func() { 77 StopEtcdServer(etcdServer) 78 }) 79 80 func InitMockDCSStore() { 81 ctrl := gomock.NewController(GinkgoT()) 82 mockDCSStore = dcs.NewMockDCS(ctrl) 83 mockDCSStore.EXPECT().GetClusterFromCache().Return(&dcs.Cluster{}).AnyTimes() 84 dcs.SetStore(mockDCSStore) 85 dcsStore = mockDCSStore 86 } 87 88 func StartEtcdServer() (*EmbeddedETCD, error) { 89 peerAddress := "http://localhost:0" 90 91 etcdServer := &EmbeddedETCD{} 92 logger := ctrl.Log.WithName("ETCD server") 93 etcdServer.logger = logger 94 return etcdServer, etcdServer.Start(peerAddress) 95 } 96 97 func StopEtcdServer(etcdServer *EmbeddedETCD) { 98 if etcdServer != nil { 99 etcdServer.Stop() 100 } 101 } 102 103 type EmbeddedETCD struct { 104 logger logr.Logger 105 tmpDir string 106 ETCD *embed.Etcd 107 client *clientv3.Client 108 } 109 110 // Start starts embedded ETCD. 111 func (e *EmbeddedETCD) Start(peerAddress string) error { 112 dir, err := os.MkdirTemp("", "ETCD") 113 if err != nil { 114 return err 115 } 116 117 cfg := embed.NewConfig() 118 cfg.Dir = dir 119 lpurl, _ := url.Parse("http://localhost:0") 120 lcurl, _ := url.Parse(peerAddress) 121 cfg.ListenPeerUrls = []url.URL{*lpurl} 122 cfg.ListenClientUrls = []url.URL{*lcurl} 123 e.ETCD, err = embed.StartEtcd(cfg) 124 if err != nil { 125 return err 126 } 127 128 select { 129 case <-e.ETCD.Server.ReadyNotify(): 130 e.logger.Info("ETCD Server is ready!") 131 case <-time.After(etcdStartTimeout * time.Second): 132 e.ETCD.Server.Stop() // trigger a shutdown 133 return errors.New("start embedded etcd server timeout") 134 } 135 e.client = v3client.New(e.ETCD.Server) 136 137 return nil 138 } 139 140 // Stop stops the embedded ETCD & cleanups the tmp dir. 141 func (e *EmbeddedETCD) Stop() { 142 e.ETCD.Close() 143 e.ETCD.Server.Stop() 144 os.RemoveAll(e.tmpDir) 145 }