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

Skip to content

Commit 62f36ea

Browse files
committed
add 2 validation modes
1 parent 0ad4eb6 commit 62f36ea

File tree

3 files changed

+163
-123
lines changed

3 files changed

+163
-123
lines changed

provider/parameter.go

+18-7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Validation struct {
5454
}
5555

5656
const (
57+
ValidationModeEnvVar = "CODER_VALIDATION_MODE"
5758
ValidationMonotonicIncreasing = "increasing"
5859
ValidationMonotonicDecreasing = "decreasing"
5960
)
@@ -153,10 +154,13 @@ func parameterDataSource() *schema.Resource {
153154
input = &envValue
154155
}
155156

156-
value, diags := parameter.Valid(input, ValidationModeDefault)
157+
mode := os.Getenv(ValidationModeEnvVar)
158+
value, diags := parameter.Valid(input, ValidationMode(mode))
157159
if diags.HasError() {
158160
return diags
159161
}
162+
163+
// Always set back the value, as it can be sourced from the default
160164
rd.Set("value", value)
161165

162166
// Set the form_type as it could have changed in the validation.
@@ -423,7 +427,7 @@ func (v *Parameter) Valid(input *string, mode ValidationMode) (string, diag.Diag
423427
}
424428
}
425429

426-
optionValues, diags := v.ValidOptions(optionType)
430+
optionValues, diags := v.ValidOptions(optionType, mode)
427431
if diags.HasError() {
428432
return "", diags
429433
}
@@ -509,7 +513,7 @@ func (v *Parameter) Valid(input *string, mode ValidationMode) (string, diag.Diag
509513
return *value, nil
510514
}
511515

512-
func (v *Parameter) ValidOptions(optionType OptionType) (map[string]struct{}, diag.Diagnostics) {
516+
func (v *Parameter) ValidOptions(optionType OptionType, mode ValidationMode) (map[string]struct{}, diag.Diagnostics) {
513517
optionNames := map[string]struct{}{}
514518
optionValues := map[string]struct{}{}
515519

@@ -545,8 +549,15 @@ func (v *Parameter) ValidOptions(optionType OptionType) (map[string]struct{}, di
545549
optionValues[option.Value] = struct{}{}
546550
optionNames[option.Name] = struct{}{}
547551

548-
// TODO: Option values should also be validated.
549-
// v.validValue(option.Value, optionType, nil, cty.Path{})
552+
if mode == ValidationModeTemplateImport {
553+
opDiags := v.validValue(option.Value, optionType, nil, cty.Path{})
554+
if opDiags.HasError() {
555+
for i := range opDiags {
556+
opDiags[i].Summary = fmt.Sprintf("Option %q: %s", option.Name, opDiags[i].Summary)
557+
}
558+
diags = append(diags, opDiags...)
559+
}
560+
}
550561
}
551562

552563
if diags.HasError() {
@@ -627,9 +638,9 @@ func (v *Parameter) validValue(value string, optionType OptionType, optionValues
627638
return diag.Diagnostics{
628639
{
629640
Severity: diag.Error,
630-
Summary: fmt.Sprintf("Invalid parameter %s according to 'validation' block", strings.ToLower(v.Name)),
641+
Summary: fmt.Sprintf("Invalid parameter %s according to 'validation' block", strings.ToLower(name)),
631642
Detail: err.Error(),
632-
AttributePath: cty.Path{},
643+
AttributePath: path,
633644
},
634645
}
635646
}

provider/parameter_test.go

+65-36
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,8 @@ func TestParameterValidationEnforcement(t *testing.T) {
878878
Validation *provider.Validation
879879
OutputValue string
880880
Optional bool
881-
Error *regexp.Regexp
881+
CreateError *regexp.Regexp
882+
ImportError *regexp.Regexp
882883
}
883884

884885
rows := make([]row, 0)
@@ -909,6 +910,19 @@ func TestParameterValidationEnforcement(t *testing.T) {
909910
t.Fatalf("failed to parse error column %q: %v", columns[9], err)
910911
}
911912
}
913+
914+
var imerr *regexp.Regexp
915+
if columns[10] != "" {
916+
if columns[10] == "=" {
917+
imerr = rerr
918+
} else {
919+
imerr, err = regexp.Compile(columns[10])
920+
if err != nil {
921+
t.Fatalf("failed to parse error column %q: %v", columns[10], err)
922+
}
923+
}
924+
}
925+
912926
var options []string
913927
if columns[4] != "" {
914928
options = strings.Split(columns[4], ",")
@@ -955,7 +969,8 @@ func TestParameterValidationEnforcement(t *testing.T) {
955969
Validation: validation,
956970
OutputValue: columns[7],
957971
Optional: optional,
958-
Error: rerr,
972+
CreateError: rerr,
973+
ImportError: imerr,
959974
})
960975
}
961976

@@ -974,9 +989,9 @@ func TestParameterValidationEnforcement(t *testing.T) {
974989
t.Setenv(provider.ParameterEnvironmentVariable("parameter"), row.InputValue)
975990
}
976991

977-
if row.Error != nil {
992+
if row.CreateError != nil && row.ImportError != nil {
978993
if row.OutputValue != "" {
979-
t.Errorf("output value %q should not be set if error is set", row.OutputValue)
994+
t.Errorf("output value %q should not be set if both errors are set", row.OutputValue)
980995
}
981996
}
982997

@@ -1020,42 +1035,56 @@ func TestParameterValidationEnforcement(t *testing.T) {
10201035

10211036
cfg.WriteString("}\n")
10221037

1023-
resource.Test(t, resource.TestCase{
1024-
ProviderFactories: coderFactory(),
1025-
IsUnitTest: true,
1026-
Steps: []resource.TestStep{{
1027-
Config: cfg.String(),
1028-
ExpectError: row.Error,
1029-
Check: func(state *terraform.State) error {
1030-
require.Len(t, state.Modules, 1)
1031-
require.Len(t, state.Modules[0].Resources, 1)
1032-
param := state.Modules[0].Resources["data.coder_parameter.parameter"]
1033-
require.NotNil(t, param)
1038+
for _, mode := range []provider.ValidationMode{provider.ValidationModeDefault, provider.ValidationModeTemplateImport} {
1039+
name := string(mode)
1040+
if mode == provider.ValidationModeDefault {
1041+
name = "create"
1042+
}
1043+
t.Run(name, func(t *testing.T) {
1044+
t.Setenv("CODER_VALIDATION_MODE", string(mode))
1045+
rerr := row.CreateError
1046+
if mode == provider.ValidationModeTemplateImport {
1047+
rerr = row.ImportError
1048+
}
10341049

1035-
if row.Default == "" {
1036-
_, ok := param.Primary.Attributes["default"]
1037-
require.False(t, ok, "default should not be set")
1038-
} else {
1039-
require.Equal(t, strings.Trim(row.Default, `"`), param.Primary.Attributes["default"])
1040-
}
1050+
resource.Test(t, resource.TestCase{
1051+
ProviderFactories: coderFactory(),
1052+
IsUnitTest: true,
1053+
Steps: []resource.TestStep{{
1054+
Config: cfg.String(),
1055+
ExpectError: rerr,
1056+
Check: func(state *terraform.State) error {
1057+
require.Len(t, state.Modules, 1)
1058+
require.Len(t, state.Modules[0].Resources, 1)
1059+
param := state.Modules[0].Resources["data.coder_parameter.parameter"]
1060+
require.NotNil(t, param)
10411061

1042-
if row.OutputValue == "" {
1043-
_, ok := param.Primary.Attributes["value"]
1044-
require.False(t, ok, "output value should not be set")
1045-
} else {
1046-
require.Equal(t, strings.Trim(row.OutputValue, `"`), param.Primary.Attributes["value"])
1047-
}
1062+
if row.Default == "" {
1063+
_, ok := param.Primary.Attributes["default"]
1064+
require.False(t, ok, "default should not be set")
1065+
} else {
1066+
require.Equal(t, strings.Trim(row.Default, `"`), param.Primary.Attributes["default"])
1067+
}
10481068

1049-
for key, expected := range map[string]string{
1050-
"optional": strconv.FormatBool(row.Optional),
1051-
} {
1052-
require.Equal(t, expected, param.Primary.Attributes[key], "optional")
1053-
}
1069+
if row.OutputValue == "" {
1070+
_, ok := param.Primary.Attributes["value"]
1071+
require.False(t, ok, "output value should not be set")
1072+
} else {
1073+
require.Equal(t, strings.Trim(row.OutputValue, `"`), param.Primary.Attributes["value"])
1074+
}
10541075

1055-
return nil
1056-
},
1057-
}},
1058-
})
1076+
for key, expected := range map[string]string{
1077+
"optional": strconv.FormatBool(row.Optional),
1078+
} {
1079+
require.Equal(t, expected, param.Primary.Attributes[key], "optional")
1080+
}
1081+
1082+
return nil
1083+
},
1084+
}},
1085+
})
1086+
})
1087+
}
10591088
})
10601089
}
10611090
}

0 commit comments

Comments
 (0)