mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 22:59:58 +00:00
TUN-8737: update metrics server port selection
## Summary Update how metrics server binds to a listener by using a known set of ports whenever the default address is used with the fallback to a random port in case all address are already in use. The default address changes at compile time in order to bind to a different default address when the final deliverable is a docker image. Refactor ReadyServer tests. Closes TUN-8737
This commit is contained in:
@@ -1,136 +1,106 @@
|
||||
package metrics
|
||||
package metrics_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cloudflare/cloudflared/connection"
|
||||
"github.com/cloudflare/cloudflared/metrics"
|
||||
"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 mockRequest(t *testing.T, readyServer *metrics.ReadyServer) (int, uint) {
|
||||
t.Helper()
|
||||
|
||||
var readyreadyConnections struct {
|
||||
Status int `json:"status"`
|
||||
ReadyConnections uint `json:"readyConnections"`
|
||||
ConnectorID uuid.UUID `json:"connectorId"`
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
readyServer.ServeHTTP(rec, nil)
|
||||
|
||||
decoder := json.NewDecoder(rec.Body)
|
||||
err := decoder.Decode(&readyreadyConnections)
|
||||
require.NoError(t, err)
|
||||
return rec.Code, readyreadyConnections.ReadyConnections
|
||||
}
|
||||
|
||||
func TestReadinessEventHandling(t *testing.T) {
|
||||
nopLogger := zerolog.Nop()
|
||||
rs := NewReadyServer(&nopLogger, uuid.Nil)
|
||||
tracker := tunnelstate.NewConnTracker(&nopLogger)
|
||||
rs := metrics.NewReadyServer(uuid.Nil, tracker)
|
||||
|
||||
// start not ok
|
||||
code, ready := rs.makeResponse()
|
||||
code, readyConnections := mockRequest(t, rs)
|
||||
assert.NotEqualValues(t, http.StatusOK, code)
|
||||
assert.Zero(t, ready)
|
||||
assert.Zero(t, readyConnections)
|
||||
|
||||
// one connected => ok
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 1,
|
||||
EventType: connection.Connected,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.EqualValues(t, http.StatusOK, code)
|
||||
assert.EqualValues(t, 1, ready)
|
||||
assert.EqualValues(t, 1, readyConnections)
|
||||
|
||||
// another connected => still ok
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 2,
|
||||
EventType: connection.Connected,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.EqualValues(t, http.StatusOK, code)
|
||||
assert.EqualValues(t, 2, ready)
|
||||
assert.EqualValues(t, 2, readyConnections)
|
||||
|
||||
// one reconnecting => still ok
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 2,
|
||||
EventType: connection.Reconnecting,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.EqualValues(t, http.StatusOK, code)
|
||||
assert.EqualValues(t, 1, ready)
|
||||
assert.EqualValues(t, 1, readyConnections)
|
||||
|
||||
// Regression test for TUN-3777
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 1,
|
||||
EventType: connection.RegisteringTunnel,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.NotEqualValues(t, http.StatusOK, code)
|
||||
assert.Zero(t, ready)
|
||||
assert.Zero(t, readyConnections)
|
||||
|
||||
// other connected then unregistered => not ok
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 1,
|
||||
EventType: connection.Connected,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.EqualValues(t, http.StatusOK, code)
|
||||
assert.EqualValues(t, 1, ready)
|
||||
assert.EqualValues(t, 1, readyConnections)
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 1,
|
||||
EventType: connection.Unregistering,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.NotEqualValues(t, http.StatusOK, code)
|
||||
assert.Zero(t, ready)
|
||||
assert.Zero(t, readyConnections)
|
||||
|
||||
// other disconnected => not ok
|
||||
rs.OnTunnelEvent(connection.Event{
|
||||
Index: 1,
|
||||
EventType: connection.Disconnected,
|
||||
})
|
||||
code, ready = rs.makeResponse()
|
||||
code, readyConnections = mockRequest(t, rs)
|
||||
assert.NotEqualValues(t, http.StatusOK, code)
|
||||
assert.Zero(t, ready)
|
||||
assert.Zero(t, readyConnections)
|
||||
}
|
||||
|
Reference in New Issue
Block a user