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.

79 lines
1.9 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 := Listen("tcp://127.0.0.1:0", Config{MaxOpenConnections: max})
  29. require.NoError(t, err)
  30. defer l.Close()
  31. go StartHTTPServer(l, mux, log.TestingLogger())
  32. // Make N GET calls to the server.
  33. attempts := max * 2
  34. var wg sync.WaitGroup
  35. var failed int32
  36. for i := 0; i < attempts; i++ {
  37. wg.Add(1)
  38. go func() {
  39. defer wg.Done()
  40. c := http.Client{Timeout: 3 * time.Second}
  41. r, err := c.Get("http://" + l.Addr().String())
  42. if err != nil {
  43. t.Log(err)
  44. atomic.AddInt32(&failed, 1)
  45. return
  46. }
  47. defer r.Body.Close()
  48. io.Copy(ioutil.Discard, r.Body)
  49. }()
  50. }
  51. wg.Wait()
  52. // We expect some Gets to fail as the server's accept queue is filled,
  53. // but most should succeed.
  54. if int(failed) >= attempts/2 {
  55. t.Errorf("%d requests failed within %d attempts", failed, attempts)
  56. }
  57. }
  58. func TestStartHTTPAndTLSServer(t *testing.T) {
  59. // set up fixtures
  60. listenerAddr := "tcp://0.0.0.0:0"
  61. listener, err := Listen(listenerAddr, Config{MaxOpenConnections: 1})
  62. require.NoError(t, err)
  63. mux := http.NewServeMux()
  64. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {})
  65. // test failure
  66. err = StartHTTPAndTLSServer(listener, mux, "", "", log.TestingLogger())
  67. require.IsType(t, (*os.PathError)(nil), err)
  68. // TODO: test that starting the server can actually work
  69. }