cluster_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. package tester
  15. import (
  16. "reflect"
  17. "sort"
  18. "testing"
  19. "github.com/coreos/etcd/tools/functional-tester/rpcpb"
  20. "go.uber.org/zap"
  21. )
  22. func Test_newCluster(t *testing.T) {
  23. exp := &Cluster{
  24. Members: []*rpcpb.Member{
  25. {
  26. EtcdExecPath: "./bin/etcd",
  27. AgentAddr: "127.0.0.1:19027",
  28. FailpointHTTPAddr: "http://127.0.0.1:7381",
  29. BaseDir: "/tmp/etcd-agent-data-1",
  30. EtcdLogPath: "/tmp/etcd-agent-data-1/current-etcd.log",
  31. EtcdClientTLS: false,
  32. EtcdClientProxy: false,
  33. EtcdPeerProxy: true,
  34. EtcdClientEndpoint: "127.0.0.1:1379",
  35. Etcd: &rpcpb.Etcd{
  36. Name: "s1",
  37. DataDir: "/tmp/etcd-agent-data-1/etcd.data",
  38. WALDir: "/tmp/etcd-agent-data-1/etcd.data/member/wal",
  39. HeartbeatIntervalMs: 100,
  40. ElectionTimeoutMs: 1000,
  41. ListenClientURLs: []string{"http://127.0.0.1:1379"},
  42. AdvertiseClientURLs: []string{"http://127.0.0.1:1379"},
  43. ListenPeerURLs: []string{"http://127.0.0.1:1380"},
  44. InitialAdvertisePeerURLs: []string{"http://127.0.0.1:13800"},
  45. InitialCluster: "s1=http://127.0.0.1:13800,s2=http://127.0.0.1:23800,s3=http://127.0.0.1:33800",
  46. InitialClusterState: "new",
  47. InitialClusterToken: "tkn",
  48. SnapshotCount: 10000,
  49. QuotaBackendBytes: 10740000000,
  50. PreVote: true,
  51. InitialCorruptCheck: true,
  52. },
  53. },
  54. {
  55. EtcdExecPath: "./bin/etcd",
  56. AgentAddr: "127.0.0.1:29027",
  57. FailpointHTTPAddr: "http://127.0.0.1:7382",
  58. BaseDir: "/tmp/etcd-agent-data-2",
  59. EtcdLogPath: "/tmp/etcd-agent-data-2/current-etcd.log",
  60. EtcdClientTLS: false,
  61. EtcdClientProxy: false,
  62. EtcdPeerProxy: true,
  63. EtcdClientEndpoint: "127.0.0.1:2379",
  64. Etcd: &rpcpb.Etcd{
  65. Name: "s2",
  66. DataDir: "/tmp/etcd-agent-data-2/etcd.data",
  67. WALDir: "/tmp/etcd-agent-data-2/etcd.data/member/wal",
  68. HeartbeatIntervalMs: 100,
  69. ElectionTimeoutMs: 1000,
  70. ListenClientURLs: []string{"http://127.0.0.1:2379"},
  71. AdvertiseClientURLs: []string{"http://127.0.0.1:2379"},
  72. ListenPeerURLs: []string{"http://127.0.0.1:2380"},
  73. InitialAdvertisePeerURLs: []string{"http://127.0.0.1:23800"},
  74. InitialCluster: "s1=http://127.0.0.1:13800,s2=http://127.0.0.1:23800,s3=http://127.0.0.1:33800",
  75. InitialClusterState: "new",
  76. InitialClusterToken: "tkn",
  77. SnapshotCount: 10000,
  78. QuotaBackendBytes: 10740000000,
  79. PreVote: true,
  80. InitialCorruptCheck: true,
  81. },
  82. },
  83. {
  84. EtcdExecPath: "./bin/etcd",
  85. AgentAddr: "127.0.0.1:39027",
  86. FailpointHTTPAddr: "http://127.0.0.1:7383",
  87. BaseDir: "/tmp/etcd-agent-data-3",
  88. EtcdLogPath: "/tmp/etcd-agent-data-3/current-etcd.log",
  89. EtcdClientTLS: false,
  90. EtcdClientProxy: false,
  91. EtcdPeerProxy: true,
  92. EtcdClientEndpoint: "127.0.0.1:3379",
  93. Etcd: &rpcpb.Etcd{
  94. Name: "s3",
  95. DataDir: "/tmp/etcd-agent-data-3/etcd.data",
  96. WALDir: "/tmp/etcd-agent-data-3/etcd.data/member/wal",
  97. HeartbeatIntervalMs: 100,
  98. ElectionTimeoutMs: 1000,
  99. ListenClientURLs: []string{"http://127.0.0.1:3379"},
  100. AdvertiseClientURLs: []string{"http://127.0.0.1:3379"},
  101. ListenPeerURLs: []string{"http://127.0.0.1:3380"},
  102. InitialAdvertisePeerURLs: []string{"http://127.0.0.1:33800"},
  103. InitialCluster: "s1=http://127.0.0.1:13800,s2=http://127.0.0.1:23800,s3=http://127.0.0.1:33800",
  104. InitialClusterState: "new",
  105. InitialClusterToken: "tkn",
  106. SnapshotCount: 10000,
  107. QuotaBackendBytes: 10740000000,
  108. PreVote: true,
  109. InitialCorruptCheck: true,
  110. },
  111. },
  112. },
  113. Tester: &rpcpb.Tester{
  114. TesterNetwork: "tcp",
  115. TesterAddr: "127.0.0.1:9028",
  116. DelayLatencyMs: 5000,
  117. DelayLatencyMsRv: 150,
  118. RoundLimit: 1,
  119. ExitOnFailure: true,
  120. ConsistencyCheck: true,
  121. EnablePprof: true,
  122. FailureCases: []string{
  123. "KILL_ONE_FOLLOWER",
  124. "KILL_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT",
  125. "KILL_LEADER",
  126. "KILL_LEADER_UNTIL_TRIGGER_SNAPSHOT",
  127. "KILL_QUORUM",
  128. "KILL_ALL",
  129. "BLACKHOLE_PEER_PORT_TX_RX_ONE_FOLLOWER",
  130. "BLACKHOLE_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT",
  131. "BLACKHOLE_PEER_PORT_TX_RX_LEADER",
  132. "BLACKHOLE_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT",
  133. "BLACKHOLE_PEER_PORT_TX_RX_QUORUM",
  134. "BLACKHOLE_PEER_PORT_TX_RX_ALL",
  135. "DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER",
  136. "RANDOM_DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER",
  137. "DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT",
  138. "RANDOM_DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT",
  139. "DELAY_PEER_PORT_TX_RX_LEADER",
  140. "RANDOM_DELAY_PEER_PORT_TX_RX_LEADER",
  141. "DELAY_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT",
  142. "RANDOM_DELAY_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT",
  143. "DELAY_PEER_PORT_TX_RX_QUORUM",
  144. "RANDOM_DELAY_PEER_PORT_TX_RX_QUORUM",
  145. "DELAY_PEER_PORT_TX_RX_ALL",
  146. "RANDOM_DELAY_PEER_PORT_TX_RX_ALL",
  147. "NO_FAIL_WITH_STRESS",
  148. "NO_FAIL_WITH_NO_STRESS_FOR_LIVENESS",
  149. },
  150. FailureDelayMs: 7000,
  151. FailureShuffle: true,
  152. FailpointCommands: []string{`panic("etcd-tester")`},
  153. RunnerExecPath: "/etcd-runner",
  154. ExternalExecPath: "",
  155. StressTypes: []string{"KV", "LEASE"},
  156. StressKeySize: 100,
  157. StressKeySizeLarge: 32769,
  158. StressKeySuffixRange: 250000,
  159. StressKeySuffixRangeTxn: 100,
  160. StressKeyTxnOps: 10,
  161. StressClients: 100,
  162. StressQPS: 2000,
  163. },
  164. }
  165. logger, err := zap.NewProduction()
  166. if err != nil {
  167. t.Fatal(err)
  168. }
  169. defer logger.Sync()
  170. cfg, err := newCluster(logger, "./local-test.yaml")
  171. if err != nil {
  172. t.Fatal(err)
  173. }
  174. cfg.lg = nil
  175. if !reflect.DeepEqual(exp, cfg) {
  176. t.Fatalf("expected %+v, got %+v", exp, cfg)
  177. }
  178. cfg.lg = logger
  179. cfg.updateFailures()
  180. fs1 := cfg.failureStrings()
  181. cfg.shuffleFailures()
  182. fs2 := cfg.failureStrings()
  183. if reflect.DeepEqual(fs1, fs2) {
  184. t.Fatalf("expected shuffled failure cases, got %q", fs2)
  185. }
  186. cfg.shuffleFailures()
  187. fs3 := cfg.failureStrings()
  188. if reflect.DeepEqual(fs2, fs3) {
  189. t.Fatalf("expected reshuffled failure cases from %q, got %q", fs2, fs3)
  190. }
  191. // shuffle ensures visit all exactly once
  192. // so when sorted, failure cases must be equal
  193. sort.Strings(fs1)
  194. sort.Strings(fs2)
  195. sort.Strings(fs3)
  196. if !reflect.DeepEqual(fs1, fs2) {
  197. t.Fatalf("expected %q, got %q", fs1, fs2)
  198. }
  199. if !reflect.DeepEqual(fs2, fs3) {
  200. t.Fatalf("expected %q, got %q", fs2, fs3)
  201. }
  202. }