Currently the `sync.Once` call is only used to init a Set in the add()
func. So when you add a value to a Set that is the result of one of the
Set operations (i.e. union, difference, intersect) the Set will be
reinitialised and the exiting values will be lost.
I don’t have a clue why this is showing up in my ACC tests just now, as
this code is in there for quite some time already. Somehow it seems to
have something to do with the refactoring of the helper/schema done
last week, as I cannot reproduce this with
47f02f80bc
/cc @svanharmelen - I think some logic changed after my refactor. I now
return Exists: true when Computed: true but the value might be blank to
note that the FieldReader FOUND a value, its just unknown. I think
before it didn't do that so the logic for GetOk has to be "does it exist
and is it _not_ computed"
Seems weird because I just realized there is no way to get the OLD value
of something if it is being computed now, but I looked and there are
tests that verify this and they're like... test #5 of Get. So, they're
not new meaning that must've been expected behavior? Hm. Let me know if
you find any other issues from acceptance tests
/cc @phinze - This is pretty straightforward, almost magically so. The
reason this works is because in `diffString` we use mapstructure[1] with
"weak decode mode" to just be responisble for turning anything into a
string.
[1]: https://github.com/mitchellh/mapstructure
Don't check if the root key is being computed for composite types.
Instead, continue recursing the composite type in order to check if
the sub-key, key.N, for each individual element is being computed.
Fixes a panic which occurs when validating a composite type where
the value is an unknown kind for the schema.
This adds "field.#" values to the state/diff with the element count of a
map. This fixes a major issue around not knowing when child elements are
computed when doing variable access of a computed map.
Example, if you have a schema like this:
"foo": &Schema{
Type: TypeMap,
Computed: true,
}
And you access it like this in a resource:
${type.name.foo.computed-field}
Then Terraform will error that "field foo could not be found on resource
type.name". By adding that "foo.#" is computed, Terraform core will pick
up that it WILL exist, so its okay.
This is a refactored solution for PR #616. Functionally this is still
the same change, but it’s implemented a lot cleaner with less code and
less changes to existing parts of TF.
It’s not enough to only check if no new value is set. It can also be
that a new value is set, but contains a variable that cannot be
interpolated until a depending resource is created during the apply
fase.
I actually found this one as one of the acceptance tests for the AWS
ELB resource was failing. It failed with the following error:
```
--- FAIL: TestAccAWSELB_InstanceAttaching (177.83 seconds)
testing.go:121: Step 1 error: Error applying: aws_elb.bar: diffs
didn't match during apply. This is a bug with the resource provider,
please report a bug.
FAIL
exit status 1
FAIL github.com/hashicorp/terraform/builtin/providers/aws 177.882s
```
After a quick look I noticed it was actually a bug in core TF so added
the test and made sure all unit tests and AWS acceptance tests are now
running successfully.