tunnel_test.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package origin
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/cloudflare/cloudflared/connection"
  6. "github.com/rs/zerolog"
  7. "github.com/stretchr/testify/assert"
  8. )
  9. type dynamicMockFetcher struct {
  10. percentage int32
  11. err error
  12. }
  13. func (dmf *dynamicMockFetcher) fetch() connection.PercentageFetcher {
  14. return func() (int32, error) {
  15. if dmf.err != nil {
  16. return 0, dmf.err
  17. }
  18. return dmf.percentage, nil
  19. }
  20. }
  21. func TestWaitForBackoffFallback(t *testing.T) {
  22. maxRetries := uint(3)
  23. backoff := BackoffHandler{
  24. MaxRetries: maxRetries,
  25. BaseTime: time.Millisecond * 10,
  26. }
  27. log := zerolog.Nop()
  28. resolveTTL := time.Duration(0)
  29. namedTunnel := &connection.NamedTunnelConfig{
  30. Credentials: connection.Credentials{
  31. AccountTag: "test-account",
  32. },
  33. }
  34. mockFetcher := dynamicMockFetcher{
  35. percentage: 0,
  36. }
  37. warpRoutingEnabled := false
  38. protocolSelector, err := connection.NewProtocolSelector(
  39. connection.HTTP2.String(),
  40. warpRoutingEnabled,
  41. namedTunnel,
  42. mockFetcher.fetch(),
  43. resolveTTL,
  44. &log,
  45. )
  46. assert.NoError(t, err)
  47. initProtocol := protocolSelector.Current()
  48. assert.Equal(t, connection.HTTP2, initProtocol)
  49. protocolFallback := &protocolFallback{
  50. backoff,
  51. initProtocol,
  52. false,
  53. }
  54. // Retry #0 and #1. At retry #2, we switch protocol, so the fallback loop has one more retry than this
  55. for i := 0; i < int(maxRetries-1); i++ {
  56. protocolFallback.BackoffTimer() // simulate retry
  57. ok := selectNextProtocol(&log, protocolFallback, protocolSelector)
  58. assert.True(t, ok)
  59. assert.Equal(t, initProtocol, protocolFallback.protocol)
  60. }
  61. // Retry fallback protocol
  62. for i := 0; i < int(maxRetries); i++ {
  63. protocolFallback.BackoffTimer() // simulate retry
  64. ok := selectNextProtocol(&log, protocolFallback, protocolSelector)
  65. assert.True(t, ok)
  66. fallback, ok := protocolSelector.Fallback()
  67. assert.True(t, ok)
  68. assert.Equal(t, fallback, protocolFallback.protocol)
  69. }
  70. currentGlobalProtocol := protocolSelector.Current()
  71. assert.Equal(t, initProtocol, currentGlobalProtocol)
  72. // No protocol to fallback, return error
  73. protocolFallback.BackoffTimer() // simulate retry
  74. ok := selectNextProtocol(&log, protocolFallback, protocolSelector)
  75. assert.False(t, ok)
  76. protocolFallback.reset()
  77. protocolFallback.BackoffTimer() // simulate retry
  78. ok = selectNextProtocol(&log, protocolFallback, protocolSelector)
  79. assert.True(t, ok)
  80. assert.Equal(t, initProtocol, protocolFallback.protocol)
  81. }