opentofu/terraform/node_data_refresh_test.go
Martin Atkins 68b900928d core: Use instances.Expander to handle resource count and for_each
This is a minimal integration of instances.Expander used just for resource
count and for_each, for now just forcing modules to always be singletons
because the rest of Terraform Core isn't ready to deal with expanding
module calls yet.

This doesn't integrate super cleanly yet because we still have some
cleanup work to do in the design of the plan walk, to make it explicit
that the nodes in the plan graph represent static configuration objects
rather than expanded instances, including for modules. To make this work
in the meantime, there is some shimming between addrs.Module and
addrs.ModuleInstance to correct for the discontinuities that result from
the fact that Terraform currently assumes that modules are always
singletons.
2020-02-14 15:20:07 -08:00

183 lines
5.2 KiB
Go

package terraform
import (
"testing"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/instances"
)
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(),
InstanceExpanderExpander: instances.NewExpander(),
// 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{
Provider: addrs.NewLegacyProvider("aws"),
Module: addrs.RootModuleInstance,
},
},
}
g, err := n.DynamicExpand(&MockEvalContext{
PathPath: addrs.RootModuleInstance,
StateState: state.SyncWrapper(),
InstanceExpanderExpander: instances.NewExpander(),
// 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.NodeDestroyableDataResourceInstance
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.NodeDestroyableDataResourceInstance
`
if expected != actual {
t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
}
var destroyableDataResource *NodeDestroyableDataResourceInstance
for _, v := range g.Vertices() {
if r, ok := v.(*NodeDestroyableDataResourceInstance); ok {
destroyableDataResource = r
}
}
if destroyableDataResource == nil {
t.Fatal("failed to find a destroyableDataResource")
}
if destroyableDataResource.ResolvedProvider.Provider.Type == "" {
t.Fatal("NodeDestroyableDataResourceInstance missing provider config")
}
}