feat: show dormant workspaces by default (#11053)

This commit is contained in:
Jon Ayers
2023-12-07 18:09:35 -06:00
committed by GitHub
parent be31b2e4d7
commit e73a202aed
15 changed files with 196 additions and 183 deletions
+1 -6
View File
@@ -7289,12 +7289,7 @@ func (q *FakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
}
}
// We omit locked workspaces by default.
if arg.IsDormant == "" && workspace.DormantAt.Valid {
continue
}
if arg.IsDormant != "" && !workspace.DormantAt.Valid {
if arg.Dormant && !workspace.DormantAt.Valid {
continue
}
+1 -1
View File
@@ -221,7 +221,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.IsDormant,
arg.Dormant,
arg.LastUsedBefore,
arg.LastUsedAfter,
arg.Offset,
+5 -7
View File
@@ -10939,13 +10939,11 @@ WHERE
) > 0
ELSE true
END
-- Filter by dormant workspaces. By default we do not return dormant
-- workspaces since they are considered soft-deleted.
-- Filter by dormant workspaces.
AND CASE
WHEN $10 :: text != '' THEN
WHEN $10 :: boolean != 'false' THEN
dormant_at IS NOT NULL
ELSE
dormant_at IS NULL
ELSE true
END
-- Filter by last_used
AND CASE
@@ -10986,7 +10984,7 @@ type GetWorkspacesParams struct {
Name string `db:"name" json:"name"`
HasAgent string `db:"has_agent" json:"has_agent"`
AgentInactiveDisconnectTimeoutSeconds int64 `db:"agent_inactive_disconnect_timeout_seconds" json:"agent_inactive_disconnect_timeout_seconds"`
IsDormant string `db:"is_dormant" json:"is_dormant"`
Dormant bool `db:"dormant" json:"dormant"`
LastUsedBefore time.Time `db:"last_used_before" json:"last_used_before"`
LastUsedAfter time.Time `db:"last_used_after" json:"last_used_after"`
Offset int32 `db:"offset_" json:"offset_"`
@@ -11025,7 +11023,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.IsDormant,
arg.Dormant,
arg.LastUsedBefore,
arg.LastUsedAfter,
arg.Offset,
+3 -5
View File
@@ -239,13 +239,11 @@ WHERE
) > 0
ELSE true
END
-- Filter by dormant workspaces. By default we do not return dormant
-- workspaces since they are considered soft-deleted.
-- Filter by dormant workspaces.
AND CASE
WHEN @is_dormant :: text != '' THEN
WHEN @dormant :: boolean != 'false' THEN
dormant_at IS NOT NULL
ELSE
dormant_at IS NULL
ELSE true
END
-- Filter by last_used
AND CASE
+1 -1
View File
@@ -107,7 +107,7 @@ func Workspaces(query string, page codersdk.Pagination, agentInactiveDisconnectT
filter.Name = parser.String(values, "", "name")
filter.Status = string(httpapi.ParseCustom(parser, values, "", "status", httpapi.ParseEnum[database.WorkspaceStatus]))
filter.HasAgent = parser.String(values, "", "has-agent")
filter.IsDormant = parser.String(values, "", "is-dormant")
filter.Dormant = parser.Boolean(values, false, "dormant")
filter.LastUsedAfter = parser.Time3339Nano(values, time.Time{}, "last_used_after")
filter.LastUsedBefore = parser.Time3339Nano(values, time.Time{}, "last_used_before")
+25 -18
View File
@@ -1503,43 +1503,50 @@ func TestWorkspaceFilterManual(t *testing.T) {
}, testutil.IntervalMedium, "agent status timeout")
})
t.Run("IsDormant", func(t *testing.T) {
t.Run("Dormant", func(t *testing.T) {
// this test has a licensed counterpart in enterprise/coderd/workspaces_test.go: FilterQueryHasDeletingByAndLicensed
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{
IncludeProvisionerDaemon: true,
})
client, db := coderdtest.NewWithDatabase(t, nil)
user := coderdtest.CreateFirstUser(t, client)
authToken := uuid.NewString()
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: echo.ParseComplete,
ProvisionPlan: echo.PlanComplete,
ProvisionApply: echo.ProvisionApplyWithAgent(authToken),
})
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := dbfake.TemplateVersion(t, db).Seed(database.TemplateVersion{
OrganizationID: user.OrganizationID,
CreatedBy: user.UserID,
}).Do().Template
// update template with inactivity ttl
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
dormantWorkspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWorkspace.LatestBuild.ID)
dormantWorkspace := dbfake.WorkspaceBuild(t, db, database.Workspace{
TemplateID: template.ID,
OwnerID: user.UserID,
OrganizationID: user.OrganizationID,
}).Do().Workspace
// Create another workspace to validate that we do not return active workspaces.
_ = coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWorkspace.LatestBuild.ID)
_ = dbfake.WorkspaceBuild(t, db, database.Workspace{
TemplateID: template.ID,
OwnerID: user.UserID,
OrganizationID: user.OrganizationID,
}).Do()
err := client.UpdateWorkspaceDormancy(ctx, dormantWorkspace.ID, codersdk.UpdateWorkspaceDormancy{
Dormant: true,
})
require.NoError(t, err)
res, err := client.Workspaces(ctx, codersdk.WorkspaceFilter{
FilterQuery: "is-dormant:true",
// Test that no filter returns both workspaces.
res, err := client.Workspaces(ctx, codersdk.WorkspaceFilter{})
require.NoError(t, err)
require.Len(t, res.Workspaces, 2)
// Test that filtering for dormant only returns our dormant workspace.
res, err = client.Workspaces(ctx, codersdk.WorkspaceFilter{
FilterQuery: "dormant:true",
})
require.NoError(t, err)
require.Len(t, res.Workspaces, 1)
require.Equal(t, dormantWorkspace.ID, res.Workspaces[0].ID)
require.NotNil(t, res.Workspaces[0].DormantAt)
})