cluster_test.go 9.5 KB

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