2020-10-14 13:42:00 +00:00
|
|
|
package origin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2020-11-25 06:55:13 +00:00
|
|
|
"github.com/rs/zerolog"
|
2020-10-14 13:42:00 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2021-03-23 14:30:43 +00:00
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/connection"
|
2021-10-11 10:31:05 +00:00
|
|
|
"github.com/cloudflare/cloudflared/edgediscovery"
|
2021-03-26 04:04:56 +00:00
|
|
|
"github.com/cloudflare/cloudflared/retry"
|
2020-10-14 13:42:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type dynamicMockFetcher struct {
|
2021-10-11 10:31:05 +00:00
|
|
|
protocolPercents edgediscovery.ProtocolPercents
|
|
|
|
err error
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (dmf *dynamicMockFetcher) fetch() connection.PercentageFetcher {
|
2021-10-11 10:31:05 +00:00
|
|
|
return func() (edgediscovery.ProtocolPercents, error) {
|
|
|
|
return dmf.protocolPercents, dmf.err
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-05 00:07:49 +00:00
|
|
|
|
2020-10-14 13:42:00 +00:00
|
|
|
func TestWaitForBackoffFallback(t *testing.T) {
|
|
|
|
maxRetries := uint(3)
|
2021-03-26 04:04:56 +00:00
|
|
|
backoff := retry.BackoffHandler{
|
2020-10-14 13:42:00 +00:00
|
|
|
MaxRetries: maxRetries,
|
|
|
|
BaseTime: time.Millisecond * 10,
|
|
|
|
}
|
2020-11-25 06:55:13 +00:00
|
|
|
log := zerolog.Nop()
|
2020-10-14 13:42:00 +00:00
|
|
|
resolveTTL := time.Duration(0)
|
|
|
|
namedTunnel := &connection.NamedTunnelConfig{
|
2020-11-23 21:36:16 +00:00
|
|
|
Credentials: connection.Credentials{
|
2020-10-14 13:42:00 +00:00
|
|
|
AccountTag: "test-account",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
mockFetcher := dynamicMockFetcher{
|
2021-10-11 10:31:05 +00:00
|
|
|
protocolPercents: edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}},
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
2021-01-21 15:23:18 +00:00
|
|
|
warpRoutingEnabled := false
|
2020-11-25 06:55:13 +00:00
|
|
|
protocolSelector, err := connection.NewProtocolSelector(
|
2022-01-05 17:58:49 +00:00
|
|
|
"auto",
|
2021-01-21 15:23:18 +00:00
|
|
|
warpRoutingEnabled,
|
2020-11-25 06:55:13 +00:00
|
|
|
namedTunnel,
|
|
|
|
mockFetcher.fetch(),
|
|
|
|
resolveTTL,
|
|
|
|
&log,
|
|
|
|
)
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
initProtocol := protocolSelector.Current()
|
|
|
|
assert.Equal(t, connection.HTTP2, initProtocol)
|
|
|
|
|
2021-02-05 00:07:49 +00:00
|
|
|
protocolFallback := &protocolFallback{
|
2020-10-14 13:42:00 +00:00
|
|
|
backoff,
|
|
|
|
initProtocol,
|
|
|
|
false,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Retry #0 and #1. At retry #2, we switch protocol, so the fallback loop has one more retry than this
|
|
|
|
for i := 0; i < int(maxRetries-1); i++ {
|
2021-02-05 00:07:49 +00:00
|
|
|
protocolFallback.BackoffTimer() // simulate retry
|
2021-11-03 12:06:04 +00:00
|
|
|
ok := selectNextProtocol(&log, protocolFallback, protocolSelector, false)
|
2021-02-05 00:07:49 +00:00
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, initProtocol, protocolFallback.protocol)
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Retry fallback protocol
|
|
|
|
for i := 0; i < int(maxRetries); i++ {
|
2021-02-05 00:07:49 +00:00
|
|
|
protocolFallback.BackoffTimer() // simulate retry
|
2021-11-03 12:06:04 +00:00
|
|
|
ok := selectNextProtocol(&log, protocolFallback, protocolSelector, false)
|
2021-02-05 00:07:49 +00:00
|
|
|
assert.True(t, ok)
|
2020-10-14 13:42:00 +00:00
|
|
|
fallback, ok := protocolSelector.Fallback()
|
|
|
|
assert.True(t, ok)
|
2021-02-05 00:07:49 +00:00
|
|
|
assert.Equal(t, fallback, protocolFallback.protocol)
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
currentGlobalProtocol := protocolSelector.Current()
|
|
|
|
assert.Equal(t, initProtocol, currentGlobalProtocol)
|
|
|
|
|
|
|
|
// No protocol to fallback, return error
|
2021-02-05 00:07:49 +00:00
|
|
|
protocolFallback.BackoffTimer() // simulate retry
|
2021-11-03 12:06:04 +00:00
|
|
|
ok := selectNextProtocol(&log, protocolFallback, protocolSelector, false)
|
2021-02-05 00:07:49 +00:00
|
|
|
assert.False(t, ok)
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2021-02-05 00:07:49 +00:00
|
|
|
protocolFallback.reset()
|
|
|
|
protocolFallback.BackoffTimer() // simulate retry
|
2021-11-03 12:06:04 +00:00
|
|
|
ok = selectNextProtocol(&log, protocolFallback, protocolSelector, false)
|
2021-02-05 00:07:49 +00:00
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, initProtocol, protocolFallback.protocol)
|
2021-11-03 12:06:04 +00:00
|
|
|
|
|
|
|
protocolFallback.reset()
|
|
|
|
protocolFallback.BackoffTimer() // simulate retry
|
|
|
|
ok = selectNextProtocol(&log, protocolFallback, protocolSelector, true)
|
|
|
|
// Check that we get a true after the first try itself when this flag is true. This allows us to immediately
|
|
|
|
// switch protocols.
|
|
|
|
assert.True(t, ok)
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|