Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: enforce template-level constraints for TTL and autostart#2018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
20 commits
Select commitHold shift + click to select a range
1713431
RED: add failing unit tests
johnstcnJun 2, 2022
f11f942
RED: add migrations and make gen
johnstcnJun 2, 2022
c5c9a7a
ORANGE: fix audit/diff tests
johnstcnJun 2, 2022
74f4dee
fixup! RED: add migrations and make gen
johnstcnJun 2, 2022
7da27a0
fixup! RED: add migrations and make gen
johnstcnJun 2, 2022
5ad048b
feat: schedule: add schedule.Min function to determine minimum interval
johnstcnJun 2, 2022
65b980e
ORANGE: coderd: fix a whole bunch of tests
johnstcnJun 2, 2022
aa298a6
RED: fast-fail some slow-failing tests
johnstcnJun 2, 2022
a5ec9bf
GREEN: fix even more tests
johnstcnJun 3, 2022
a6255d6
GREEN: fix final unit test
johnstcnJun 3, 2022
245795e
cli: templatecreate: add CLI flags --max-ttl --min-autostart-interval
johnstcnJun 3, 2022
709db5b
fixup! cli: templatecreate: add CLI flags --max-ttl --min-autostart-i…
johnstcnJun 3, 2022
c4a0927
make gen
johnstcnJun 3, 2022
244e479
update test entities
johnstcnJun 3, 2022
60ef479
Merge remote-tracking branch 'origin/main' into 1433-template-constra…
johnstcnJun 7, 2022
c9aab8b
fixup! Merge remote-tracking branch 'origin/main' into 1433-template-…
johnstcnJun 7, 2022
f997af2
coderd: default newly-minted workspaces to template max_ttl
johnstcnJun 7, 2022
d7f697b
address PR comment
johnstcnJun 7, 2022
ebe4c15
fix broken unit test
johnstcnJun 7, 2022
08ef2eb
fix some more tests
johnstcnJun 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
RED: add failing unit tests
  • Loading branch information
@johnstcn
johnstcn committedJun 3, 2022
commit17134311a033d075a9b844536d3f8b482e41e8ea
29 changes: 29 additions & 0 deletionscli/autostart_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"testing"
"time"

"github.com/stretchr/testify/require"

Expand DownExpand Up@@ -158,4 +159,32 @@ func TestAutostart(t *testing.T) {
require.NoError(t, err, "fetch updated workspace")
require.Equal(t, expectedSchedule, *updated.AutostartSchedule, "expected default autostart schedule")
})

t.Run("BelowTemplateConstraint", func(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Question(gut-check): Should there be a similar case forAboveTemplateConstraint ?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't see any reason to enforce an upper bound on the interval between successive autostarts.

t.Parallel()

var (
ctx = context.Background()
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user = coderdtest.CreateFirstUser(t, client)
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
ctr.MinAutostartIntervalMillis = ptr.Ref(time.Hour.Milliseconds())
})
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
cmdArgs = []string{"autostart", "enable", workspace.Name, "--minute", "*", "--hour", "*"}
)

cmd, root := clitest.New(t, cmdArgs...)
clitest.SetupConfig(t, client, root)

err := cmd.Execute()
require.NoError(t, err, "unexpected error")

// Ensure nothing happened
updated, err := client.Workspace(ctx, workspace.ID)
require.NoError(t, err, "fetch updated workspace")
require.Equal(t, *workspace.AutostartSchedule, *updated.AutostartSchedule, "expected previous autostart schedule")
})
}
58 changes: 58 additions & 0 deletionscli/create_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,7 @@ import (
"github.com/coder/coder/cli/clitest"
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/util/ptr"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/provisionersdk/proto"
Expand DownExpand Up@@ -62,6 +63,63 @@ func TestCreate(t *testing.T) {
<-doneChan
})

t.Run("AboveTemplateMaxTTL", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
ctr.MaxTTLMillis = ptr.Ref((12 * time.Hour).Milliseconds())
})
args := []string{
"create",
"my-workspace",
"--template", template.Name,
"--ttl", "24h",
}
cmd, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
errCh := make(chan error)
pty := ptytest.New(t)
cmd.SetIn(pty.Input())
cmd.SetOut(pty.Output())
go func() {
defer close(errCh)
errCh <- cmd.Execute()
}()
require.EqualError(t, <-errCh, "TODO what is the error")
})

t.Run("BelowTemplateMinAutostartInterval", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
ctr.MinAutostartIntervalMillis = ptr.Ref(time.Hour.Milliseconds())
})
args := []string{
"create",
"my-workspace",
"--template", template.Name,
"--autostart-minute", "*", // Every minute
"--autostart-hour", "*", // Every hour
}
cmd, root := clitest.New(t, args...)
clitest.SetupConfig(t, client, root)
errCh := make(chan error)
pty := ptytest.New(t)
cmd.SetIn(pty.Input())
cmd.SetOut(pty.Output())
go func() {
defer close(errCh)
errCh <- cmd.Execute()
}()
require.EqualError(t, <-errCh, "TODO what is the error")
})

t.Run("CreateErrInvalidTz", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
Expand Down
33 changes: 33 additions & 0 deletionscli/ttl_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -168,4 +168,37 @@ func TestTTL(t *testing.T) {
err := cmd.Execute()
require.ErrorContains(t, err, "status code 403: forbidden", "unexpected error")
})

