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.

95 lines
2.3 KiB

  1. package server
  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 Serve(l, mux, log.TestingLogger(), config) //nolint:errcheck // ignore for tests
  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. _, err = io.Copy(ioutil.Discard, r.Body)
  53. require.NoError(t, err)
  54. }()
  55. }
  56. wg.Wait()
  57. // We expect some Gets to fail as the server's accept queue is filled,
  58. // but most should succeed.
  59. if int(failed) >= attempts/2 {
  60. t.Errorf("%d requests failed within %d attempts", failed, attempts)
  61. }
  62. }
  63. func TestServeTLS(t *testing.T) {
  64. ln, err := net.Listen("tcp", "localhost:0")
  65. require.NoError(t, err)
  66. defer ln.Close()
  67. mux := http.NewServeMux()
  68. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  69. fmt.Fprint(w, "some body")
  70. })
  71. go ServeTLS(ln, mux, "test.crt", "test.key", log.TestingLogger(), DefaultConfig())
  72. tr := &http.Transport{
  73. TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // nolint: gosec
  74. }
  75. c := &http.Client{Transport: tr}
  76. res, err := c.Get("https://" + ln.Addr().String())
  77. require.NoError(t, err)
  78. defer res.Body.Close()
  79. assert.Equal(t, http.StatusOK, res.StatusCode)
  80. body, err := ioutil.ReadAll(res.Body)
  81. require.NoError(t, err)
  82. assert.Equal(t, []byte("some body"), body)
  83. }