helper/schema: computed bool fields should not crash

Fixes #7715

If a bool field was computed and the raw value was not convertable to a
boolean, helper/schema would crash. The correct behavior is to try not
to read the raw value when the value is computed and to simply mark that
it is computed. This does that (and matches the behavior of the other
primitives).
This commit is contained in:
Mitchell Hashimoto 2016-11-02 13:25:23 -07:00
parent 13483b574e
commit 7834cf7190
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
3 changed files with 104 additions and 0 deletions

View File

@ -223,6 +223,9 @@ func stringToPrimitive(
returnVal = false
break
}
if computed {
break
}
v, err := strconv.ParseBool(value)
if err != nil {

View File

@ -49,6 +49,71 @@ func TestConfigFieldReader(t *testing.T) {
})
}
// This contains custom table tests for our ConfigFieldReader
func TestConfigFieldReader_custom(t *testing.T) {
schema := map[string]*Schema{
"bool": &Schema{
Type: TypeBool,
},
}
cases := map[string]struct {
Addr []string
Result FieldReadResult
Config *terraform.ResourceConfig
Err bool
}{
"basic": {
[]string{"bool"},
FieldReadResult{
Value: true,
Exists: true,
},
testConfig(t, map[string]interface{}{
"bool": true,
}),
false,
},
"computed": {
[]string{"bool"},
FieldReadResult{
Exists: true,
Computed: true,
},
testConfigInterpolate(t, map[string]interface{}{
"bool": "${var.foo}",
}, map[string]ast.Variable{
"var.foo": ast.Variable{
Value: config.UnknownVariableValue,
Type: ast.TypeString,
},
}),
false,
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
r := &ConfigFieldReader{
Schema: schema,
Config: tc.Config,
}
out, err := r.ReadField(tc.Addr)
if err != nil != tc.Err {
t.Fatalf("%s: err: %s", name, err)
}
if s, ok := out.Value.(*Set); ok {
// If it is a set, convert to a list so its more easily checked.
out.Value = s.List()
}
if !reflect.DeepEqual(tc.Result, out) {
t.Fatalf("%s: bad: %#v", name, out)
}
})
}
}
func TestConfigFieldReader_DefaultHandling(t *testing.T) {
schema := map[string]*Schema{
"strWithDefault": &Schema{

View File

@ -2455,6 +2455,42 @@ func TestSchemaMap_Diff(t *testing.T) {
Err: false,
},
// GH-7715
"computed value for boolean field": {
Schema: map[string]*Schema{
"foo": &Schema{
Type: TypeBool,
ForceNew: true,
Computed: true,
Optional: true,
},
},
State: &terraform.InstanceState{},
Config: map[string]interface{}{
"foo": "${var.foo}",
},
ConfigVariables: map[string]ast.Variable{
"var.foo": interfaceToVariableSwallowError(
config.UnknownVariableValue),
},
Diff: &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{
Old: "",
New: "false",
NewComputed: true,
RequiresNew: true,
},
},
},
Err: false,
},
}
for tn, tc := range cases {