2020-10-14 13:42:00 +00:00
|
|
|
package connection
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2021-10-11 10:31:05 +00:00
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/edgediscovery"
|
2020-10-14 13:42:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2023-02-06 19:06:02 +00:00
|
|
|
testNoTTL = 0
|
|
|
|
testAccountTag = "testAccountTag"
|
2020-10-14 13:42:00 +00:00
|
|
|
)
|
|
|
|
|
2023-02-06 19:06:02 +00:00
|
|
|
func mockFetcher(getError bool, protocolPercent ...edgediscovery.ProtocolPercent) edgediscovery.PercentageFetcher {
|
2021-10-11 10:31:05 +00:00
|
|
|
return func() (edgediscovery.ProtocolPercents, error) {
|
|
|
|
if getError {
|
2021-11-12 15:38:06 +00:00
|
|
|
return nil, fmt.Errorf("failed to fetch percentage")
|
2021-10-11 10:31:05 +00:00
|
|
|
}
|
|
|
|
return protocolPercent, nil
|
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
|
|
|
}
|
|
|
|
|
2023-02-06 19:06:02 +00:00
|
|
|
func (dmf *dynamicMockFetcher) fetch() edgediscovery.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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestNewProtocolSelector(t *testing.T) {
|
|
|
|
tests := []struct {
|
2023-02-06 19:06:02 +00:00
|
|
|
name string
|
|
|
|
protocol string
|
|
|
|
tunnelTokenProvided bool
|
|
|
|
needPQ bool
|
|
|
|
expectedProtocol Protocol
|
|
|
|
hasFallback bool
|
|
|
|
expectedFallback Protocol
|
|
|
|
wantErr bool
|
2020-10-14 13:42:00 +00:00
|
|
|
}{
|
|
|
|
{
|
2023-02-06 19:06:02 +00:00
|
|
|
name: "named tunnel with unknown protocol",
|
|
|
|
protocol: "unknown",
|
|
|
|
wantErr: true,
|
2022-01-05 17:58:49 +00:00
|
|
|
},
|
2021-10-11 10:31:05 +00:00
|
|
|
{
|
2023-02-06 19:06:02 +00:00
|
|
|
name: "named tunnel with h2mux: force to http2",
|
|
|
|
protocol: "h2mux",
|
2021-10-11 10:31:05 +00:00
|
|
|
expectedProtocol: HTTP2,
|
|
|
|
},
|
|
|
|
{
|
2023-02-06 19:06:02 +00:00
|
|
|
name: "named tunnel with http2: no fallback",
|
|
|
|
protocol: "http2",
|
|
|
|
expectedProtocol: HTTP2,
|
2021-01-21 15:23:18 +00:00
|
|
|
},
|
2020-10-14 13:42:00 +00:00
|
|
|
{
|
2023-02-06 19:06:02 +00:00
|
|
|
name: "named tunnel with auto: quic",
|
|
|
|
protocol: AutoSelectFlag,
|
|
|
|
expectedProtocol: QUIC,
|
|
|
|
hasFallback: true,
|
|
|
|
expectedFallback: HTTP2,
|
2020-10-14 13:42:00 +00:00
|
|
|
},
|
|
|
|
{
|
2023-02-06 19:06:02 +00:00
|
|
|
name: "named tunnel (post quantum)",
|
|
|
|
protocol: AutoSelectFlag,
|
|
|
|
needPQ: true,
|
|
|
|
expectedProtocol: QUIC,
|
2020-10-14 13:42:00 +00:00
|
|
|
},
|
|
|
|
{
|
2023-02-06 19:06:02 +00:00
|
|
|
name: "named tunnel (post quantum) w/http2",
|
|
|
|
protocol: "http2",
|
|
|
|
needPQ: true,
|
|
|
|
expectedProtocol: QUIC,
|
2020-10-14 13:42:00 +00:00
|
|
|
},
|
|
|
|
}
|
2020-11-25 06:55:13 +00:00
|
|
|
|
2023-02-06 19:06:02 +00:00
|
|
|
fetcher := dynamicMockFetcher{
|
|
|
|
protocolPercents: edgediscovery.ProtocolPercents{},
|
|
|
|
}
|
|
|
|
|
2020-10-14 13:42:00 +00:00
|
|
|
for _, test := range tests {
|
2021-10-11 10:31:05 +00:00
|
|
|
t.Run(test.name, func(t *testing.T) {
|
2023-02-06 19:06:02 +00:00
|
|
|
selector, err := NewProtocolSelector(test.protocol, testAccountTag, test.tunnelTokenProvided, test.needPQ, fetcher.fetch(), ResolveTTL, &log)
|
2021-10-11 10:31:05 +00:00
|
|
|
if test.wantErr {
|
|
|
|
assert.Error(t, err, fmt.Sprintf("test %s failed", test.name))
|
|
|
|
} else {
|
|
|
|
assert.NoError(t, err, fmt.Sprintf("test %s failed", test.name))
|
|
|
|
assert.Equal(t, test.expectedProtocol, selector.Current(), fmt.Sprintf("test %s failed", test.name))
|
|
|
|
fallback, ok := selector.Fallback()
|
|
|
|
assert.Equal(t, test.hasFallback, ok, fmt.Sprintf("test %s failed", test.name))
|
|
|
|
if test.hasFallback {
|
|
|
|
assert.Equal(t, test.expectedFallback, fallback, fmt.Sprintf("test %s failed", test.name))
|
|
|
|
}
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
2021-10-11 10:31:05 +00:00
|
|
|
})
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAutoProtocolSelectorRefresh(t *testing.T) {
|
|
|
|
fetcher := dynamicMockFetcher{}
|
2023-02-06 19:06:02 +00:00
|
|
|
selector, err := NewProtocolSelector(AutoSelectFlag, testAccountTag, false, false, fetcher.fetch(), testNoTTL, &log)
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.NoError(t, err)
|
2023-02-06 19:06:02 +00:00
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}}
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 0}}
|
2023-02-06 19:06:02 +00:00
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}}
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
|
|
|
fetcher.err = fmt.Errorf("failed to fetch")
|
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: -1}}
|
2020-10-14 13:42:00 +00:00
|
|
|
fetcher.err = nil
|
2023-02-06 19:06:02 +00:00
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 0}}
|
2023-02-06 19:06:02 +00:00
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "quic", Percentage: 100}}
|
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestHTTP2ProtocolSelectorRefresh(t *testing.T) {
|
|
|
|
fetcher := dynamicMockFetcher{}
|
2022-01-05 17:58:49 +00:00
|
|
|
// Since the user chooses http2 on purpose, we always stick to it.
|
2023-02-06 19:06:02 +00:00
|
|
|
selector, err := NewProtocolSelector(HTTP2.String(), testAccountTag, false, false, fetcher.fetch(), testNoTTL, &log)
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}}
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 0}}
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
|
|
|
fetcher.err = fmt.Errorf("failed to fetch")
|
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: -1}}
|
2020-10-14 13:42:00 +00:00
|
|
|
fetcher.err = nil
|
2022-01-05 17:58:49 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 0}}
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}}
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
|
|
|
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: -1}}
|
2022-01-05 17:58:49 +00:00
|
|
|
assert.Equal(t, HTTP2, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|
|
|
|
|
2023-02-06 19:06:02 +00:00
|
|
|
func TestAutoProtocolSelectorNoRefreshWithToken(t *testing.T) {
|
2021-10-11 10:31:05 +00:00
|
|
|
fetcher := dynamicMockFetcher{}
|
2023-02-06 19:06:02 +00:00
|
|
|
selector, err := NewProtocolSelector(AutoSelectFlag, testAccountTag, true, false, fetcher.fetch(), testNoTTL, &log)
|
2020-10-14 13:42:00 +00:00
|
|
|
assert.NoError(t, err)
|
2021-10-11 10:31:05 +00:00
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
|
2023-02-06 19:06:02 +00:00
|
|
|
fetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: "http2", Percentage: 100}}
|
2021-10-11 10:31:05 +00:00
|
|
|
assert.Equal(t, QUIC, selector.Current())
|
2020-10-14 13:42:00 +00:00
|
|
|
}
|