chore: improve build deadline code (#19203)

- Adds/improves a lot of comments to make the autostop calculation code
clearer
- Changes the behavior of the enterprise template schedule store to
match the behavior of the workspace TTL endpoint when the new TTL is
zero
- Fixes a bug in the workspace TTL endpoint where it could unset the
build deadline, even though a max_deadline was specified
- Adds a new constraint to the workspace_builds table that enforces the
deadline is non-zero and below the max_deadline if it is set
- Adds CHECK constraint enum generation to scripts/dbgen, used for
testing the above constraint
- Adds Dean and Danielle as CODEOWNERS for the autostop calculation code
This commit is contained in:
Dean Sheather
2025-08-07 11:00:31 +10:00
committed by GitHub
parent ec3b8cea91
commit dc598856e3
16 changed files with 660 additions and 258 deletions
+49
View File
@@ -2897,6 +2897,55 @@ func TestWorkspaceUpdateTTL(t *testing.T) {
}
})
t.Run("RemoveAutostopWithRunningWorkspaceWithMaxDeadline", func(t *testing.T) {
t.Parallel()
var (
ctx = testutil.Context(t, testutil.WaitLong)
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user = coderdtest.CreateFirstUser(t, client)
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
deadline = 8 * time.Hour
maxDeadline = 10 * time.Hour
workspace = coderdtest.CreateWorkspace(t, client, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
cwr.TTLMillis = ptr.Ref(deadline.Milliseconds())
})
build = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
)
// This is a hack, but the max_deadline isn't precisely configurable
// without a lot of unnecessary hassle.
dbBuild, err := db.GetWorkspaceBuildByID(dbauthz.AsSystemRestricted(ctx), build.ID) //nolint:gocritic // test
require.NoError(t, err)
dbJob, err := db.GetProvisionerJobByID(dbauthz.AsSystemRestricted(ctx), dbBuild.JobID) //nolint:gocritic // test
require.NoError(t, err)
require.True(t, dbJob.CompletedAt.Valid)
expectedMaxDeadline := dbJob.CompletedAt.Time.Add(maxDeadline)
err = db.UpdateWorkspaceBuildDeadlineByID(dbauthz.AsSystemRestricted(ctx), database.UpdateWorkspaceBuildDeadlineByIDParams{ //nolint:gocritic // test
ID: build.ID,
Deadline: dbBuild.Deadline,
MaxDeadline: expectedMaxDeadline,
UpdatedAt: dbtime.Now(),
})
require.NoError(t, err)
// Remove autostop.
err = client.UpdateWorkspaceTTL(ctx, workspace.ID, codersdk.UpdateWorkspaceTTLRequest{
TTLMillis: nil,
})
require.NoError(t, err)
// Expect that the deadline is set to the max_deadline.
build, err = client.WorkspaceBuild(ctx, build.ID)
require.NoError(t, err)
require.True(t, build.Deadline.Valid)
require.WithinDuration(t, build.Deadline.Time, expectedMaxDeadline, time.Second)
require.True(t, build.MaxDeadline.Valid)
require.WithinDuration(t, build.MaxDeadline.Time, expectedMaxDeadline, time.Second)
})
t.Run("CustomAutostopDisabledByTemplate", func(t *testing.T) {
t.Parallel()
var (