Skip to content

Commit 786f77b

Browse files
committed
add some parameter tests
1 parent b4bf24f commit 786f77b

File tree

8 files changed

+196
-66
lines changed

8 files changed

+196
-66
lines changed

cli/parameter.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type workspaceParameterFlags struct {
2020

2121
richParameterFile string
2222
richParameters []string
23+
24+
promptRichParameters bool
2325
}
2426

2527
func (wpf *workspaceParameterFlags) cliBuildOptions() []clibase.Option {
@@ -52,6 +54,11 @@ func (wpf *workspaceParameterFlags) cliParameters() []clibase.Option {
5254
Description: "Specify a file path with values for rich parameters defined in the template.",
5355
Value: clibase.StringOf(&wpf.richParameterFile),
5456
},
57+
{
58+
Flag: "always-prompt",
59+
Description: "Always prompt all parameters. Does not pull parameter values from existing workspace.",
60+
Value: clibase.BoolOf(&wpf.promptRichParameters),
61+
},
5562
}
5663
}
5764

cli/parameterresolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func (pr *ParameterResolver) resolveWithInput(resolved []codersdk.WorkspaceBuild
194194
(action == WorkspaceUpdate && promptParameterOption) ||
195195
(action == WorkspaceUpdate && tvp.Mutable && tvp.Required) ||
196196
(action == WorkspaceUpdate && !tvp.Mutable && firstTimeUse) ||
197-
(action == WorkspaceUpdate && tvp.Mutable && !tvp.Ephemeral && pr.promptRichParameters) {
197+
(tvp.Mutable && !tvp.Ephemeral && pr.promptRichParameters) {
198198
parameterValue, err := cliui.RichParameter(inv, tvp)
199199
if err != nil {
200200
return nil, err

cli/restart.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (r *RootCmd) restart() *clibase.Cmd {
2525
clibase.RequireNArgs(1),
2626
r.InitClient(client),
2727
),
28-
Options: append(parameterFlags.cliBuildOptions(), cliui.SkipPromptOption()),
28+
Options: clibase.OptionSet{cliui.SkipPromptOption()},
2929
Handler: func(inv *clibase.Invocation) error {
3030
ctx := inv.Context()
3131
out := inv.Stdout
@@ -35,11 +35,10 @@ func (r *RootCmd) restart() *clibase.Cmd {
3535
return err
3636
}
3737

38-
startReq, err := workspaceStartRequest(inv, client, startWorkspaceArgs{
39-
workspace: workspace,
40-
action: WorkspaceRestart,
41-
parameterFlags: parameterFlags,
42-
promptRichParameters: false,
38+
startReq, err := buildWorkspaceStartRequest(inv, client, startWorkspaceArgs{
39+
workspace: workspace,
40+
action: WorkspaceRestart,
41+
parameterFlags: parameterFlags,
4342
})
4443
if err != nil {
4544
return err
@@ -70,10 +69,9 @@ func (r *RootCmd) restart() *clibase.Cmd {
7069
// workspaces with the active version.
7170
if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusUnauthorized {
7271
build, err = startWorkspace(inv, client, startWorkspaceArgs{
73-
workspace: workspace,
74-
parameterFlags: parameterFlags,
75-
action: WorkspaceUpdate,
76-
promptRichParameters: false,
72+
workspace: workspace,
73+
parameterFlags: parameterFlags,
74+
action: WorkspaceUpdate,
7775
})
7876
if err != nil {
7977
return xerrors.Errorf("start workspace with active template version: %w", err)
@@ -94,5 +92,9 @@ func (r *RootCmd) restart() *clibase.Cmd {
9492
return nil
9593
},
9694
}
95+
96+
cmd.Options = append(cmd.Options, parameterFlags.cliBuildOptions()...)
97+
cmd.Options = append(cmd.Options, parameterFlags.cliParameters()...)
98+
9799
return cmd
98100
}

cli/restart_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,56 @@ func TestRestartWithParameters(t *testing.T) {
239239
Value: immutableParameterValue,
240240
})
241241
})
242+
243+
t.Run("AlwaysPrompt", func(t *testing.T) {
244+
t.Parallel()
245+
246+
// Create the workspace
247+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
248+
owner := coderdtest.CreateFirstUser(t, client)
249+
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
250+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, mutableParamsResponse)
251+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
252+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
253+
workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
254+
cwr.RichParameterValues = []codersdk.WorkspaceBuildParameter{
255+
{
256+
Name: mutableParameterName,
257+
Value: mutableParameterValue,
258+
},
259+
}
260+
})
261+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
262+
263+
// Restart the workspace again
264+
inv, root := clitest.New(t, "restart", workspace.Name, "-y", "--always-prompt")
265+
clitest.SetupConfig(t, member, root)
266+
doneChan := make(chan struct{})
267+
pty := ptytest.New(t).Attach(inv)
268+
go func() {
269+
defer close(doneChan)
270+
err := inv.Run()
271+
assert.NoError(t, err)
272+
}()
273+
274+
newValue := "xyz"
275+
pty.ExpectMatch(mutableParameterName)
276+
pty.WriteLine(newValue)
277+
pty.ExpectMatch("workspace has been restarted")
278+
<-doneChan
279+
280+
// Verify if immutable parameter is set
281+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
282+
defer cancel()
283+
284+
workspace, err := client.WorkspaceByOwnerAndName(ctx, workspace.OwnerName, workspace.Name, codersdk.WorkspaceOptions{})
285+
require.NoError(t, err)
286+
actualParameters, err := client.WorkspaceBuildParameters(ctx, workspace.LatestBuild.ID)
287+
require.NoError(t, err)
288+
require.Contains(t, actualParameters, codersdk.WorkspaceBuildParameter{
289+
Name: mutableParameterName,
290+
Value: newValue,
291+
})
292+
293+
})
242294
}

cli/start.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,25 @@ func (r *RootCmd) start() *clibase.Cmd {
2424
clibase.RequireNArgs(1),
2525
r.InitClient(client),
2626
),
27-
Options: append(parameterFlags.cliBuildOptions(), cliui.SkipPromptOption()),
27+
Options: clibase.OptionSet{cliui.SkipPromptOption()},
2828
Handler: func(inv *clibase.Invocation) error {
2929
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
3030
if err != nil {
3131
return err
3232
}
3333

3434
build, err := startWorkspace(inv, client, startWorkspaceArgs{
35-
workspace: workspace,
36-
parameterFlags: parameterFlags,
37-
action: WorkspaceStart,
38-
promptRichParameters: false,
35+
workspace: workspace,
36+
parameterFlags: parameterFlags,
37+
action: WorkspaceStart,
3938
})
4039
// It's possible for a workspace build to fail due to the template requiring starting
4140
// workspaces with the active version.
4241
if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusUnauthorized {
4342
build, err = startWorkspace(inv, client, startWorkspaceArgs{
44-
workspace: workspace,
45-
parameterFlags: parameterFlags,
46-
action: WorkspaceUpdate,
47-
promptRichParameters: false,
43+
workspace: workspace,
44+
parameterFlags: parameterFlags,
45+
action: WorkspaceUpdate,
4846
})
4947
if err != nil {
5048
return xerrors.Errorf("start workspace with active template version: %w", err)
@@ -65,17 +63,20 @@ func (r *RootCmd) start() *clibase.Cmd {
6563
return nil
6664
},
6765
}
66+
67+
cmd.Options = append(cmd.Options, parameterFlags.cliBuildOptions()...)
68+
cmd.Options = append(cmd.Options, parameterFlags.cliParameters()...)
69+
6870
return cmd
6971
}
7072

7173
type startWorkspaceArgs struct {
72-
workspace codersdk.Workspace
73-
parameterFlags workspaceParameterFlags
74-
action WorkspaceCLIAction
75-
promptRichParameters bool
74+
workspace codersdk.Workspace
75+
parameterFlags workspaceParameterFlags
76+
action WorkspaceCLIAction
7677
}
7778

78-
func workspaceStartRequest(inv *clibase.Invocation, client *codersdk.Client, args startWorkspaceArgs) (codersdk.CreateWorkspaceBuildRequest, error) {
79+
func buildWorkspaceStartRequest(inv *clibase.Invocation, client *codersdk.Client, args startWorkspaceArgs) (codersdk.CreateWorkspaceBuildRequest, error) {
7980
version := args.workspace.LatestBuild.TemplateVersionID
8081
if args.workspace.AutomaticUpdates == codersdk.AutomaticUpdatesAlways || args.action == WorkspaceUpdate {
8182
template, err := client.Template(inv.Context(), args.workspace.TemplateID)
@@ -111,7 +112,7 @@ func workspaceStartRequest(inv *clibase.Invocation, client *codersdk.Client, arg
111112

112113
PromptBuildOptions: args.parameterFlags.promptBuildOptions,
113114
BuildOptions: buildOptions,
114-
PromptRichParameters: args.promptRichParameters,
115+
PromptRichParameters: args.parameterFlags.promptRichParameters,
115116
RichParameters: cliRichParameters,
116117
RichParameterFile: args.parameterFlags.richParameterFile,
117118
})
@@ -127,7 +128,7 @@ func workspaceStartRequest(inv *clibase.Invocation, client *codersdk.Client, arg
127128
}
128129

129130
func startWorkspace(inv *clibase.Invocation, client *codersdk.Client, args startWorkspaceArgs) (codersdk.WorkspaceBuild, error) {
130-
req, err := workspaceStartRequest(inv, client, args)
131+
req, err := buildWorkspaceStartRequest(inv, client, args)
131132
if err != nil {
132133
return codersdk.WorkspaceBuild{}, err
133134
}

cli/start_test.go

Lines changed: 102 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,52 @@ const (
2626
immutableParameterName = "immutable_parameter"
2727
immutableParameterDescription = "This is immutable parameter"
2828
immutableParameterValue = "abc"
29+
30+
mutableParameterName = "mutable_parameter"
31+
mutableParameterValue = "hello"
32+
)
33+
34+
var (
35+
mutableParamsResponse = &echo.Responses{
36+
Parse: echo.ParseComplete,
37+
ProvisionPlan: []*proto.Response{
38+
{
39+
Type: &proto.Response_Plan{
40+
Plan: &proto.PlanComplete{
41+
Parameters: []*proto.RichParameter{
42+
{
43+
Name: mutableParameterName,
44+
Description: "This is a mutable parameter",
45+
Required: true,
46+
Mutable: true,
47+
},
48+
},
49+
},
50+
},
51+
},
52+
},
53+
ProvisionApply: echo.ApplyComplete,
54+
}
55+
56+
immutableParamsResponse = &echo.Responses{
57+
Parse: echo.ParseComplete,
58+
ProvisionPlan: []*proto.Response{
59+
{
60+
Type: &proto.Response_Plan{
61+
Plan: &proto.PlanComplete{
62+
Parameters: []*proto.RichParameter{
63+
{
64+
Name: immutableParameterName,
65+
Description: immutableParameterDescription,
66+
Required: true,
67+
},
68+
},
69+
},
70+
},
71+
},
72+
},
73+
ProvisionApply: echo.ApplyComplete,
74+
}
2975
)
3076

3177
func TestStart(t *testing.T) {
@@ -147,34 +193,14 @@ func TestStart(t *testing.T) {
147193
func TestStartWithParameters(t *testing.T) {
148194
t.Parallel()
149195

150-
echoResponses := &echo.Responses{
151-
Parse: echo.ParseComplete,
152-
ProvisionPlan: []*proto.Response{
153-
{
154-
Type: &proto.Response_Plan{
155-
Plan: &proto.PlanComplete{
156-
Parameters: []*proto.RichParameter{
157-
{
158-
Name: immutableParameterName,
159-
Description: immutableParameterDescription,
160-
Required: true,
161-
},
162-
},
163-
},
164-
},
165-
},
166-
},
167-
ProvisionApply: echo.ApplyComplete,
168-
}
169-
170196
t.Run("DoNotAskForImmutables", func(t *testing.T) {
171197
t.Parallel()
172198

173199
// Create the workspace
174200
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
175201
owner := coderdtest.CreateFirstUser(t, client)
176202
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
177-
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses)
203+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, immutableParamsResponse)
178204
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
179205
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
180206
workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
@@ -218,6 +244,61 @@ func TestStartWithParameters(t *testing.T) {
218244
Value: immutableParameterValue,
219245
})
220246
})
247+
248+
t.Run("AlwaysPrompt", func(t *testing.T) {
249+
t.Parallel()
250+
251+
// Create the workspace
252+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
253+
owner := coderdtest.CreateFirstUser(t, client)
254+
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
255+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, mutableParamsResponse)
256+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
257+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
258+
workspace := coderdtest.CreateWorkspace(t, member, owner.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
259+
cwr.RichParameterValues = []codersdk.WorkspaceBuildParameter{
260+
{
261+
Name: mutableParameterName,
262+
Value: mutableParameterValue,
263+
},
264+
}
265+
})
266+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
267+
268+
// Stop the workspace
269+
workspaceBuild := coderdtest.CreateWorkspaceBuild(t, client, workspace, database.WorkspaceTransitionStop)
270+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspaceBuild.ID)
271+
272+
// Start the workspace again
273+
inv, root := clitest.New(t, "start", workspace.Name, "--always-prompt")
274+
clitest.SetupConfig(t, member, root)
275+
doneChan := make(chan struct{})
276+
pty := ptytest.New(t).Attach(inv)
277+
go func() {
278+
defer close(doneChan)
279+
err := inv.Run()
280+
assert.NoError(t, err)
281+
}()
282+
283+
newValue := "xyz"
284+
pty.ExpectMatch(mutableParameterName)
285+
pty.WriteLine(newValue)
286+
pty.ExpectMatch("workspace has been started")
287+
<-doneChan
288+
289+
// Verify if immutable parameter is set
290+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
291+
defer cancel()
292+
293+
workspace, err := client.WorkspaceByOwnerAndName(ctx, workspace.OwnerName, workspace.Name, codersdk.WorkspaceOptions{})
294+
require.NoError(t, err)
295+
actualParameters, err := client.WorkspaceBuildParameters(ctx, workspace.LatestBuild.ID)
296+
require.NoError(t, err)
297+
require.Contains(t, actualParameters, codersdk.WorkspaceBuildParameter{
298+
Name: mutableParameterName,
299+
Value: newValue,
300+
})
301+
})
221302
}
222303

223304
// TestStartAutoUpdate also tests restart since the flows are virtually identical.

0 commit comments

Comments
 (0)