main.go 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright 2015 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 main
  15. import (
  16. "flag"
  17. "fmt"
  18. "net/http"
  19. "strings"
  20. "github.com/coreos/pkg/capnslog"
  21. "github.com/prometheus/client_golang/prometheus"
  22. )
  23. var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcd-tester")
  24. func main() {
  25. endpointStr := flag.String("agent-endpoints", "localhost:9027", "HTTP RPC endpoints of agents. Do not specify the schema.")
  26. datadir := flag.String("data-dir", "agent.etcd", "etcd data directory location on agent machine.")
  27. stressKeySize := flag.Int("stress-key-size", 100, "the size of each key written into etcd.")
  28. stressKeySuffixRange := flag.Int("stress-key-count", 250000, "the count of key range written into etcd.")
  29. limit := flag.Int("limit", -1, "the limit of rounds to run failure set (-1 to run without limits).")
  30. stressQPS := flag.Int("stress-qps", 5000, "maximum number of stresser requests per second.")
  31. schedCases := flag.String("schedule-cases", "", "test case schedule")
  32. consistencyCheck := flag.Bool("consistency-check", true, "true to check consistency (revision, hash)")
  33. isV2Only := flag.Bool("v2-only", false, "'true' to run V2 only tester.")
  34. flag.Parse()
  35. endpoints := strings.Split(*endpointStr, ",")
  36. c, err := newCluster(endpoints, *datadir, *stressQPS, *stressKeySize, *stressKeySuffixRange, *isV2Only)
  37. if err != nil {
  38. plog.Fatal(err)
  39. }
  40. defer c.Terminate()
  41. failures := []failure{
  42. newFailureKillAll(),
  43. newFailureKillMajority(),
  44. newFailureKillOne(),
  45. newFailureKillLeader(),
  46. newFailureKillOneForLongTime(),
  47. newFailureKillLeaderForLongTime(),
  48. newFailureIsolate(),
  49. newFailureIsolateAll(),
  50. newFailureSlowNetworkOneMember(),
  51. newFailureSlowNetworkLeader(),
  52. newFailureSlowNetworkAll(),
  53. }
  54. // ensure cluster is fully booted to know failpoints are available
  55. c.WaitHealth()
  56. fpFailures, fperr := failpointFailures(c)
  57. if len(fpFailures) == 0 {
  58. plog.Infof("no failpoints found (%v)", fperr)
  59. }
  60. failures = append(failures, fpFailures...)
  61. schedule := failures
  62. if schedCases != nil && *schedCases != "" {
  63. cases := strings.Split(*schedCases, " ")
  64. schedule = make([]failure, len(cases))
  65. for i := range cases {
  66. caseNum := 0
  67. n, err := fmt.Sscanf(cases[i], "%d", &caseNum)
  68. if n == 0 || err != nil {
  69. plog.Fatalf(`couldn't parse case "%s" (%v)`, cases[i], err)
  70. }
  71. schedule[i] = failures[caseNum]
  72. }
  73. }
  74. t := &tester{
  75. failures: schedule,
  76. cluster: c,
  77. limit: *limit,
  78. consistencyCheck: *consistencyCheck,
  79. }
  80. sh := statusHandler{status: &t.status}
  81. http.Handle("/status", sh)
  82. http.Handle("/metrics", prometheus.Handler())
  83. go func() { plog.Fatal(http.ListenAndServe(":9028", nil)) }()
  84. t.runLoop()
  85. }