mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-05-11 06:06:35 +00:00

cloudflared falls back aggressively to HTTP/2 protocol if a connection attempt with QUIC failed. This was done to ensure that machines with UDP egress disabled did not stop clients from connecting to the cloudlfare edge. This PR improves on that experience by having cloudflared remember if a QUIC connection was successful which implies UDP egress works. In this case, cloudflared does not fallback to HTTP/2 and keeps trying to connect to the edge with QUIC.
137 lines
3.5 KiB
Go
137 lines
3.5 KiB
Go
package metrics
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/rs/zerolog"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/cloudflare/cloudflared/connection"
|
|
"github.com/cloudflare/cloudflared/tunnelstate"
|
|
)
|
|
|
|
func TestReadyServer_makeResponse(t *testing.T) {
|
|
type fields struct {
|
|
isConnected map[uint8]tunnelstate.ConnectionInfo
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantOK bool
|
|
wantReadyConnections uint
|
|
}{
|
|
{
|
|
name: "One connection online => HTTP 200",
|
|
fields: fields{
|
|
isConnected: map[uint8]tunnelstate.ConnectionInfo{
|
|
0: {IsConnected: false},
|
|
1: {IsConnected: false},
|
|
2: {IsConnected: true},
|
|
3: {IsConnected: false},
|
|
},
|
|
},
|
|
wantOK: true,
|
|
wantReadyConnections: 1,
|
|
},
|
|
{
|
|
name: "No connections online => no HTTP 200",
|
|
fields: fields{
|
|
isConnected: map[uint8]tunnelstate.ConnectionInfo{
|
|
0: {IsConnected: false},
|
|
1: {IsConnected: false},
|
|
2: {IsConnected: false},
|
|
3: {IsConnected: false},
|
|
},
|
|
},
|
|
wantReadyConnections: 0,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
rs := &ReadyServer{
|
|
tracker: tunnelstate.MockedConnTracker(tt.fields.isConnected),
|
|
}
|
|
gotStatusCode, gotReadyConnections := rs.makeResponse()
|
|
if tt.wantOK && gotStatusCode != http.StatusOK {
|
|
t.Errorf("ReadyServer.makeResponse() gotStatusCode = %v, want ok = %v", gotStatusCode, tt.wantOK)
|
|
}
|
|
if gotReadyConnections != tt.wantReadyConnections {
|
|
t.Errorf("ReadyServer.makeResponse() gotReadyConnections = %v, want %v", gotReadyConnections, tt.wantReadyConnections)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadinessEventHandling(t *testing.T) {
|
|
nopLogger := zerolog.Nop()
|
|
rs := NewReadyServer(&nopLogger, uuid.Nil)
|
|
|
|
// start not ok
|
|
code, ready := rs.makeResponse()
|
|
assert.NotEqualValues(t, http.StatusOK, code)
|
|
assert.Zero(t, ready)
|
|
|
|
// one connected => ok
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 1,
|
|
EventType: connection.Connected,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.EqualValues(t, http.StatusOK, code)
|
|
assert.EqualValues(t, 1, ready)
|
|
|
|
// another connected => still ok
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 2,
|
|
EventType: connection.Connected,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.EqualValues(t, http.StatusOK, code)
|
|
assert.EqualValues(t, 2, ready)
|
|
|
|
// one reconnecting => still ok
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 2,
|
|
EventType: connection.Reconnecting,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.EqualValues(t, http.StatusOK, code)
|
|
assert.EqualValues(t, 1, ready)
|
|
|
|
// Regression test for TUN-3777
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 1,
|
|
EventType: connection.RegisteringTunnel,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.NotEqualValues(t, http.StatusOK, code)
|
|
assert.Zero(t, ready)
|
|
|
|
// other connected then unregistered => not ok
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 1,
|
|
EventType: connection.Connected,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.EqualValues(t, http.StatusOK, code)
|
|
assert.EqualValues(t, 1, ready)
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 1,
|
|
EventType: connection.Unregistering,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.NotEqualValues(t, http.StatusOK, code)
|
|
assert.Zero(t, ready)
|
|
|
|
// other disconnected => not ok
|
|
rs.OnTunnelEvent(connection.Event{
|
|
Index: 1,
|
|
EventType: connection.Disconnected,
|
|
})
|
|
code, ready = rs.makeResponse()
|
|
assert.NotEqualValues(t, http.StatusOK, code)
|
|
assert.Zero(t, ready)
|
|
}
|