mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 01:41:48 -06:00
06a75b8038
Make sure that NodeDestroyableDataResource has a ResolvedProvider to call EvalWriteState. This entails setting the ResolvedProvider in concreteResourceDestroyable, as well as calling EvalGetProvider in NodeDestroyableDataResource to load the provider schema. Even though writing the state for a data destroy node should just be removing the instance, every instance written sets the Provider for the entire resource. This means that when scaling back a counted data source, if the removed instances are written last, the data source will be missing the provider in the state.
181 lines
4.9 KiB
Go
181 lines
4.9 KiB
Go
package terraform
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
)
|
|
|
|
func TestNodeRefreshableDataResourceDynamicExpand_scaleOut(t *testing.T) {
|
|
m := testModule(t, "refresh-data-scale-inout")
|
|
|
|
state := MustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"data.aws_instance.foo.0": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
"data.aws_instance.foo.1": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
n := &NodeRefreshableDataResource{
|
|
NodeAbstractResource: &NodeAbstractResource{
|
|
Addr: addrs.RootModuleInstance.Resource(
|
|
addrs.DataResourceMode,
|
|
"aws_instance",
|
|
"foo",
|
|
),
|
|
Config: m.Module.DataResources["data.aws_instance.foo"],
|
|
},
|
|
}
|
|
|
|
g, err := n.DynamicExpand(&MockEvalContext{
|
|
PathPath: addrs.RootModuleInstance,
|
|
StateState: state.SyncWrapper(),
|
|
|
|
// DynamicExpand will call EvaluateExpr to evaluate the "count"
|
|
// expression, which is just a literal number 3 in the fixture config
|
|
// and so we'll just hard-code this here too.
|
|
EvaluateExprResult: cty.NumberIntVal(3),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("error on DynamicExpand: %s", err)
|
|
}
|
|
|
|
actual := g.StringWithNodeTypes()
|
|
expected := `data.aws_instance.foo[0] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[1] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[2] - *terraform.NodeRefreshableDataResourceInstance
|
|
root - terraform.graphNodeRoot
|
|
data.aws_instance.foo[0] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[1] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[2] - *terraform.NodeRefreshableDataResourceInstance
|
|
`
|
|
if expected != actual {
|
|
t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestNodeRefreshableDataResourceDynamicExpand_scaleIn(t *testing.T) {
|
|
m := testModule(t, "refresh-data-scale-inout")
|
|
|
|
state := MustShimLegacyState(&State{
|
|
Modules: []*ModuleState{
|
|
&ModuleState{
|
|
Path: rootModulePath,
|
|
Resources: map[string]*ResourceState{
|
|
"data.aws_instance.foo.0": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "foo",
|
|
},
|
|
},
|
|
},
|
|
"data.aws_instance.foo.1": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
},
|
|
"data.aws_instance.foo.2": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "baz",
|
|
},
|
|
},
|
|
},
|
|
"data.aws_instance.foo.3": &ResourceState{
|
|
Type: "aws_instance",
|
|
Deposed: []*InstanceState{
|
|
&InstanceState{
|
|
ID: "qux",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
n := &NodeRefreshableDataResource{
|
|
NodeAbstractResource: &NodeAbstractResource{
|
|
Addr: addrs.RootModuleInstance.Resource(
|
|
addrs.DataResourceMode,
|
|
"aws_instance",
|
|
"foo",
|
|
),
|
|
Config: m.Module.DataResources["data.aws_instance.foo"],
|
|
ResolvedProvider: addrs.AbsProviderConfig{
|
|
ProviderConfig: addrs.ProviderConfig{
|
|
Type: "aws",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
g, err := n.DynamicExpand(&MockEvalContext{
|
|
PathPath: addrs.RootModuleInstance,
|
|
StateState: state.SyncWrapper(),
|
|
|
|
// DynamicExpand will call EvaluateExpr to evaluate the "count"
|
|
// expression, which is just a literal number 3 in the fixture config
|
|
// and so we'll just hard-code this here too.
|
|
EvaluateExprResult: cty.NumberIntVal(3),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("error on DynamicExpand: %s", err)
|
|
}
|
|
actual := g.StringWithNodeTypes()
|
|
expected := `data.aws_instance.foo[0] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[1] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[2] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[3] - *terraform.NodeDestroyableDataResource
|
|
root - terraform.graphNodeRoot
|
|
data.aws_instance.foo[0] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[1] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[2] - *terraform.NodeRefreshableDataResourceInstance
|
|
data.aws_instance.foo[3] - *terraform.NodeDestroyableDataResource
|
|
`
|
|
if expected != actual {
|
|
t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
|
|
}
|
|
|
|
var destroyableDataResource *NodeDestroyableDataResource
|
|
for _, v := range g.Vertices() {
|
|
if r, ok := v.(*NodeDestroyableDataResource); ok {
|
|
destroyableDataResource = r
|
|
}
|
|
}
|
|
|
|
if destroyableDataResource == nil {
|
|
t.Fatal("failed to find a destroyableDataResource")
|
|
}
|
|
|
|
if destroyableDataResource.ResolvedProvider.ProviderConfig.Type == "" {
|
|
t.Fatal("NodeDestroyableDataResource missing provider config")
|
|
}
|
|
}
|