You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.8 KiB

  1. package rpcserver
  2. import (
  3. "fmt"
  4. "io"
  5. "io/ioutil"
  6. "net/http"
  7. "os"
  8. "sync"
  9. "sync/atomic"
  10. "testing"
  11. "time"
  12. "github.com/stretchr/testify/require"
  13. "github.com/tendermint/tendermint/libs/log"
  14. )
  15. func TestMaxOpenConnections(t *testing.T) {
  16. const max = 5 // max simultaneous connections
  17. // Start the server.
  18. var open int32
  19. mux := http.NewServeMux()
  20. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  21. if n := atomic.AddInt32(&open, 1); n > int32(max) {
  22. t.Errorf("%d open connections, want <= %d", n, max)
  23. }
  24. defer atomic.AddInt32(&open, -1)
  25. time.Sleep(10 * time.Millisecond)
  26. fmt.Fprint(w, "some body")
  27. })
  28. l, err := StartHTTPServer("tcp://127.0.0.1:0", mux, log.TestingLogger(), Config{MaxOpenConnections: max})
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. defer l.Close()
  33. // Make N GET calls to the server.
  34. attempts := max * 2
  35. var wg sync.WaitGroup
  36. var failed int32
  37. for i := 0; i < attempts; i++ {
  38. wg.Add(1)
  39. go func() {
  40. defer wg.Done()
  41. c := http.Client{Timeout: 3 * time.Second}
  42. r, err := c.Get("http://" + l.Addr().String())
  43. if err != nil {
  44. t.Log(err)
  45. atomic.AddInt32(&failed, 1)
  46. return
  47. }
  48. defer r.Body.Close()
  49. io.Copy(ioutil.Discard, r.Body)
  50. }()
  51. }
  52. wg.Wait()
  53. // We expect some Gets to fail as the server's accept queue is filled,
  54. // but most should succeed.
  55. if int(failed) >= attempts/2 {
  56. t.Errorf("%d requests failed within %d attempts", failed, attempts)
  57. }
  58. }
  59. func TestStartHTTPAndTLSServer(t *testing.T) {
  60. // set up fixtures
  61. listenerAddr := "tcp://0.0.0.0:0"
  62. mux := http.NewServeMux()
  63. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {})
  64. // test failure
  65. gotListener, err := StartHTTPAndTLSServer(listenerAddr, mux, "", "", log.TestingLogger(), Config{MaxOpenConnections: 1})
  66. require.Nil(t, gotListener)
  67. require.IsType(t, (*os.PathError)(nil), err)
  68. }