server_utils.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package tests
  2. import (
  3. "io/ioutil"
  4. "net/http"
  5. "os"
  6. "sync"
  7. "time"
  8. "github.com/coreos/etcd/third_party/github.com/coreos/raft"
  9. "github.com/coreos/etcd/metrics"
  10. "github.com/coreos/etcd/server"
  11. "github.com/coreos/etcd/store"
  12. )
  13. const (
  14. testName = "ETCDTEST"
  15. testClientURL = "localhost:4401"
  16. testRaftURL = "localhost:7701"
  17. testSnapshotCount = 10000
  18. testHeartbeatInterval = time.Duration(50) * time.Millisecond
  19. testElectionTimeout = time.Duration(200) * time.Millisecond
  20. )
  21. // Starts a server in a temporary directory.
  22. func RunServer(f func(*server.Server)) {
  23. path, _ := ioutil.TempDir("", "etcd-")
  24. defer os.RemoveAll(path)
  25. store := store.New()
  26. registry := server.NewRegistry(store)
  27. serverStats := server.NewRaftServerStats(testName)
  28. followersStats := server.NewRaftFollowersStats(testName)
  29. psConfig := server.PeerServerConfig{
  30. Name: testName,
  31. URL: "http://" + testRaftURL,
  32. Scheme: "http",
  33. SnapshotCount: testSnapshotCount,
  34. MaxClusterSize: 9,
  35. }
  36. mb := metrics.NewBucket("")
  37. ps := server.NewPeerServer(psConfig, registry, store, &mb, followersStats, serverStats)
  38. psListener, err := server.NewListener(testRaftURL)
  39. if err != nil {
  40. panic(err)
  41. }
  42. // Create Raft transporter and server
  43. dialTimeout := (3 * testHeartbeatInterval) + testElectionTimeout
  44. responseHeaderTimeout := (3 * testHeartbeatInterval) + testElectionTimeout
  45. raftTransporter := server.NewTransporter(followersStats, serverStats, registry, testHeartbeatInterval, dialTimeout, responseHeaderTimeout)
  46. raftServer, err := raft.NewServer(testName, path, raftTransporter, store, ps, "")
  47. if err != nil {
  48. panic(err)
  49. }
  50. raftServer.SetElectionTimeout(testElectionTimeout)
  51. raftServer.SetHeartbeatInterval(testHeartbeatInterval)
  52. ps.SetRaftServer(raftServer)
  53. s := server.New(testName, "http://"+testClientURL, ps, registry, store, nil)
  54. sListener, err := server.NewListener(testClientURL)
  55. if err != nil {
  56. panic(err)
  57. }
  58. ps.SetServer(s)
  59. w := &sync.WaitGroup{}
  60. // Start up peer server.
  61. c := make(chan bool)
  62. go func() {
  63. c <- true
  64. ps.Start(false, []string{})
  65. h := waitHandler{w, ps.HTTPHandler()}
  66. http.Serve(psListener, &h)
  67. }()
  68. <-c
  69. // Start up etcd server.
  70. go func() {
  71. c <- true
  72. h := waitHandler{w, s.HTTPHandler()}
  73. http.Serve(sListener, &h)
  74. }()
  75. <-c
  76. // Wait to make sure servers have started.
  77. time.Sleep(50 * time.Millisecond)
  78. // Execute the function passed in.
  79. f(s)
  80. // Clean up servers.
  81. ps.Stop()
  82. psListener.Close()
  83. sListener.Close()
  84. w.Wait()
  85. }
  86. type waitHandler struct {
  87. wg *sync.WaitGroup
  88. handler http.Handler
  89. }
  90. func (h *waitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request){
  91. h.wg.Add(1)
  92. defer h.wg.Done()
  93. h.handler.ServeHTTP(w, r)
  94. //important to flush before decrementing the wait group.
  95. //we won't get a chance to once main() ends.
  96. w.(http.Flusher).Flush()
  97. }