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) {
|
func TestContext2Refresh_dataComputedModuleVar(t *testing.T) {
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
m := testModule(t, "refresh-data-module-var")
|
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")
|
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(
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
tfdiags.Error,
|
tfdiags.Error,
|
||||||
"Provider produced invalid object",
|
"Provider produced invalid object",
|
||||||
fmt.Sprintf(
|
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),
|
n.ProviderAddr.ProviderConfig.Type, absAddr, tfdiags.FormatError(err),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
resource "test_instance" "foo" {
|
||||||
|
dynamic = {}
|
||||||
|
}
|
Loading…
Reference in New Issue