github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/bench/bench_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 bench 21 22 import ( 23 "fmt" 24 "net/http" 25 26 . "github.com/onsi/ginkgo/v2" 27 . "github.com/onsi/gomega" 28 29 corev1 "k8s.io/api/core/v1" 30 "k8s.io/apimachinery/pkg/runtime" 31 "k8s.io/apimachinery/pkg/runtime/schema" 32 "k8s.io/cli-runtime/pkg/genericiooptions" 33 "k8s.io/cli-runtime/pkg/resource" 34 "k8s.io/client-go/kubernetes/scheme" 35 clientfake "k8s.io/client-go/rest/fake" 36 cmdtesting "k8s.io/kubectl/pkg/cmd/testing" 37 38 "github.com/1aal/kubeblocks/pkg/cli/testing" 39 "github.com/1aal/kubeblocks/pkg/cli/types" 40 ) 41 42 var _ = Describe("bench", func() { 43 const ( 44 namespace = "default" 45 clusterName = "test" 46 ) 47 48 var ( 49 tf *cmdtesting.TestFactory 50 streams genericiooptions.IOStreams 51 cluster = testing.FakeCluster(clusterName, namespace) 52 pods = testing.FakePods(3, namespace, clusterName) 53 ) 54 BeforeEach(func() { 55 streams, _, _, _ = genericiooptions.NewTestIOStreams() 56 tf = cmdtesting.NewTestFactory().WithNamespace(namespace) 57 tf.Client = &clientfake.RESTClient{} 58 tf.FakeDynamicClient = testing.FakeDynamicClient() 59 codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) 60 httpResp := func(obj runtime.Object) *http.Response { 61 return &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, obj)} 62 } 63 64 tf.UnstructuredClient = &clientfake.RESTClient{ 65 GroupVersion: schema.GroupVersion{Group: types.AppsAPIGroup, Version: types.AppsAPIVersion}, 66 NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer, 67 Client: clientfake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { 68 urlPrefix := "/api/v1/namespaces/" + namespace 69 mapping := map[string]*http.Response{ 70 "/api/v1/nodes/" + testing.NodeName: httpResp(testing.FakeNode()), 71 urlPrefix + "/services": httpResp(&corev1.ServiceList{}), 72 urlPrefix + "/events": httpResp(&corev1.EventList{}), 73 urlPrefix + "/persistentvolumeclaims": httpResp(&corev1.PersistentVolumeClaimList{}), 74 urlPrefix + "/pods": httpResp(pods), 75 } 76 return mapping[req.URL.Path], nil 77 }), 78 } 79 80 tf.Client = tf.UnstructuredClient 81 tf.FakeDynamicClient = testing.FakeDynamicClient(cluster, testing.FakeClusterDef(), testing.FakeClusterVersion()) 82 }) 83 84 AfterEach(func() { 85 tf.Cleanup() 86 }) 87 88 It("bench command", func() { 89 cmd := NewBenchCmd(tf, streams) 90 Expect(cmd != nil).Should(BeTrue()) 91 Expect(cmd.HasSubCommands()).Should(BeTrue()) 92 }) 93 94 It("sysbench command", func() { 95 cmd := NewSysBenchCmd(tf, streams) 96 Expect(cmd != nil).Should(BeTrue()) 97 }) 98 99 It("test sysbench run", func() { 100 o := &SysBenchOptions{ 101 BenchBaseOptions: BenchBaseOptions{ 102 Driver: "mysql", 103 Database: "test", 104 Host: "svc-1", 105 Port: 3306, 106 User: "test", 107 Password: "test", 108 factory: tf, 109 namespace: namespace, 110 IOStreams: streams, 111 }, 112 Type: []string{"oltp_read_only"}, 113 Tables: 1, 114 Size: 100, 115 Duration: 60, 116 } 117 Expect(o.Complete([]string{})).Should(BeNil()) 118 Expect(o.Validate()).ShouldNot(BeNil()) 119 Expect(o.Run()).Should(BeNil()) 120 }) 121 122 It("pgbench command", func() { 123 cmd := NewPgBenchCmd(tf, streams) 124 Expect(cmd != nil).Should(BeTrue()) 125 }) 126 127 It("test pgbench run", func() { 128 o := &PgBenchOptions{ 129 BenchBaseOptions: BenchBaseOptions{ 130 Driver: pgBenchDriver, 131 Database: "test", 132 Host: "svc-1", 133 Port: 3306, 134 User: "test", 135 Password: "test", 136 factory: tf, 137 namespace: namespace, 138 IOStreams: streams, 139 }, 140 Scale: 100, 141 Clients: []int{1}, 142 } 143 Expect(o.Complete([]string{})).Should(BeNil()) 144 Expect(o.Validate()).ShouldNot(BeNil()) 145 Expect(o.Run()).Should(BeNil()) 146 }) 147 148 It("ycsb command", func() { 149 cmd := NewYcsbCmd(tf, streams) 150 Expect(cmd != nil).Should(BeTrue()) 151 }) 152 153 It("test ycsb run", func() { 154 o := &YcsbOptions{ 155 BenchBaseOptions: BenchBaseOptions{ 156 Driver: "mysql", 157 Database: "test", 158 Host: "svc-1", 159 Port: 3306, 160 User: "test", 161 Password: "test", 162 factory: tf, 163 namespace: namespace, 164 IOStreams: streams, 165 }, 166 RecordCount: 1000, 167 OperationCount: 1000, 168 Threads: []int{1}, 169 } 170 Expect(o.Complete([]string{})).Should(BeNil()) 171 Expect(o.Validate()).ShouldNot(BeNil()) 172 Expect(o.Run()).Should(BeNil()) 173 }) 174 175 It("parse driver and endpoint", func() { 176 driver, host, port, err := getDriverAndHostAndPort(cluster, testing.FakeServices()) 177 Expect(err).Should(BeNil()) 178 Expect(driver).Should(Equal(testing.ComponentName)) 179 Expect(host).Should(Equal(fmt.Sprintf("svc-1.%s.svc.cluster.local", testing.Namespace))) 180 Expect(port).Should(Equal(3306)) 181 }) 182 183 It("parse tolerations", func() { 184 o := &BenchBaseOptions{ 185 TolerationsRaw: []string{"dev=true:NoSchedule,large:NoSchedule"}, 186 } 187 err := o.BaseComplete() 188 Expect(err).Should(BeNil()) 189 Expect(o.Tolerations).Should(Equal([]corev1.Toleration{ 190 {Key: "dev", Operator: corev1.TolerationOpEqual, Value: "true", Effect: corev1.TaintEffectNoSchedule}, 191 {Key: "large", Operator: corev1.TolerationOpExists, Effect: corev1.TaintEffectNoSchedule}, 192 })) 193 }) 194 })