2023-04-04 22:45:32 +00:00
|
|
|
package management
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io"
|
2023-07-05 20:28:30 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"strings"
|
2023-04-04 22:45:32 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2023-07-05 20:28:30 +00:00
|
|
|
"github.com/google/uuid"
|
2023-04-04 22:45:32 +00:00
|
|
|
"github.com/rs/zerolog"
|
2023-04-21 18:54:37 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2023-04-04 22:45:32 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"nhooyr.io/websocket"
|
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/internal/test"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2023-07-05 20:28:30 +00:00
|
|
|
noopLogger = zerolog.New(io.Discard)
|
|
|
|
managementHostname = "https://management.argotunnel.com"
|
2023-04-04 22:45:32 +00:00
|
|
|
)
|
|
|
|
|
2023-07-05 20:28:30 +00:00
|
|
|
func TestDisableDiagnosticRoutes(t *testing.T) {
|
|
|
|
mgmt := New("management.argotunnel.com", false, "1.1.1.1:80", uuid.Nil, "", &noopLogger, nil)
|
|
|
|
for _, path := range []string{"/metrics", "/debug/pprof/goroutine", "/debug/pprof/heap"} {
|
|
|
|
t.Run(strings.Replace(path, "/", "_", -1), func(t *testing.T) {
|
|
|
|
req := httptest.NewRequest("GET", managementHostname+path+"?access_token="+validToken, nil)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
|
|
mgmt.ServeHTTP(recorder, req)
|
|
|
|
resp := recorder.Result()
|
|
|
|
require.Equal(t, http.StatusNotFound, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-04 22:45:32 +00:00
|
|
|
func TestReadEventsLoop(t *testing.T) {
|
|
|
|
sentEvent := EventStartStreaming{
|
|
|
|
ClientEvent: ClientEvent{Type: StartStreaming},
|
|
|
|
}
|
|
|
|
client, server := test.WSPipe(nil, nil)
|
|
|
|
client.CloseRead(context.Background())
|
|
|
|
defer func() {
|
|
|
|
client.Close(websocket.StatusInternalError, "")
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
err := WriteEvent(client, context.Background(), &sentEvent)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}()
|
|
|
|
m := ManagementService{
|
|
|
|
log: &noopLogger,
|
|
|
|
}
|
|
|
|
events := make(chan *ClientEvent)
|
|
|
|
go m.readEvents(server, context.Background(), events)
|
|
|
|
event := <-events
|
|
|
|
require.Equal(t, sentEvent.Type, event.Type)
|
|
|
|
server.Close(websocket.StatusInternalError, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReadEventsLoop_ContextCancelled(t *testing.T) {
|
|
|
|
client, server := test.WSPipe(nil, nil)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
client.CloseRead(ctx)
|
|
|
|
defer func() {
|
|
|
|
client.Close(websocket.StatusInternalError, "")
|
|
|
|
}()
|
|
|
|
m := ManagementService{
|
|
|
|
log: &noopLogger,
|
|
|
|
}
|
|
|
|
events := make(chan *ClientEvent)
|
|
|
|
go func() {
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
cancel()
|
|
|
|
}()
|
|
|
|
// Want to make sure this function returns when context is cancelled
|
|
|
|
m.readEvents(server, ctx, events)
|
|
|
|
server.Close(websocket.StatusInternalError, "")
|
|
|
|
}
|
2023-04-21 18:54:37 +00:00
|
|
|
|
|
|
|
func TestCanStartStream_NoSessions(t *testing.T) {
|
|
|
|
m := ManagementService{
|
|
|
|
log: &noopLogger,
|
|
|
|
logger: &Logger{
|
|
|
|
Log: &noopLogger,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
_, cancel := context.WithCancel(context.Background())
|
|
|
|
session := newSession(0, actor{}, cancel)
|
|
|
|
assert.True(t, m.canStartStream(session))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCanStartStream_ExistingSessionDifferentActor(t *testing.T) {
|
|
|
|
m := ManagementService{
|
|
|
|
log: &noopLogger,
|
|
|
|
logger: &Logger{
|
|
|
|
Log: &noopLogger,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
_, cancel := context.WithCancel(context.Background())
|
|
|
|
session1 := newSession(0, actor{ID: "test"}, cancel)
|
|
|
|
assert.True(t, m.canStartStream(session1))
|
|
|
|
m.logger.Listen(session1)
|
|
|
|
assert.True(t, session1.Active())
|
|
|
|
|
|
|
|
// Try another session
|
|
|
|
session2 := newSession(0, actor{ID: "test2"}, cancel)
|
|
|
|
assert.Equal(t, 1, m.logger.ActiveSessions())
|
|
|
|
assert.False(t, m.canStartStream(session2))
|
|
|
|
|
|
|
|
// Close session1
|
|
|
|
m.logger.Remove(session1)
|
|
|
|
assert.True(t, session1.Active()) // Remove doesn't stop a session
|
|
|
|
session1.Stop()
|
|
|
|
assert.False(t, session1.Active())
|
|
|
|
assert.Equal(t, 0, m.logger.ActiveSessions())
|
|
|
|
|
|
|
|
// Try session2 again
|
|
|
|
assert.True(t, m.canStartStream(session2))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCanStartStream_ExistingSessionSameActor(t *testing.T) {
|
|
|
|
m := ManagementService{
|
|
|
|
log: &noopLogger,
|
|
|
|
logger: &Logger{
|
|
|
|
Log: &noopLogger,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
actor := actor{ID: "test"}
|
|
|
|
_, cancel := context.WithCancel(context.Background())
|
|
|
|
session1 := newSession(0, actor, cancel)
|
|
|
|
assert.True(t, m.canStartStream(session1))
|
|
|
|
m.logger.Listen(session1)
|
|
|
|
assert.True(t, session1.Active())
|
|
|
|
|
|
|
|
// Try another session
|
|
|
|
session2 := newSession(0, actor, cancel)
|
|
|
|
assert.Equal(t, 1, m.logger.ActiveSessions())
|
|
|
|
assert.True(t, m.canStartStream(session2))
|
|
|
|
// session1 is removed and stopped
|
|
|
|
assert.Equal(t, 0, m.logger.ActiveSessions())
|
|
|
|
assert.False(t, session1.Active())
|
|
|
|
}
|