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 15package tester 16 17import ( 18 "reflect" 19 "sort" 20 "testing" 21 22 "go.etcd.io/etcd/functional/rpcpb" 23 24 "go.uber.org/zap" 25) 26 27func Test_read(t *testing.T) { 28 exp := &Cluster{ 29 Members: []*rpcpb.Member{ 30 { 31 EtcdExec: "./bin/etcd", 32 AgentAddr: "127.0.0.1:19027", 33 FailpointHTTPAddr: "http://127.0.0.1:7381", 34 BaseDir: "/tmp/etcd-functional-1", 35 EtcdClientProxy: false, 36 EtcdPeerProxy: true, 37 EtcdClientEndpoint: "127.0.0.1:1379", 38 Etcd: &rpcpb.Etcd{ 39 Name: "s1", 40 DataDir: "/tmp/etcd-functional-1/etcd.data", 41 WALDir: "/tmp/etcd-functional-1/etcd.data/member/wal", 42 HeartbeatIntervalMs: 100, 43 ElectionTimeoutMs: 1000, 44 ListenClientURLs: []string{"https://127.0.0.1:1379"}, 45 AdvertiseClientURLs: []string{"https://127.0.0.1:1379"}, 46 ClientAutoTLS: true, 47 ClientCertAuth: false, 48 ClientCertFile: "", 49 ClientKeyFile: "", 50 ClientTrustedCAFile: "", 51 ListenPeerURLs: []string{"https://127.0.0.1:1380"}, 52 AdvertisePeerURLs: []string{"https://127.0.0.1:1381"}, 53 PeerAutoTLS: true, 54 PeerClientCertAuth: false, 55 PeerCertFile: "", 56 PeerKeyFile: "", 57 PeerTrustedCAFile: "", 58 InitialCluster: "s1=https://127.0.0.1:1381,s2=https://127.0.0.1:2381,s3=https://127.0.0.1:3381", 59 InitialClusterState: "new", 60 InitialClusterToken: "tkn", 61 SnapshotCount: 10000, 62 QuotaBackendBytes: 10740000000, 63 PreVote: true, 64 InitialCorruptCheck: true, 65 Logger: "zap", 66 LogOutputs: []string{"/tmp/etcd-functional-1/etcd.log"}, 67 }, 68 ClientCertData: "", 69 ClientCertPath: "", 70 ClientKeyData: "", 71 ClientKeyPath: "", 72 ClientTrustedCAData: "", 73 ClientTrustedCAPath: "", 74 PeerCertData: "", 75 PeerCertPath: "", 76 PeerKeyData: "", 77 PeerKeyPath: "", 78 PeerTrustedCAData: "", 79 PeerTrustedCAPath: "", 80 SnapshotPath: "/tmp/etcd-functional-1.snapshot.db", 81 }, 82 { 83 EtcdExec: "./bin/etcd", 84 AgentAddr: "127.0.0.1:29027", 85 FailpointHTTPAddr: "http://127.0.0.1:7382", 86 BaseDir: "/tmp/etcd-functional-2", 87 EtcdClientProxy: false, 88 EtcdPeerProxy: true, 89 EtcdClientEndpoint: "127.0.0.1:2379", 90 Etcd: &rpcpb.Etcd{ 91 Name: "s2", 92 DataDir: "/tmp/etcd-functional-2/etcd.data", 93 WALDir: "/tmp/etcd-functional-2/etcd.data/member/wal", 94 HeartbeatIntervalMs: 100, 95 ElectionTimeoutMs: 1000, 96 ListenClientURLs: []string{"https://127.0.0.1:2379"}, 97 AdvertiseClientURLs: []string{"https://127.0.0.1:2379"}, 98 ClientAutoTLS: true, 99 ClientCertAuth: false, 100 ClientCertFile: "", 101 ClientKeyFile: "", 102 ClientTrustedCAFile: "", 103 ListenPeerURLs: []string{"https://127.0.0.1:2380"}, 104 AdvertisePeerURLs: []string{"https://127.0.0.1:2381"}, 105 PeerAutoTLS: true, 106 PeerClientCertAuth: false, 107 PeerCertFile: "", 108 PeerKeyFile: "", 109 PeerTrustedCAFile: "", 110 InitialCluster: "s1=https://127.0.0.1:1381,s2=https://127.0.0.1:2381,s3=https://127.0.0.1:3381", 111 InitialClusterState: "new", 112 InitialClusterToken: "tkn", 113 SnapshotCount: 10000, 114 QuotaBackendBytes: 10740000000, 115 PreVote: true, 116 InitialCorruptCheck: true, 117 Logger: "zap", 118 LogOutputs: []string{"/tmp/etcd-functional-2/etcd.log"}, 119 }, 120 ClientCertData: "", 121 ClientCertPath: "", 122 ClientKeyData: "", 123 ClientKeyPath: "", 124 ClientTrustedCAData: "", 125 ClientTrustedCAPath: "", 126 PeerCertData: "", 127 PeerCertPath: "", 128 PeerKeyData: "", 129 PeerKeyPath: "", 130 PeerTrustedCAData: "", 131 PeerTrustedCAPath: "", 132 SnapshotPath: "/tmp/etcd-functional-2.snapshot.db", 133 }, 134 { 135 EtcdExec: "./bin/etcd", 136 AgentAddr: "127.0.0.1:39027", 137 FailpointHTTPAddr: "http://127.0.0.1:7383", 138 BaseDir: "/tmp/etcd-functional-3", 139 EtcdClientProxy: false, 140 EtcdPeerProxy: true, 141 EtcdClientEndpoint: "127.0.0.1:3379", 142 Etcd: &rpcpb.Etcd{ 143 Name: "s3", 144 DataDir: "/tmp/etcd-functional-3/etcd.data", 145 WALDir: "/tmp/etcd-functional-3/etcd.data/member/wal", 146 HeartbeatIntervalMs: 100, 147 ElectionTimeoutMs: 1000, 148 ListenClientURLs: []string{"https://127.0.0.1:3379"}, 149 AdvertiseClientURLs: []string{"https://127.0.0.1:3379"}, 150 ClientAutoTLS: true, 151 ClientCertAuth: false, 152 ClientCertFile: "", 153 ClientKeyFile: "", 154 ClientTrustedCAFile: "", 155 ListenPeerURLs: []string{"https://127.0.0.1:3380"}, 156 AdvertisePeerURLs: []string{"https://127.0.0.1:3381"}, 157 PeerAutoTLS: true, 158 PeerClientCertAuth: false, 159 PeerCertFile: "", 160 PeerKeyFile: "", 161 PeerTrustedCAFile: "", 162 InitialCluster: "s1=https://127.0.0.1:1381,s2=https://127.0.0.1:2381,s3=https://127.0.0.1:3381", 163 InitialClusterState: "new", 164 InitialClusterToken: "tkn", 165 SnapshotCount: 10000, 166 QuotaBackendBytes: 10740000000, 167 PreVote: true, 168 InitialCorruptCheck: true, 169 Logger: "zap", 170 LogOutputs: []string{"/tmp/etcd-functional-3/etcd.log"}, 171 }, 172 ClientCertData: "", 173 ClientCertPath: "", 174 ClientKeyData: "", 175 ClientKeyPath: "", 176 ClientTrustedCAData: "", 177 ClientTrustedCAPath: "", 178 PeerCertData: "", 179 PeerCertPath: "", 180 PeerKeyData: "", 181 PeerKeyPath: "", 182 PeerTrustedCAData: "", 183 PeerTrustedCAPath: "", 184 SnapshotPath: "/tmp/etcd-functional-3.snapshot.db", 185 }, 186 }, 187 Tester: &rpcpb.Tester{ 188 DataDir: "/tmp/etcd-tester-data", 189 Network: "tcp", 190 Addr: "127.0.0.1:9028", 191 DelayLatencyMs: 5000, 192 DelayLatencyMsRv: 500, 193 UpdatedDelayLatencyMs: 5000, 194 RoundLimit: 1, 195 ExitOnCaseFail: true, 196 EnablePprof: true, 197 CaseDelayMs: 7000, 198 CaseShuffle: true, 199 Cases: []string{ 200 "SIGTERM_ONE_FOLLOWER", 201 "SIGTERM_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT", 202 "SIGTERM_LEADER", 203 "SIGTERM_LEADER_UNTIL_TRIGGER_SNAPSHOT", 204 "SIGTERM_QUORUM", 205 "SIGTERM_ALL", 206 "SIGQUIT_AND_REMOVE_ONE_FOLLOWER", 207 "SIGQUIT_AND_REMOVE_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT", 208 // "SIGQUIT_AND_REMOVE_LEADER", 209 // "SIGQUIT_AND_REMOVE_LEADER_UNTIL_TRIGGER_SNAPSHOT", 210 // "SIGQUIT_AND_REMOVE_QUORUM_AND_RESTORE_LEADER_SNAPSHOT_FROM_SCRATCH", 211 // "BLACKHOLE_PEER_PORT_TX_RX_ONE_FOLLOWER", 212 // "BLACKHOLE_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT", 213 "BLACKHOLE_PEER_PORT_TX_RX_LEADER", 214 "BLACKHOLE_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT", 215 "BLACKHOLE_PEER_PORT_TX_RX_QUORUM", 216 "BLACKHOLE_PEER_PORT_TX_RX_ALL", 217 // "DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER", 218 // "RANDOM_DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER", 219 // "DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT", 220 // "RANDOM_DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT", 221 "DELAY_PEER_PORT_TX_RX_LEADER", 222 "RANDOM_DELAY_PEER_PORT_TX_RX_LEADER", 223 "DELAY_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT", 224 "RANDOM_DELAY_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT", 225 "DELAY_PEER_PORT_TX_RX_QUORUM", 226 "RANDOM_DELAY_PEER_PORT_TX_RX_QUORUM", 227 "DELAY_PEER_PORT_TX_RX_ALL", 228 "RANDOM_DELAY_PEER_PORT_TX_RX_ALL", 229 "NO_FAIL_WITH_STRESS", 230 "NO_FAIL_WITH_NO_STRESS_FOR_LIVENESS", 231 }, 232 FailpointCommands: []string{`panic("etcd-tester")`}, 233 RunnerExecPath: "./bin/etcd-runner", 234 ExternalExecPath: "", 235 Stressers: []*rpcpb.Stresser{ 236 {Type: "KV_WRITE_SMALL", Weight: 0.35}, 237 {Type: "KV_WRITE_LARGE", Weight: 0.002}, 238 {Type: "KV_READ_ONE_KEY", Weight: 0.07}, 239 {Type: "KV_READ_RANGE", Weight: 0.07}, 240 {Type: "KV_DELETE_ONE_KEY", Weight: 0.07}, 241 {Type: "KV_DELETE_RANGE", Weight: 0.07}, 242 {Type: "KV_TXN_WRITE_DELETE", Weight: 0.35}, 243 {Type: "LEASE", Weight: 0.0}, 244 }, 245 Checkers: []string{"KV_HASH", "LEASE_EXPIRE"}, 246 StressKeySize: 100, 247 StressKeySizeLarge: 32769, 248 StressKeySuffixRange: 250000, 249 StressKeySuffixRangeTxn: 100, 250 StressKeyTxnOps: 10, 251 StressClients: 100, 252 StressQPS: 2000, 253 }, 254 } 255 256 logger, err := zap.NewProduction() 257 if err != nil { 258 t.Fatal(err) 259 } 260 defer logger.Sync() 261 262 cfg, err := read(logger, "../../functional.yaml") 263 if err != nil { 264 t.Fatal(err) 265 } 266 cfg.lg = nil 267 268 if !reflect.DeepEqual(exp, cfg) { 269 t.Fatalf("expected %+v, got %+v", exp, cfg) 270 } 271 272 cfg.lg = logger 273 274 cfg.updateCases() 275 fs1 := cfg.listCases() 276 277 cfg.shuffleCases() 278 fs2 := cfg.listCases() 279 if reflect.DeepEqual(fs1, fs2) { 280 t.Fatalf("expected shuffled failure cases, got %q", fs2) 281 } 282 283 cfg.shuffleCases() 284 fs3 := cfg.listCases() 285 if reflect.DeepEqual(fs2, fs3) { 286 t.Fatalf("expected reshuffled failure cases from %q, got %q", fs2, fs3) 287 } 288 289 // shuffle ensures visit all exactly once 290 // so when sorted, failure cases must be equal 291 sort.Strings(fs1) 292 sort.Strings(fs2) 293 sort.Strings(fs3) 294 295 if !reflect.DeepEqual(fs1, fs2) { 296 t.Fatalf("expected %q, got %q", fs1, fs2) 297 } 298 if !reflect.DeepEqual(fs2, fs3) { 299 t.Fatalf("expected %q, got %q", fs2, fs3) 300 } 301} 302