core: Don't fail on dynamic attribute values during refresh
Our post-refresh safety check had the constraint and real type inverted, so previously any refresh of a resource type with a dynamically-typed attribute would fail this type check. Also includes a small tweak to the error message from this check since the old one was a little awkward to read in practice when the error is a cty.PathError rendered with an attribute path prefix.
This commit is contained in:
parent
87fe6cbecd
commit
04cbf249aa
|
@ -89,6 +89,79 @@ func TestContext2Refresh(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContext2Refresh_dynamicAttr(t *testing.T) {
|
||||
m := testModule(t, "refresh-dynamic")
|
||||
|
||||
startingState := states.BuildState(func(ss *states.SyncState) {
|
||||
ss.SetResourceInstanceCurrent(
|
||||
addrs.Resource{
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
Type: "test_instance",
|
||||
Name: "foo",
|
||||
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
||||
&states.ResourceInstanceObjectSrc{
|
||||
Status: states.ObjectReady,
|
||||
AttrsJSON: []byte(`{"dynamic":{"type":"string","value":"hello"}}`),
|
||||
},
|
||||
addrs.ProviderConfig{
|
||||
Type: "test",
|
||||
}.Absolute(addrs.RootModuleInstance),
|
||||
)
|
||||
})
|
||||
|
||||
readStateVal := cty.ObjectVal(map[string]cty.Value{
|
||||
"dynamic": cty.EmptyTupleVal,
|
||||
})
|
||||
|
||||
p := testProvider("test")
|
||||
p.GetSchemaReturn = &ProviderSchema{
|
||||
ResourceTypes: map[string]*configschema.Block{
|
||||
"test_instance": {
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"dynamic": {Type: cty.DynamicPseudoType, Optional: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||
return providers.ReadResourceResponse{
|
||||
NewState: readStateVal,
|
||||
}
|
||||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Config: m,
|
||||
ProviderResolver: providers.ResolverFixed(
|
||||
map[string]providers.Factory{
|
||||
"test": testProviderFuncFixed(p),
|
||||
},
|
||||
),
|
||||
State: startingState,
|
||||
})
|
||||
|
||||
schema := p.GetSchemaReturn.ResourceTypes["test_instance"]
|
||||
ty := schema.ImpliedType()
|
||||
|
||||
s, diags := ctx.Refresh()
|
||||
if diags.HasErrors() {
|
||||
t.Fatal(diags.Err())
|
||||
}
|
||||
|
||||
if !p.ReadResourceCalled {
|
||||
t.Fatal("ReadResource should be called")
|
||||
}
|
||||
|
||||
mod := s.RootModule()
|
||||
newState, err := mod.Resources["test_instance.foo"].Instances[addrs.NoKey].Current.Decode(ty)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !cmp.Equal(readStateVal, newState.Value, valueComparer) {
|
||||
t.Error(cmp.Diff(newState.Value, readStateVal, valueComparer, equateEmpty))
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Refresh_dataComputedModuleVar(t *testing.T) {
|
||||
p := testProvider("aws")
|
||||
m := testModule(t, "refresh-data-module-var")
|
||||
|
|
|
@ -71,12 +71,12 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
|
|||
panic("new state is cty.NilVal")
|
||||
}
|
||||
|
||||
for _, err := range schema.ImpliedType().TestConformance(resp.NewState.Type()) {
|
||||
for _, err := range resp.NewState.Type().TestConformance(schema.ImpliedType()) {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Provider produced invalid object",
|
||||
fmt.Sprintf(
|
||||
"Provider %q planned an invalid value for %s: %s during refresh.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.",
|
||||
"Provider %q planned an invalid value for %s during refresh: %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.",
|
||||
n.ProviderAddr.ProviderConfig.Type, absAddr, tfdiags.FormatError(err),
|
||||
),
|
||||
))
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
resource "test_instance" "foo" {
|
||||
dynamic = {}
|
||||
}
|
Loading…
Reference in New Issue