t.Run("TemplateMaxTTL", func(t *testing.T) {
t.Parallel()

var (
ctx = context.Background()
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user = coderdtest.CreateFirstUser(t, client)
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
ctr.MaxTTLMillis = ptr.Ref((8 * time.Hour).Milliseconds())
})
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
cwr.TTLMillis = ptr.Ref((8 * time.Hour).Milliseconds())
})
cmdArgs = []string{"ttl", "set", workspace.Name, "24h"}
stdoutBuf = &bytes.Buffer{}
)

cmd, root := clitest.New(t, cmdArgs...)
clitest.SetupConfig(t, client, root)
cmd.SetOut(stdoutBuf)

err := cmd.Execute()
require.EqualError(t, err, "TODO what is the error")

// Ensure ttl not updated
updated, err := client.Workspace(ctx, workspace.ID)
require.NoError(t, err, "fetch updated workspace")
require.NotNil(t, updated.TTLMillis)
require.Equal(t, (8 * time.Hour).Milliseconds, *updated.TTLMillis)
})
}
12 changes: 8 additions & 4 deletionscoderd/coderdtest/coderdtest.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -322,12 +322,16 @@ func CreateWorkspaceBuild(

// CreateTemplate creates a template with the "echo" provisioner for
// compatibility with testing. The name assigned is randomly generated.
func CreateTemplate(t *testing.T, client *codersdk.Client, organization uuid.UUID, version uuid.UUID) codersdk.Template {
template, err := client.CreateTemplate(context.Background(), organization, codersdk.CreateTemplateRequest{
func CreateTemplate(t *testing.T, client *codersdk.Client, organization uuid.UUID, version uuid.UUID, mutators ...func(*codersdk.CreateTemplateRequest)) codersdk.Template {
req := codersdk.CreateTemplateRequest{
Name: randomUsername(),
Description: randomUsername(),
VersionID: version,
})
}
for _, mut := range mutators {
mut(&req)
}
template, err := client.CreateTemplate(context.Background(), organization, req)
require.NoError(t, err)
return template
}
Expand DownExpand Up@@ -400,7 +404,7 @@ func CreateWorkspace(t *testing.T, client *codersdk.Client, organization uuid.UU
req := codersdk.CreateWorkspaceRequest{
TemplateID: templateID,
Name: randomUsername(),
AutostartSchedule: ptr.Ref("CRON_TZ=US/Central* * * **"),
AutostartSchedule: ptr.Ref("CRON_TZ=US/Central30 9 * *1-5"),
TTLMillis: ptr.Ref((8 * time.Hour).Milliseconds()),
}
for _, mutator := range mutators {
Expand Down
20 changes: 16 additions & 4 deletionscoderd/workspaces_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -588,9 +588,10 @@ func TestWorkspaceUpdateTTL(t *testing.T) {
t.Parallel()

testCases := []struct {
name string
ttlMillis *int64
expectedError string
name string
ttlMillis *int64
expectedError string
modifyTemplate func(*codersdk.CreateTemplateRequest)
}{
{
name: "disable ttl",
Expand All@@ -617,19 +618,30 @@ func TestWorkspaceUpdateTTL(t *testing.T) {
ttlMillis: ptr.Ref((24*7*time.Hour + time.Minute).Milliseconds()),
expectedError: "ttl must be less than 7 days",
},
{
name: "above template maximum ttl",
ttlMillis: ptr.Ref((12*time.Hour + time.Minute).Milliseconds()),
expectedError: "TODO what is the error",
modifyTemplate: func(ctr *codersdk.CreateTemplateRequest) { ctr.MaxTTLMillis = ptr.Ref((8 * time.Hour).Milliseconds()) },
},
}

for _, testCase := range testCases {
testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()

mutators := make([]func(*codersdk.CreateTemplateRequest), 0)
if testCase.modifyTemplate != nil {
mutators = append(mutators, testCase.modifyTemplate)
}
var (
ctx = context.Background()
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user = coderdtest.CreateFirstUser(t, client)
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, mutators...)
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
cwr.AutostartSchedule = nil
cwr.TTLMillis = nil
Expand Down
9 changes: 9 additions & 0 deletionscodersdk/organizations.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -61,6 +61,15 @@ type CreateTemplateRequest struct {
// templates, but it doesn't make sense for users.
VersionID uuid.UUID `json:"template_version_id" validate:"required"`
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`

// MaxTTLMillis allows optionally specifying the maximum allowable TTL
// for all workspaces created from this template.
MaxTTLMillis *int64 `json:"max_ttl_ms,omitempty"`

// MinAutostartIntervalMillis allows optionally specifying the minimum
// allowable duration between autostarts for all workspaces created from
// this template.
MinAutostartIntervalMillis *int64 `json:"min_autostart_interval_ms,omitempty"`
Comment on lines +65 to +72
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Making these optional in creation; if preferred I can make them mandatory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Is this so you don't have some autostart config that says start my workspace every minute?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yup!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thought: Can we make he zero values useful here? Or can these be set to zero to disable them entirely? If zero doesn't need to disable, we can treat it as not set, avoiding the use of pointers.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

FE prefers to consume null instead of zero-values; hence the pointers.
It would be nice though; I'll open a follow-up PR to investigate this.

}

// CreateWorkspaceRequest provides options for creating a new workspace.
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp