mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
chore: add agentapi tests (#11269)
This commit is contained in:
252
coderd/agentapi/apps_test.go
Normal file
252
coderd/agentapi/apps_test.go
Normal file
@ -0,0 +1,252 @@
|
||||
package agentapi_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
|
||||
agentproto "github.com/coder/coder/v2/agent/proto"
|
||||
"github.com/coder/coder/v2/coderd/agentapi"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbmock"
|
||||
)
|
||||
|
||||
func TestBatchUpdateAppHealths(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
agent = database.WorkspaceAgent{
|
||||
ID: uuid.New(),
|
||||
}
|
||||
app1 = database.WorkspaceApp{
|
||||
ID: uuid.New(),
|
||||
AgentID: agent.ID,
|
||||
Slug: "code-server-1",
|
||||
DisplayName: "code-server 1",
|
||||
HealthcheckUrl: "http://localhost:3000",
|
||||
Health: database.WorkspaceAppHealthInitializing,
|
||||
}
|
||||
app2 = database.WorkspaceApp{
|
||||
ID: uuid.New(),
|
||||
AgentID: agent.ID,
|
||||
Slug: "code-server-2",
|
||||
DisplayName: "code-server 2",
|
||||
HealthcheckUrl: "http://localhost:3001",
|
||||
Health: database.WorkspaceAppHealthHealthy,
|
||||
}
|
||||
)
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dbM := dbmock.NewMockStore(gomock.NewController(t))
|
||||
dbM.EXPECT().GetWorkspaceAppsByAgentID(gomock.Any(), agent.ID).Return([]database.WorkspaceApp{app1, app2}, nil)
|
||||
dbM.EXPECT().UpdateWorkspaceAppHealthByID(gomock.Any(), database.UpdateWorkspaceAppHealthByIDParams{
|
||||
ID: app1.ID,
|
||||
Health: database.WorkspaceAppHealthHealthy,
|
||||
}).Return(nil)
|
||||
dbM.EXPECT().UpdateWorkspaceAppHealthByID(gomock.Any(), database.UpdateWorkspaceAppHealthByIDParams{
|
||||
ID: app2.ID,
|
||||
Health: database.WorkspaceAppHealthUnhealthy,
|
||||
}).Return(nil)
|
||||
|
||||
publishCalled := false
|
||||
api := &agentapi.AppsAPI{
|
||||
AgentFn: func(context.Context) (database.WorkspaceAgent, error) {
|
||||
return agent, nil
|
||||
},
|
||||
Database: dbM,
|
||||
Log: slogtest.Make(t, nil),
|
||||
PublishWorkspaceUpdateFn: func(ctx context.Context, wa *database.WorkspaceAgent) error {
|
||||
publishCalled = true
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// Set one to healthy, set another to unhealthy.
|
||||
resp, err := api.BatchUpdateAppHealths(context.Background(), &agentproto.BatchUpdateAppHealthRequest{
|
||||
Updates: []*agentproto.BatchUpdateAppHealthRequest_HealthUpdate{
|
||||
{
|
||||
Id: app1.ID[:],
|
||||
Health: agentproto.AppHealth_HEALTHY,
|
||||
},
|
||||
{
|
||||
Id: app2.ID[:],
|
||||
Health: agentproto.AppHealth_UNHEALTHY,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &agentproto.BatchUpdateAppHealthResponse{}, resp)
|
||||
|
||||
require.True(t, publishCalled)
|
||||
})
|
||||
|
||||
t.Run("Unchanged", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dbM := dbmock.NewMockStore(gomock.NewController(t))
|
||||
dbM.EXPECT().GetWorkspaceAppsByAgentID(gomock.Any(), agent.ID).Return([]database.WorkspaceApp{app1, app2}, nil)
|
||||
|
||||
publishCalled := false
|
||||
api := &agentapi.AppsAPI{
|
||||
AgentFn: func(context.Context) (database.WorkspaceAgent, error) {
|
||||
return agent, nil
|
||||
},
|
||||
Database: dbM,
|
||||
Log: slogtest.Make(t, nil),
|
||||
PublishWorkspaceUpdateFn: func(ctx context.Context, wa *database.WorkspaceAgent) error {
|
||||
publishCalled = true
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// Set both to their current status, neither should be updated in the
|
||||
// DB.
|
||||
resp, err := api.BatchUpdateAppHealths(context.Background(), &agentproto.BatchUpdateAppHealthRequest{
|
||||
Updates: []*agentproto.BatchUpdateAppHealthRequest_HealthUpdate{
|
||||
{
|
||||
Id: app1.ID[:],
|
||||
Health: agentproto.AppHealth_INITIALIZING,
|
||||
},
|
||||
{
|
||||
Id: app2.ID[:],
|
||||
Health: agentproto.AppHealth_HEALTHY,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &agentproto.BatchUpdateAppHealthResponse{}, resp)
|
||||
|
||||
require.False(t, publishCalled)
|
||||
})
|
||||
|
||||
t.Run("Empty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// No DB queries are made if there are no updates to process.
|
||||
dbM := dbmock.NewMockStore(gomock.NewController(t))
|
||||
|
||||
publishCalled := false
|
||||
api := &agentapi.AppsAPI{
|
||||
AgentFn: func(context.Context) (database.WorkspaceAgent, error) {
|
||||
return agent, nil
|
||||
},
|
||||
Database: dbM,
|
||||
Log: slogtest.Make(t, nil),
|
||||
PublishWorkspaceUpdateFn: func(ctx context.Context, wa *database.WorkspaceAgent) error {
|
||||
publishCalled = true
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// Do nothing.
|
||||
resp, err := api.BatchUpdateAppHealths(context.Background(), &agentproto.BatchUpdateAppHealthRequest{
|
||||
Updates: []*agentproto.BatchUpdateAppHealthRequest_HealthUpdate{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &agentproto.BatchUpdateAppHealthResponse{}, resp)
|
||||
|
||||
require.False(t, publishCalled)
|
||||
})
|
||||
|
||||
t.Run("AppNoHealthcheck", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app3 := database.WorkspaceApp{
|
||||
ID: uuid.New(),
|
||||
AgentID: agent.ID,
|
||||
Slug: "code-server-3",
|
||||
DisplayName: "code-server 3",
|
||||
}
|
||||
|
||||
dbM := dbmock.NewMockStore(gomock.NewController(t))
|
||||
dbM.EXPECT().GetWorkspaceAppsByAgentID(gomock.Any(), agent.ID).Return([]database.WorkspaceApp{app3}, nil)
|
||||
|
||||
api := &agentapi.AppsAPI{
|
||||
AgentFn: func(context.Context) (database.WorkspaceAgent, error) {
|
||||
return agent, nil
|
||||
},
|
||||
Database: dbM,
|
||||
Log: slogtest.Make(t, nil),
|
||||
PublishWorkspaceUpdateFn: nil,
|
||||
}
|
||||
|
||||
// Set app3 to healthy, should error.
|
||||
resp, err := api.BatchUpdateAppHealths(context.Background(), &agentproto.BatchUpdateAppHealthRequest{
|
||||
Updates: []*agentproto.BatchUpdateAppHealthRequest_HealthUpdate{
|
||||
{
|
||||
Id: app3.ID[:],
|
||||
Health: agentproto.AppHealth_HEALTHY,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, "does not have healthchecks enabled")
|
||||
require.Nil(t, resp)
|
||||
})
|
||||
|
||||
t.Run("UnknownApp", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dbM := dbmock.NewMockStore(gomock.NewController(t))
|
||||
dbM.EXPECT().GetWorkspaceAppsByAgentID(gomock.Any(), agent.ID).Return([]database.WorkspaceApp{app1, app2}, nil)
|
||||
|
||||
api := &agentapi.AppsAPI{
|
||||
AgentFn: func(context.Context) (database.WorkspaceAgent, error) {
|
||||
return agent, nil
|
||||
},
|
||||
Database: dbM,
|
||||
Log: slogtest.Make(t, nil),
|
||||
PublishWorkspaceUpdateFn: nil,
|
||||
}
|
||||
|
||||
// Set an unknown app to healthy, should error.
|
||||
id := uuid.New()
|
||||
resp, err := api.BatchUpdateAppHealths(context.Background(), &agentproto.BatchUpdateAppHealthRequest{
|
||||
Updates: []*agentproto.BatchUpdateAppHealthRequest_HealthUpdate{
|
||||
{
|
||||
Id: id[:],
|
||||
Health: agentproto.AppHealth_HEALTHY,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, "not found")
|
||||
require.Nil(t, resp)
|
||||
})
|
||||
|
||||
t.Run("InvalidHealth", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dbM := dbmock.NewMockStore(gomock.NewController(t))
|
||||
dbM.EXPECT().GetWorkspaceAppsByAgentID(gomock.Any(), agent.ID).Return([]database.WorkspaceApp{app1, app2}, nil)
|
||||
|
||||
api := &agentapi.AppsAPI{
|
||||
AgentFn: func(context.Context) (database.WorkspaceAgent, error) {
|
||||
return agent, nil
|
||||
},
|
||||
Database: dbM,
|
||||
Log: slogtest.Make(t, nil),
|
||||
PublishWorkspaceUpdateFn: nil,
|
||||
}
|
||||
|
||||
// Set an unknown app to healthy, should error.
|
||||
resp, err := api.BatchUpdateAppHealths(context.Background(), &agentproto.BatchUpdateAppHealthRequest{
|
||||
Updates: []*agentproto.BatchUpdateAppHealthRequest_HealthUpdate{
|
||||
{
|
||||
Id: app1.ID[:],
|
||||
Health: -999,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, "unknown health status")
|
||||
require.Nil(t, resp)
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user