github.com/lfch/etcd-io/tests/v3@v3.0.0-20221004140520-eac99acd3e9d/functional/tester/stresser.go (about) 1 // Copyright 2018 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tester 16 17 import ( 18 "fmt" 19 "time" 20 21 "github.com/lfch/etcd-io/tests/v3/functional/rpcpb" 22 23 "go.uber.org/zap" 24 ) 25 26 // Stresser defines stressing client operations. 27 type Stresser interface { 28 // Stress starts to stress the etcd cluster 29 Stress() error 30 // Pause stops the stresser from sending requests to etcd. Resume by calling Stress. 31 Pause() map[string]int 32 // Close releases all of the Stresser's resources. 33 Close() map[string]int 34 // ModifiedKeys reports the number of keys created and deleted by stresser 35 ModifiedKeys() int64 36 } 37 38 // newStresser creates stresser from a comma separated list of stresser types. 39 func newStresser(clus *Cluster, m *rpcpb.Member) (stressers []Stresser) { 40 // TODO: Too intensive stressing clients can panic etcd member with 41 // 'out of memory' error. Put rate limits in server side. 42 ks := &keyStresser{ 43 lg: clus.lg, 44 m: m, 45 keySize: int(clus.Tester.StressKeySize), 46 keyLargeSize: int(clus.Tester.StressKeySizeLarge), 47 keySuffixRange: int(clus.Tester.StressKeySuffixRange), 48 keyTxnSuffixRange: int(clus.Tester.StressKeySuffixRangeTxn), 49 keyTxnOps: int(clus.Tester.StressKeyTxnOps), 50 clientsN: int(clus.Tester.StressClients), 51 rateLimiter: clus.rateLimiter, 52 } 53 ksExist := false 54 55 for _, s := range clus.Tester.Stressers { 56 clus.lg.Info( 57 "creating stresser", 58 zap.String("type", s.Type), 59 zap.Float64("weight", s.Weight), 60 zap.String("endpoint", m.EtcdClientEndpoint), 61 ) 62 switch s.Type { 63 case "KV_WRITE_SMALL": 64 ksExist = true 65 ks.weightKVWriteSmall = s.Weight 66 case "KV_WRITE_LARGE": 67 ksExist = true 68 ks.weightKVWriteLarge = s.Weight 69 case "KV_READ_ONE_KEY": 70 ksExist = true 71 ks.weightKVReadOneKey = s.Weight 72 case "KV_READ_RANGE": 73 ksExist = true 74 ks.weightKVReadRange = s.Weight 75 case "KV_DELETE_ONE_KEY": 76 ksExist = true 77 ks.weightKVDeleteOneKey = s.Weight 78 case "KV_DELETE_RANGE": 79 ksExist = true 80 ks.weightKVDeleteRange = s.Weight 81 case "KV_TXN_WRITE_DELETE": 82 ksExist = true 83 ks.weightKVTxnWriteDelete = s.Weight 84 85 case "LEASE": 86 stressers = append(stressers, &leaseStresser{ 87 stype: rpcpb.StresserType_LEASE, 88 lg: clus.lg, 89 m: m, 90 numLeases: 10, // TODO: configurable 91 keysPerLease: 10, // TODO: configurable 92 rateLimiter: clus.rateLimiter, 93 }) 94 95 case "ELECTION_RUNNER": 96 reqRate := 100 97 args := []string{ 98 "election", 99 fmt.Sprintf("%v", time.Now().UnixNano()), // election name as current nano time 100 "--dial-timeout=10s", 101 "--endpoints", m.EtcdClientEndpoint, 102 "--total-client-connections=10", 103 "--rounds=0", // runs forever 104 "--req-rate", fmt.Sprintf("%v", reqRate), 105 } 106 stressers = append(stressers, newRunnerStresser( 107 rpcpb.StresserType_ELECTION_RUNNER, 108 m.EtcdClientEndpoint, 109 clus.lg, 110 clus.Tester.RunnerExecPath, 111 args, 112 clus.rateLimiter, 113 reqRate, 114 )) 115 116 case "WATCH_RUNNER": 117 reqRate := 100 118 args := []string{ 119 "watcher", 120 "--prefix", fmt.Sprintf("%v", time.Now().UnixNano()), // prefix all keys with nano time 121 "--total-keys=1", 122 "--total-prefixes=1", 123 "--watch-per-prefix=1", 124 "--endpoints", m.EtcdClientEndpoint, 125 "--rounds=0", // runs forever 126 "--req-rate", fmt.Sprintf("%v", reqRate), 127 } 128 stressers = append(stressers, newRunnerStresser( 129 rpcpb.StresserType_WATCH_RUNNER, 130 m.EtcdClientEndpoint, 131 clus.lg, 132 clus.Tester.RunnerExecPath, 133 args, 134 clus.rateLimiter, 135 reqRate, 136 )) 137 138 case "LOCK_RACER_RUNNER": 139 reqRate := 100 140 args := []string{ 141 "lock-racer", 142 fmt.Sprintf("%v", time.Now().UnixNano()), // locker name as current nano time 143 "--endpoints", m.EtcdClientEndpoint, 144 "--total-client-connections=10", 145 "--rounds=0", // runs forever 146 "--req-rate", fmt.Sprintf("%v", reqRate), 147 } 148 stressers = append(stressers, newRunnerStresser( 149 rpcpb.StresserType_LOCK_RACER_RUNNER, 150 m.EtcdClientEndpoint, 151 clus.lg, 152 clus.Tester.RunnerExecPath, 153 args, 154 clus.rateLimiter, 155 reqRate, 156 )) 157 158 case "LEASE_RUNNER": 159 args := []string{ 160 "lease-renewer", 161 "--ttl=30", 162 "--endpoints", m.EtcdClientEndpoint, 163 } 164 stressers = append(stressers, newRunnerStresser( 165 rpcpb.StresserType_LEASE_RUNNER, 166 m.EtcdClientEndpoint, 167 clus.lg, 168 clus.Tester.RunnerExecPath, 169 args, 170 clus.rateLimiter, 171 0, 172 )) 173 } 174 } 175 176 if ksExist { 177 return append(stressers, ks) 178 } 179 return stressers 180 }