fleet/server/service/debug_handler_test.go
Zach Wasserman 0bb9d69ece
Add debug endpoints and associated fleetctl commands (#45)
Adds endpoints and fleetctl commands to retrieve various debug profiles
from the Fleet server.

The best summary is from the help text:

```
fleetctl debug
NAME:
   fleetctl debug - Tools for debugging Fleet

USAGE:
   fleetctl debug command [command options] [arguments...]

COMMANDS:
   profile    Record a CPU profile from the Fleet server.
   cmdline    Get the command line used to invoke the Fleet server.
   heap       Report the allocated memory in the Fleet server.
   goroutine  Get stack traces of all goroutines (threads) in the Fleet server.
   trace      Record an execution trace on the Fleet server.
   archive    Create an archive with the entire suite of debug profiles.

OPTIONS:
   --config value   Path to the Fleet config file (default: "/Users/zwass/.fleet/config") [$CONFIG]
   --context value  Name of Fleet config context to use (default: "default") [$CONTEXT]
   --help, -h       show help
```
2020-11-17 17:12:37 -08:00

126 lines
3.6 KiB
Go

package service
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/bmizerany/assert"
"github.com/fleetdm/fleet/server/config"
"github.com/fleetdm/fleet/server/kolide"
"github.com/pkg/errors"
"github.com/stretchr/testify/mock"
)
type mockService struct {
mock.Mock
kolide.Service
}
func (m *mockService) GetSessionByKey(ctx context.Context, sessionKey string) (*kolide.Session, error) {
args := m.Called(ctx, sessionKey)
if ret := args.Get(0); ret != nil {
return ret.(*kolide.Session), nil
}
return nil, args.Error(1)
}
func (m *mockService) User(ctx context.Context, userId uint) (*kolide.User, error) {
args := m.Called(ctx, userId)
if ret := args.Get(0); ret != nil {
return ret.(*kolide.User), nil
}
return nil, args.Error(1)
}
var testConfig = config.KolideConfig{
Auth: config.AuthConfig{
JwtKey: "insecure",
},
}
func TestDebugHandlerAuthenticationTokenMissing(t *testing.T) {
handler := MakeDebugHandler(&mockService{}, testConfig, nil)
req := httptest.NewRequest(http.MethodGet, "https://fleetdm.com/debug/pprof/profile", nil)
res := httptest.NewRecorder()
handler.ServeHTTP(res, req)
assert.Equal(t, http.StatusUnauthorized, res.Code)
}
func TestDebugHandlerAuthenticationTokenInvalid(t *testing.T) {
handler := MakeDebugHandler(&mockService{}, testConfig, nil)
req := httptest.NewRequest(http.MethodGet, "https://fleetdm.com/debug/pprof/profile", nil)
req.Header.Add("Authorization", "BEARER foobar")
res := httptest.NewRecorder()
handler.ServeHTTP(res, req)
assert.Equal(t, http.StatusUnauthorized, res.Code)
}
func TestDebugHandlerAuthenticationSessionInvalid(t *testing.T) {
svc := &mockService{}
svc.On(
"GetSessionByKey",
mock.Anything,
"session",
).Return(nil, errors.New("invalid session"))
handler := MakeDebugHandler(svc, testConfig, nil)
req := httptest.NewRequest(http.MethodGet, "https://fleetdm.com/debug/pprof/profile", nil)
req.Header.Add("Authorization", "BEARER eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2tleSI6InNlc3Npb24iLCJpYXQiOjE1MTYyMzkwMjJ9.YZIL9fKxfVg7fCms4CTKCPT2w8x8N3e2pciV_h0OvTk")
res := httptest.NewRecorder()
handler.ServeHTTP(res, req)
assert.Equal(t, http.StatusUnauthorized, res.Code)
}
func TestDebugHandlerAuthenticationDisabled(t *testing.T) {
svc := &mockService{}
svc.On(
"GetSessionByKey",
mock.Anything,
"session",
).Return(&kolide.Session{UserID: 42, ID: 1}, nil)
svc.On(
"User",
mock.Anything,
uint(42),
).Return(&kolide.User{Enabled: false}, nil)
handler := MakeDebugHandler(svc, testConfig, nil)
req := httptest.NewRequest(http.MethodGet, "https://fleetdm.com/debug/pprof/profile", nil)
req.Header.Add("Authorization", "BEARER eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2tleSI6InNlc3Npb24iLCJpYXQiOjE1MTYyMzkwMjJ9.YZIL9fKxfVg7fCms4CTKCPT2w8x8N3e2pciV_h0OvTk")
res := httptest.NewRecorder()
handler.ServeHTTP(res, req)
assert.Equal(t, http.StatusForbidden, res.Code)
}
func TestDebugHandlerAuthenticationSuccess(t *testing.T) {
svc := &mockService{}
svc.On(
"GetSessionByKey",
mock.Anything,
"session",
).Return(&kolide.Session{UserID: 42, ID: 1}, nil)
svc.On(
"User",
mock.Anything,
uint(42),
).Return(&kolide.User{Enabled: true}, nil)
handler := MakeDebugHandler(svc, testConfig, nil)
req := httptest.NewRequest(http.MethodGet, "https://fleetdm.com/debug/pprof/cmdline", nil)
req.Header.Add("Authorization", "BEARER eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2tleSI6InNlc3Npb24iLCJpYXQiOjE1MTYyMzkwMjJ9.YZIL9fKxfVg7fCms4CTKCPT2w8x8N3e2pciV_h0OvTk")
res := httptest.NewRecorder()
handler.ServeHTTP(res, req)
assert.Equal(t, http.StatusOK, res.Code)
}