opentofu/terraform/graph_builder_apply_test.go
James Bardin 883f40cdb4 core: fix updated test fixture
The TestApplyGraphBuilder_doubleCBD fixture was updated incorrectly with
a cycle in the desired output. The test matches one the expected string
is fixed.
2018-10-16 18:49:20 -07:00

583 lines
13 KiB
Go

package terraform
import (
"strings"
"testing"
"github.com/hashicorp/terraform/addrs"
)
func TestApplyGraphBuilder_impl(t *testing.T) {
var _ GraphBuilder = new(ApplyGraphBuilder)
}
func TestApplyGraphBuilder(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{
// Verify noop doesn't show up in graph
"test_object.noop": &InstanceDiff{},
"test_object.create": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
"test_object.other": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
&ModuleDiff{
Path: []string{"root", "child"},
Resources: map[string]*InstanceDiff{
"test_object.create": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
"test_object.other": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-basic"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
DisableReduce: true,
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
if g.Path.String() != addrs.RootModuleInstance.String() {
t.Fatalf("wrong path %q", g.Path.String())
}
actual := strings.TrimSpace(g.String())
expected := strings.TrimSpace(testApplyGraphBuilderStr)
if actual != expected {
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
}
}
// This tests the ordering of two resources where a non-CBD depends
// on a CBD. GH-11349.
func TestApplyGraphBuilder_depCbd(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{"test_object.A": &InstanceDiff{Destroy: true,
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
RequiresNew: true,
},
},
},
"test_object.B": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-dep-cbd"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
DisableReduce: true,
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
t.Logf("Graph: %s", g.String())
if g.Path.String() != addrs.RootModuleInstance.String() {
t.Fatalf("wrong path %q", g.Path.String())
}
// Create A, Modify B, Destroy A
testGraphHappensBefore(
t, g,
"test_object.A",
"test_object.A (destroy)")
testGraphHappensBefore(
t, g,
"test_object.A",
"test_object.B")
testGraphHappensBefore(
t, g,
"test_object.B",
"test_object.A (destroy)")
}
// This tests the ordering of two resources that are both CBD that
// require destroy/create.
func TestApplyGraphBuilder_doubleCBD(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{
"test_object.A": &InstanceDiff{
Destroy: true,
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
"test_object.B": &InstanceDiff{
Destroy: true,
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-double-cbd"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
DisableReduce: true,
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
if g.Path.String() != addrs.RootModuleInstance.String() {
t.Fatalf("wrong path %q", g.Path.String())
}
actual := strings.TrimSpace(g.String())
expected := strings.TrimSpace(testApplyGraphBuilderDoubleCBDStr)
if actual != expected {
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
}
}
// This tests the ordering of two resources being destroyed that depend
// on each other from only state. GH-11749
func TestApplyGraphBuilder_destroyStateOnly(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root", "child"},
Resources: map[string]*InstanceDiff{
"test_object.A": &InstanceDiff{
Destroy: true,
},
"test_object.B": &InstanceDiff{
Destroy: true,
},
},
},
},
}
state := &State{
Modules: []*ModuleState{
&ModuleState{
Path: []string{"root", "child"},
Resources: map[string]*ResourceState{
"test_object.A": &ResourceState{
Type: "test_object",
Primary: &InstanceState{
ID: "foo",
Attributes: map[string]string{},
},
},
"test_object.B": &ResourceState{
Type: "test_object",
Primary: &InstanceState{
ID: "bar",
Attributes: map[string]string{},
},
Dependencies: []string{"test_object.A"},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "empty"),
Diff: diff,
State: state,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
DisableReduce: true,
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
t.Logf("Graph: %s", g.String())
if g.Path.String() != addrs.RootModuleInstance.String() {
t.Fatalf("wrong path %q", g.Path.String())
}
testGraphHappensBefore(
t, g,
"module.child.test_object.B (destroy)",
"module.child.test_object.A (destroy)")
}
// This tests the ordering of destroying a single count of a resource.
func TestApplyGraphBuilder_destroyCount(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{
"test_object.A.1": &InstanceDiff{
Destroy: true,
},
"test_object.B": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"name": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-count"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
DisableReduce: true,
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
if g.Path.String() != addrs.RootModuleInstance.String() {
t.Fatalf("wrong module path %q", g.Path)
}
actual := strings.TrimSpace(g.String())
expected := strings.TrimSpace(testApplyGraphBuilderDestroyCountStr)
if actual != expected {
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
}
}
func TestApplyGraphBuilder_moduleDestroy(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root", "A"},
Resources: map[string]*InstanceDiff{
"test_object.foo": &InstanceDiff{
Destroy: true,
},
},
},
&ModuleDiff{
Path: []string{"root", "B"},
Resources: map[string]*InstanceDiff{
"test_object.foo": &InstanceDiff{
Destroy: true,
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-module-destroy"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
testGraphHappensBefore(
t, g,
"module.B.test_object.foo (destroy)",
"module.A.test_object.foo (destroy)",
)
}
func TestApplyGraphBuilder_provisioner(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{
"test_object.foo": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-provisioner"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
testGraphContains(t, g, "provisioner.test")
testGraphHappensBefore(
t, g,
"provisioner.test",
"test_object.foo",
)
}
func TestApplyGraphBuilder_provisionerDestroy(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{
"test_object.foo": &InstanceDiff{
Destroy: true,
},
},
},
},
}
b := &ApplyGraphBuilder{
Destroy: true,
Config: testModule(t, "graph-builder-apply-provisioner"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
testGraphContains(t, g, "provisioner.test")
testGraphHappensBefore(
t, g,
"provisioner.test",
"test_object.foo (destroy)",
)
}
func TestApplyGraphBuilder_targetModule(t *testing.T) {
diff := &Diff{
Modules: []*ModuleDiff{
&ModuleDiff{
Path: []string{"root"},
Resources: map[string]*InstanceDiff{
"test_object.foo": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
&ModuleDiff{
Path: []string{"root", "child2"},
Resources: map[string]*InstanceDiff{
"test_object.foo": &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"test_string": &ResourceAttrDiff{
Old: "",
New: "foo",
},
},
},
},
},
},
}
b := &ApplyGraphBuilder{
Config: testModule(t, "graph-builder-apply-target-module"),
Diff: diff,
Components: simpleMockComponentFactory(),
Schemas: simpleTestSchemas(),
Targets: []addrs.Targetable{
addrs.RootModuleInstance.Child("child2", addrs.NoKey),
},
}
g, err := b.Build(addrs.RootModuleInstance)
if err != nil {
t.Fatalf("err: %s", err)
}
testGraphNotContains(t, g, "module.child1.output.instance_id")
}
const testApplyGraphBuilderStr = `
meta.count-boundary (count boundary fixup)
module.child.provisioner.test
module.child.test_object.create
module.child.test_object.other
provider.test
test_object.create
test_object.other
module.child.provisioner.test
module.child.test_object.create
module.child.provisioner.test
provider.test
module.child.test_object.other
module.child.test_object.create
provider.test
provider.test
provider.test (close)
module.child.test_object.create
module.child.test_object.other
provider.test
test_object.create
test_object.other
provisioner.test (close)
module.child.test_object.create
root
meta.count-boundary (count boundary fixup)
provider.test (close)
provisioner.test (close)
test_object.create
provider.test
test_object.other
provider.test
test_object.create
`
const testApplyGraphBuilderDoubleCBDStr = `
meta.count-boundary (count boundary fixup)
provider.test
test_object.A
test_object.A (destroy)
test_object.B
test_object.B (destroy)
provider.test
provider.test (close)
provider.test
test_object.A
test_object.A (destroy)
test_object.B
test_object.B (destroy)
root
meta.count-boundary (count boundary fixup)
provider.test (close)
test_object.A
provider.test
test_object.A (destroy)
provider.test
test_object.A
test_object.B
test_object.B (destroy)
test_object.B
provider.test
test_object.A
test_object.B (destroy)
provider.test
test_object.B
`
const testApplyGraphBuilderDestroyCountStr = `
meta.count-boundary (count boundary fixup)
provider.test
test_object.A[1] (destroy)
test_object.B
provider.test
provider.test (close)
provider.test
test_object.A[1] (destroy)
test_object.B
root
meta.count-boundary (count boundary fixup)
provider.test (close)
test_object.A[1] (destroy)
provider.test
test_object.B
provider.test
test_object.A[1] (destroy)
`