Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 391ed16

Browse files
committed
fixup test to take an opinion
1 parent 0ed9ccc commit 391ed16

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed

coderd/dynamicparameters/resolver.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func ResolveParameters(
106106
//
107107
// This is how the form should look to the user on their workspace settings page.
108108
// This is the original form truth that our validations should initially be based on.
109-
output, diags := renderer.Render(ctx, ownerID, values.ValuesMap())
109+
output, diags := renderer.Render(ctx, ownerID, previousValuesMap)
110110
if diags.HasErrors() {
111111
// Top level diagnostics should break the build. Previous values (and new) should
112112
// always be valid. If there is a case where this is not true, then this has to
@@ -123,6 +123,7 @@ func ResolveParameters(
123123
//
124124
// To enforce these, the user's input values are trimmed based on the
125125
// mutability and ephemeral parameters defined in the template version.
126+
wasImmutable := make(map[string]struct{})
126127
for _, parameter := range output.Parameters {
127128
// Ephemeral parameters should not be taken from the previous build.
128129
// They must always be explicitly set in every build.
@@ -140,6 +141,7 @@ func ResolveParameters(
140141
//
141142
// We do this so the next form render uses the original immutable value.
142143
if !firstBuild && !parameter.Mutable {
144+
wasImmutable[parameter.Name] = struct{}{}
143145
delete(values, parameter.Name)
144146
prev, ok := previousValuesMap[parameter.Name]
145147
if ok {
@@ -168,7 +170,12 @@ func ResolveParameters(
168170
for _, parameter := range output.Parameters {
169171
parameterNames[parameter.Name] = struct{}{}
170172

171-
if !firstBuild && !parameter.Mutable {
173+
// Immutability is sourced from the current `mutable` argument, and also the
174+
// previous parameter's `mutable` argument. This means you cannot flip an
175+
// `immutable` parameter to `mutable` in a single build. This is to preserve the
176+
// original mutability of the parameter.
177+
_, wi := wasImmutable[parameter.Name]
178+
if !firstBuild && (!parameter.Mutable || wi) {
172179
originalValue, ok := originalValues[parameter.Name]
173180
// Immutable parameters should not be changed after the first build.
174181
// If the value matches the original value, that is fine.
@@ -182,13 +189,19 @@ func ResolveParameters(
182189
if parameter.Source != nil {
183190
src = &parameter.Source.HCLBlock().TypeRange
184191
}
192+
errTitle := "Immutable"
193+
// In the strange case someone flips mutability from `true` to `false`.
194+
// Change the error title to indicate that this was previously immutable.
195+
if wi && parameter.Mutable {
196+
errTitle = "Previously immutable"
197+
}
185198

186199
// An immutable parameter was changed, which is not allowed.
187200
// Add a failed diagnostic to the output.
188201
parameterError.Extend(parameter.Name, hcl.Diagnostics{
189202
&hcl.Diagnostic{
190203
Severity: hcl.DiagError,
191-
Summary: "Immutable parameter changed",
204+
Summary: fmt.Sprintf("%s parameter changed", errTitle),
192205
Detail: fmt.Sprintf("Parameter %q is not mutable, so it can't be updated after creating a workspace.", parameter.Name),
193206
Subject: src,
194207
},

coderd/dynamicparameters/resolver_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,58 @@ import (
2020
func TestResolveParameters(t *testing.T) {
2121
t.Parallel()
2222

23+
t.Run("ChangeImmutable", func(t *testing.T) {
24+
t.Parallel()
25+
26+
ctrl := gomock.NewController(t)
27+
render := rendermock.NewMockRenderer(ctrl)
28+
29+
// The first render takes in the existing values
30+
render.EXPECT().
31+
Render(gomock.Any(), gomock.Any(), gomock.Any()).
32+
Return(&preview.Output{
33+
Parameters: []previewtypes.Parameter{
34+
{
35+
ParameterData: previewtypes.ParameterData{
36+
Name: "immutable",
37+
Type: previewtypes.ParameterTypeString,
38+
FormType: provider.ParameterFormTypeInput,
39+
Mutable: false,
40+
DefaultValue: previewtypes.StringLiteral("foo"),
41+
Required: true,
42+
},
43+
Value: previewtypes.StringLiteral("foo"),
44+
Diagnostics: nil,
45+
},
46+
},
47+
}, nil).
48+
Return(&preview.Output{
49+
Parameters: []previewtypes.Parameter{
50+
{
51+
ParameterData: previewtypes.ParameterData{
52+
Name: "immutable",
53+
Type: previewtypes.ParameterTypeString,
54+
FormType: provider.ParameterFormTypeInput,
55+
Mutable: false,
56+
DefaultValue: previewtypes.StringLiteral("foo"),
57+
Required: true,
58+
},
59+
Value: previewtypes.StringLiteral("foo"),
60+
Diagnostics: nil,
61+
},
62+
},
63+
}, nil)
64+
65+
ctx := testutil.Context(t, testutil.WaitShort)
66+
values, err := dynamicparameters.ResolveParameters(ctx, uuid.New(), render, false,
67+
[]database.WorkspaceBuildParameter{}, // No previous values
68+
[]codersdk.WorkspaceBuildParameter{}, // No new build values
69+
[]database.TemplateVersionPresetParameter{}, // No preset values
70+
)
71+
require.NoError(t, err)
72+
require.Equal(t, map[string]string{"immutable": "foo"}, values)
73+
})
74+
2375
t.Run("NewImmutable", func(t *testing.T) {
2476
t.Parallel()
2577

enterprise/coderd/dynamicparameters_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ func TestDynamicParameterBuild(t *testing.T) {
355355
t.Run("ImmutableChangeValue", func(t *testing.T) {
356356
// Ok this is a weird test to document how things are working.
357357
// What if a parameter flips it's immutability based on a value?
358+
// The current behavior is to source immutability from the previous build.
358359
t.Parallel()
359360

360361
ctx := testutil.Context(t, testutil.WaitShort)
@@ -376,15 +377,14 @@ func TestDynamicParameterBuild(t *testing.T) {
376377
coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, wrk.LatestBuild.ID)
377378

378379
// Try new values
379-
bld, err := templateAdmin.CreateWorkspaceBuild(ctx, wrk.ID, codersdk.CreateWorkspaceBuildRequest{
380+
_, err = templateAdmin.CreateWorkspaceBuild(ctx, wrk.ID, codersdk.CreateWorkspaceBuildRequest{
380381
Transition: codersdk.WorkspaceTransitionStart,
381382
RichParameterValues: []codersdk.WorkspaceBuildParameter{
382383
{Name: "isimmutable", Value: "false"},
383384
{Name: "immutable", Value: "not-coder"},
384385
},
385386
})
386-
require.NoError(t, err)
387-
coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, bld.ID)
387+
require.ErrorContains(t, err, `Previously immutable parameter changed`)
388388
})
389389
})
390390
}

0 commit comments

Comments
 (0)