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.

61 lines
1.6 KiB

  1. //go:build release
  2. // +build release
  3. // The code in here is comprehensive as an integration
  4. // test and is long, hence is only run before releases.
  5. package client
  6. import (
  7. "bytes"
  8. "context"
  9. "errors"
  10. "net"
  11. "regexp"
  12. "testing"
  13. "time"
  14. "github.com/stretchr/testify/require"
  15. )
  16. func TestWSClientReconnectWithJitter(t *testing.T) {
  17. const numClients = 8
  18. const maxReconnectAttempts = 3
  19. const maxSleepTime = time.Duration(((1<<maxReconnectAttempts)-1)+maxReconnectAttempts) * time.Second
  20. ctx, cancel := context.WithCancel(context.Background())
  21. defer cancel()
  22. failDialer := func(net, addr string) (net.Conn, error) {
  23. return nil, errors.New("not connected")
  24. }
  25. clientMap := make(map[int]*WSClient)
  26. buf := new(bytes.Buffer)
  27. for i := 0; i < numClients; i++ {
  28. c, err := NewWS("tcp://foo", "/websocket")
  29. require.NoError(t, err)
  30. c.Dialer = failDialer
  31. c.maxReconnectAttempts = maxReconnectAttempts
  32. c.Start(ctx)
  33. // Not invoking defer c.Stop() because
  34. // after all the reconnect attempts have been
  35. // exhausted, c.Stop is implicitly invoked.
  36. clientMap[i] = c
  37. // Trigger the reconnect routine that performs exponential backoff.
  38. go c.reconnect(ctx)
  39. }
  40. // Next we have to examine the logs to ensure that no single time was repeated
  41. backoffDurRegexp := regexp.MustCompile(`backoff_duration=(.+)`)
  42. matches := backoffDurRegexp.FindAll(buf.Bytes(), -1)
  43. seenMap := make(map[string]int)
  44. for i, match := range matches {
  45. if origIndex, seen := seenMap[string(match)]; seen {
  46. t.Errorf("match #%d (%q) was seen originally at log entry #%d", i, match, origIndex)
  47. } else {
  48. seenMap[string(match)] = i
  49. }
  50. }
  51. }