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.

94 lines
2.3 KiB

  1. package rpcserver
  2. import (
  3. "crypto/tls"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "net"
  8. "net/http"
  9. "sync"
  10. "sync/atomic"
  11. "testing"
  12. "time"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. "github.com/tendermint/tendermint/libs/log"
  16. )
  17. func TestMaxOpenConnections(t *testing.T) {
  18. const max = 5 // max simultaneous connections
  19. // Start the server.
  20. var open int32
  21. mux := http.NewServeMux()
  22. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  23. if n := atomic.AddInt32(&open, 1); n > int32(max) {
  24. t.Errorf("%d open connections, want <= %d", n, max)
  25. }
  26. defer atomic.AddInt32(&open, -1)
  27. time.Sleep(10 * time.Millisecond)
  28. fmt.Fprint(w, "some body")
  29. })
  30. config := DefaultConfig()
  31. config.MaxOpenConnections = max
  32. l, err := Listen("tcp://127.0.0.1:0", config)
  33. require.NoError(t, err)
  34. defer l.Close()
  35. go StartHTTPServer(l, mux, log.TestingLogger(), config)
  36. // Make N GET calls to the server.
  37. attempts := max * 2
  38. var wg sync.WaitGroup
  39. var failed int32
  40. for i := 0; i < attempts; i++ {
  41. wg.Add(1)
  42. go func() {
  43. defer wg.Done()
  44. c := http.Client{Timeout: 3 * time.Second}
  45. r, err := c.Get("http://" + l.Addr().String())
  46. if err != nil {
  47. t.Log(err)
  48. atomic.AddInt32(&failed, 1)
  49. return
  50. }
  51. defer r.Body.Close()
  52. io.Copy(ioutil.Discard, r.Body)
  53. }()
  54. }
  55. wg.Wait()
  56. // We expect some Gets to fail as the server's accept queue is filled,
  57. // but most should succeed.
  58. if int(failed) >= attempts/2 {
  59. t.Errorf("%d requests failed within %d attempts", failed, attempts)
  60. }
  61. }
  62. func TestStartHTTPAndTLSServer(t *testing.T) {
  63. ln, err := net.Listen("tcp", "localhost:0")
  64. require.NoError(t, err)
  65. defer ln.Close()
  66. mux := http.NewServeMux()
  67. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  68. fmt.Fprint(w, "some body")
  69. })
  70. go StartHTTPAndTLSServer(ln, mux, "test.crt", "test.key", log.TestingLogger(), DefaultConfig())
  71. tr := &http.Transport{
  72. TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // nolint: gosec
  73. }
  74. c := &http.Client{Transport: tr}
  75. res, err := c.Get("https://" + ln.Addr().String())
  76. require.NoError(t, err)
  77. defer res.Body.Close()
  78. assert.Equal(t, http.StatusOK, res.StatusCode)
  79. body, err := ioutil.ReadAll(res.Body)
  80. require.NoError(t, err)
  81. assert.Equal(t, []byte("some body"), body)
  82. }