opentofu/terraform/node_resource_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

185 lines
5.3 KiB
Go

package terraform
import (
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/instances"
)
func TestNodeRefreshableManagedResourceDynamicExpand_scaleOut(t *testing.T) {
m := testModule(t, "refresh-resource-scale-inout")
state := MustShimLegacyState(&State{
Modules: []*ModuleState{
&ModuleState{
Path: rootModulePath,
Resources: map[string]*ResourceState{
"aws_instance.foo.0": &ResourceState{
Type: "aws_instance",
Deposed: []*InstanceState{
&InstanceState{
ID: "foo",
},
},
},
"aws_instance.foo.1": &ResourceState{
Type: "aws_instance",
Deposed: []*InstanceState{
&InstanceState{
ID: "bar",
},
},
},
},
},
},
}).SyncWrapper()
n := &NodeRefreshableManagedResource{
NodeAbstractResource: &NodeAbstractResource{
Addr: addrs.RootModuleInstance.Resource(
addrs.ManagedResourceMode, "aws_instance", "foo",
),
Config: m.Module.ManagedResources["aws_instance.foo"],
},
}
g, err := n.DynamicExpand(&MockEvalContext{
PathPath: addrs.RootModuleInstance,
StateState: state,
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 attempting DynamicExpand: %s", err)
}
actual := g.StringWithNodeTypes()
expected := `aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
root - terraform.graphNodeRoot
aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
`
if expected != actual {
t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
}
}
func TestNodeRefreshableManagedResourceDynamicExpand_scaleIn(t *testing.T) {
m := testModule(t, "refresh-resource-scale-inout")
state := MustShimLegacyState(&State{
Modules: []*ModuleState{
&ModuleState{
Path: rootModulePath,
Resources: map[string]*ResourceState{
"aws_instance.foo.0": &ResourceState{
Type: "aws_instance",
Deposed: []*InstanceState{
&InstanceState{
ID: "foo",
},
},
},
"aws_instance.foo.1": &ResourceState{
Type: "aws_instance",
Deposed: []*InstanceState{
&InstanceState{
ID: "bar",
},
},
},
"aws_instance.foo.2": &ResourceState{
Type: "aws_instance",
Deposed: []*InstanceState{
&InstanceState{
ID: "baz",
},
},
},
"aws_instance.foo.3": &ResourceState{
Type: "aws_instance",
Deposed: []*InstanceState{
&InstanceState{
ID: "qux",
},
},
},
},
},
},
}).SyncWrapper()
n := &NodeRefreshableManagedResource{
NodeAbstractResource: &NodeAbstractResource{
Addr: addrs.RootModuleInstance.Resource(
addrs.ManagedResourceMode, "aws_instance", "foo",
),
Config: m.Module.ManagedResources["aws_instance.foo"],
},
}
g, err := n.DynamicExpand(&MockEvalContext{
PathPath: addrs.RootModuleInstance,
StateState: state,
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 attempting DynamicExpand: %s", err)
}
actual := g.StringWithNodeTypes()
expected := `aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[3] - *terraform.NodeRefreshableManagedResourceInstance
root - terraform.graphNodeRoot
aws_instance.foo[0] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[1] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[2] - *terraform.NodeRefreshableManagedResourceInstance
aws_instance.foo[3] - *terraform.NodeRefreshableManagedResourceInstance
`
if expected != actual {
t.Fatalf("Expected:\n%s\nGot:\n%s", expected, actual)
}
}
func TestNodeRefreshableManagedResourceEvalTree_scaleOut(t *testing.T) {
m := testModule(t, "refresh-resource-scale-inout")
n := &NodeRefreshableManagedResourceInstance{
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
NodeAbstractResource: NodeAbstractResource{
Addr: addrs.RootModuleInstance.Resource(
addrs.ManagedResourceMode, "aws_instance", "foo",
),
Config: m.Module.ManagedResources["aws_instance.foo"],
},
InstanceKey: addrs.IntKey(2),
},
}
actual := n.EvalTree()
expected := n.evalTreeManagedResourceNoState()
if !reflect.DeepEqual(expected, actual) {
t.Fatalf("Expected:\n\n%s\nGot:\n\n%s\n", spew.Sdump(expected), spew.Sdump(actual))
}
}