mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: remove max_ttl from templates (#12644)
* chore: remove max_ttl from templates Completely removing max_ttl as a feature on template scheduling. Must use other template scheduling features to achieve autostop.
This commit is contained in:
@@ -1039,248 +1039,6 @@ func TestCompleteJob(t *testing.T) {
|
||||
require.False(t, job.Error.Valid)
|
||||
})
|
||||
|
||||
// TODO(@dean): remove this legacy test for MaxTTL
|
||||
t.Run("WorkspaceBuildLegacy", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
templateAllowAutostop bool
|
||||
templateDefaultTTL time.Duration
|
||||
templateMaxTTL time.Duration
|
||||
workspaceTTL time.Duration
|
||||
transition database.WorkspaceTransition
|
||||
// The TTL is actually a deadline time on the workspace_build row,
|
||||
// so during the test this will be compared to be within 15 seconds
|
||||
// of the expected value.
|
||||
expectedTTL time.Duration
|
||||
expectedMaxTTL time.Duration
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 0,
|
||||
templateMaxTTL: 0,
|
||||
workspaceTTL: 0,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: 0,
|
||||
expectedMaxTTL: 0,
|
||||
},
|
||||
{
|
||||
name: "Delete",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 0,
|
||||
templateMaxTTL: 0,
|
||||
workspaceTTL: 0,
|
||||
transition: database.WorkspaceTransitionDelete,
|
||||
expectedTTL: 0,
|
||||
expectedMaxTTL: 0,
|
||||
},
|
||||
{
|
||||
name: "WorkspaceTTL",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 0,
|
||||
templateMaxTTL: 0,
|
||||
workspaceTTL: time.Hour,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: time.Hour,
|
||||
expectedMaxTTL: 0,
|
||||
},
|
||||
{
|
||||
name: "TemplateDefaultTTLIgnored",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: time.Hour,
|
||||
templateMaxTTL: 0,
|
||||
workspaceTTL: 0,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: 0,
|
||||
expectedMaxTTL: 0,
|
||||
},
|
||||
{
|
||||
name: "WorkspaceTTLOverridesTemplateDefaultTTL",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 2 * time.Hour,
|
||||
templateMaxTTL: 0,
|
||||
workspaceTTL: time.Hour,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: time.Hour,
|
||||
expectedMaxTTL: 0,
|
||||
},
|
||||
{
|
||||
name: "TemplateMaxTTL",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 0,
|
||||
templateMaxTTL: time.Hour,
|
||||
workspaceTTL: 0,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: time.Hour,
|
||||
expectedMaxTTL: time.Hour,
|
||||
},
|
||||
{
|
||||
name: "TemplateMaxTTLOverridesWorkspaceTTL",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 0,
|
||||
templateMaxTTL: 2 * time.Hour,
|
||||
workspaceTTL: 3 * time.Hour,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: 2 * time.Hour,
|
||||
expectedMaxTTL: 2 * time.Hour,
|
||||
},
|
||||
{
|
||||
name: "TemplateMaxTTLOverridesTemplateDefaultTTL",
|
||||
templateAllowAutostop: true,
|
||||
templateDefaultTTL: 3 * time.Hour,
|
||||
templateMaxTTL: 2 * time.Hour,
|
||||
workspaceTTL: 0,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: 2 * time.Hour,
|
||||
expectedMaxTTL: 2 * time.Hour,
|
||||
},
|
||||
{
|
||||
name: "TemplateBlockWorkspaceTTL",
|
||||
templateAllowAutostop: false,
|
||||
templateDefaultTTL: 3 * time.Hour,
|
||||
templateMaxTTL: 6 * time.Hour,
|
||||
workspaceTTL: 4 * time.Hour,
|
||||
transition: database.WorkspaceTransitionStart,
|
||||
expectedTTL: 3 * time.Hour,
|
||||
expectedMaxTTL: 6 * time.Hour,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
c := c
|
||||
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tss := &atomic.Pointer[schedule.TemplateScheduleStore]{}
|
||||
srv, db, ps, pd := setup(t, false, &overrides{templateScheduleStore: tss})
|
||||
|
||||
var store schedule.TemplateScheduleStore = schedule.MockTemplateScheduleStore{
|
||||
GetFn: func(_ context.Context, _ database.Store, _ uuid.UUID) (schedule.TemplateScheduleOptions, error) {
|
||||
return schedule.TemplateScheduleOptions{
|
||||
UserAutostartEnabled: false,
|
||||
UserAutostopEnabled: c.templateAllowAutostop,
|
||||
DefaultTTL: c.templateDefaultTTL,
|
||||
MaxTTL: c.templateMaxTTL,
|
||||
UseMaxTTL: true,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
tss.Store(&store)
|
||||
|
||||
user := dbgen.User(t, db, database.User{})
|
||||
template := dbgen.Template(t, db, database.Template{
|
||||
Name: "template",
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
OrganizationID: pd.OrganizationID,
|
||||
})
|
||||
version := dbgen.TemplateVersion(t, db, database.TemplateVersion{
|
||||
OrganizationID: pd.OrganizationID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
Valid: true,
|
||||
},
|
||||
JobID: uuid.New(),
|
||||
})
|
||||
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
|
||||
ID: template.ID,
|
||||
UpdatedAt: dbtime.Now(),
|
||||
AllowUserAutostart: c.templateAllowAutostop,
|
||||
DefaultTTL: int64(c.templateDefaultTTL),
|
||||
MaxTTL: int64(c.templateMaxTTL),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
file := dbgen.File(t, db, database.File{CreatedBy: user.ID})
|
||||
workspaceTTL := sql.NullInt64{}
|
||||
if c.workspaceTTL != 0 {
|
||||
workspaceTTL = sql.NullInt64{
|
||||
Int64: int64(c.workspaceTTL),
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
workspace := dbgen.Workspace(t, db, database.Workspace{
|
||||
TemplateID: template.ID,
|
||||
Ttl: workspaceTTL,
|
||||
OrganizationID: pd.OrganizationID,
|
||||
})
|
||||
build := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
|
||||
WorkspaceID: workspace.ID,
|
||||
TemplateVersionID: version.ID,
|
||||
Transition: c.transition,
|
||||
Reason: database.BuildReasonInitiator,
|
||||
})
|
||||
job := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{
|
||||
OrganizationID: pd.OrganizationID,
|
||||
FileID: file.ID,
|
||||
Type: database.ProvisionerJobTypeWorkspaceBuild,
|
||||
Input: must(json.Marshal(provisionerdserver.WorkspaceProvisionJob{
|
||||
WorkspaceBuildID: build.ID,
|
||||
})),
|
||||
})
|
||||
_, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
|
||||
OrganizationID: pd.OrganizationID,
|
||||
WorkerID: uuid.NullUUID{
|
||||
UUID: pd.ID,
|
||||
Valid: true,
|
||||
},
|
||||
Types: []database.ProvisionerType{database.ProvisionerTypeEcho},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
publishedWorkspace := make(chan struct{})
|
||||
closeWorkspaceSubscribe, err := ps.Subscribe(codersdk.WorkspaceNotifyChannel(build.WorkspaceID), func(_ context.Context, _ []byte) {
|
||||
close(publishedWorkspace)
|
||||
})
|
||||
require.NoError(t, err)
|
||||
defer closeWorkspaceSubscribe()
|
||||
publishedLogs := make(chan struct{})
|
||||
closeLogsSubscribe, err := ps.Subscribe(provisionersdk.ProvisionerJobLogsNotifyChannel(job.ID), func(_ context.Context, _ []byte) {
|
||||
close(publishedLogs)
|
||||
})
|
||||
require.NoError(t, err)
|
||||
defer closeLogsSubscribe()
|
||||
|
||||
_, err = srv.CompleteJob(ctx, &proto.CompletedJob{
|
||||
JobId: job.ID.String(),
|
||||
Type: &proto.CompletedJob_WorkspaceBuild_{
|
||||
WorkspaceBuild: &proto.CompletedJob_WorkspaceBuild{
|
||||
State: []byte{},
|
||||
Resources: []*sdkproto.Resource{{
|
||||
Name: "example",
|
||||
Type: "aws_instance",
|
||||
}},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
<-publishedWorkspace
|
||||
<-publishedLogs
|
||||
|
||||
workspace, err = db.GetWorkspaceByID(ctx, workspace.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, c.transition == database.WorkspaceTransitionDelete, workspace.Deleted)
|
||||
|
||||
workspaceBuild, err := db.GetWorkspaceBuildByID(ctx, build.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
if c.expectedTTL == 0 {
|
||||
require.True(t, workspaceBuild.Deadline.IsZero())
|
||||
} else {
|
||||
require.WithinDuration(t, time.Now().Add(c.expectedTTL), workspaceBuild.Deadline, 15*time.Second, "deadline does not match expected")
|
||||
}
|
||||
if c.expectedMaxTTL == 0 {
|
||||
require.True(t, workspaceBuild.MaxDeadline.IsZero())
|
||||
} else {
|
||||
require.WithinDuration(t, time.Now().Add(c.expectedMaxTTL), workspaceBuild.MaxDeadline, 15*time.Second, "max deadline does not match expected")
|
||||
require.GreaterOrEqual(t, workspaceBuild.MaxDeadline.Unix(), workspaceBuild.Deadline.Unix(), "max deadline is smaller than deadline")
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("WorkspaceBuild", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1386,7 +1144,6 @@ func TestCompleteJob(t *testing.T) {
|
||||
UserAutostartEnabled: false,
|
||||
UserAutostopEnabled: true,
|
||||
DefaultTTL: 0,
|
||||
UseMaxTTL: false,
|
||||
AutostopRequirement: c.templateAutostopRequirement,
|
||||
}, nil
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user