core: Pass components through to the destroy transformers
These transformers both construct temporary graphs using many of the same transformers used in the apply graph, and properly doing this now requires access to the providers and provisioners in order to obtain their schemas. Along with this, we also update the tests here to use the simpleMockComponentFactory helper to get a mock provider with a schema already configured, which means we also need to update the test fixtures and assertions to use the resource type and attributes defined in that mock factory.
This commit is contained in:
parent
1a9ee72ecb
commit
bec0f56808
|
@ -291,6 +291,7 @@ func (c *Context) Graph(typ GraphType, opts *ContextGraphOpts) (*Graph, tfdiags.
|
|||
return (&DestroyPlanGraphBuilder{
|
||||
Config: c.config,
|
||||
State: c.state,
|
||||
Components: c.components,
|
||||
Targets: c.targets,
|
||||
Validate: opts.Validate,
|
||||
}).Build(addrs.RootModuleInstance)
|
||||
|
|
|
@ -88,10 +88,18 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
|
|||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
||||
|
||||
// Destruction ordering
|
||||
&DestroyEdgeTransformer{Config: b.Config, State: b.State},
|
||||
&DestroyEdgeTransformer{
|
||||
Config: b.Config,
|
||||
State: b.State,
|
||||
Components: b.Components,
|
||||
},
|
||||
GraphTransformIf(
|
||||
func() bool { return !b.Destroy },
|
||||
&CBDEdgeTransformer{Config: b.Config, State: b.State},
|
||||
&CBDEdgeTransformer{
|
||||
Config: b.Config,
|
||||
State: b.State,
|
||||
Components: b.Components,
|
||||
},
|
||||
),
|
||||
|
||||
// Provisioner-related transformations
|
||||
|
|
|
@ -22,6 +22,10 @@ type DestroyPlanGraphBuilder struct {
|
|||
// Targets are resources to target
|
||||
Targets []addrs.Targetable
|
||||
|
||||
// Components is a factory for the plug-in components (providers and
|
||||
// provisioners) available for use.
|
||||
Components contextComponentFactory
|
||||
|
||||
// Validate will do structural validation of the graph.
|
||||
Validate bool
|
||||
}
|
||||
|
@ -55,7 +59,11 @@ func (b *DestroyPlanGraphBuilder) Steps() []GraphTransformer {
|
|||
|
||||
// Destruction ordering. We require this only so that
|
||||
// targeting below will prune the correct things.
|
||||
&DestroyEdgeTransformer{Config: b.Config, State: b.State},
|
||||
&DestroyEdgeTransformer{
|
||||
Config: b.Config,
|
||||
State: b.State,
|
||||
Components: b.Components,
|
||||
},
|
||||
|
||||
// Target. Note we don't set "Destroy: true" here since we already
|
||||
// created proper destroy ordering.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
resource "test" "A" {}
|
||||
resource "test_object" "A" {}
|
||||
|
||||
resource "test" "B" {
|
||||
value = "${test.A.value}"
|
||||
resource "test_object" "B" {
|
||||
test_string = "${test_object.A.test_string}"
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
resource "aws_instance" "a" {}
|
||||
resource "aws_instance" "b" {
|
||||
value = "${aws_instance.a.id}"
|
||||
resource "test_object" "a" {}
|
||||
|
||||
resource "test_object" "b" {
|
||||
test_string = "${test_object.a.test_string}"
|
||||
}
|
||||
|
||||
resource "aws_instance" "c" {
|
||||
value = "${aws_instance.b.id}"
|
||||
resource "test_object" "c" {
|
||||
test_string = "${test_object.b.test_string}"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
resource "aws_instance" "b" {
|
||||
value = "foo"
|
||||
resource "test_object" "b" {
|
||||
test_string = "foo"
|
||||
}
|
||||
|
||||
output "output" {
|
||||
value = "${aws_instance.b.value}"
|
||||
value = "${test_object.b.test_string}"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
resource "aws_instance" "a" {
|
||||
value = "${module.child.output}"
|
||||
resource "test_object" "a" {
|
||||
test_string = "${module.child.output}"
|
||||
}
|
||||
|
||||
module "child" {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
resource "test" "A" {}
|
||||
resource "test_object" "A" {}
|
||||
|
||||
resource "test" "B" {
|
||||
value = "${test.A.value}"
|
||||
resource "test_object" "B" {
|
||||
test_string = "${test_object.A.test_string}"
|
||||
}
|
||||
|
||||
resource "test" "C" {
|
||||
value = "${test.B.value}"
|
||||
resource "test_object" "C" {
|
||||
test_string = "${test_object.B.test_string}"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
resource "test" "A" {}
|
||||
resource "test" "B" {
|
||||
resource "test_object" "A" {}
|
||||
|
||||
resource "test_object" "B" {
|
||||
count = 2
|
||||
value = "${test.A.*.value}"
|
||||
test_string = "${test_object.A.*.test_string}"
|
||||
}
|
||||
|
|
|
@ -40,11 +40,14 @@ type CBDEdgeTransformer struct {
|
|||
// any way possible. Either can be nil if not availabile.
|
||||
Config *configs.Config
|
||||
State *State
|
||||
|
||||
// If configuration is present then Components is required in order to
|
||||
// obtain schema information from providers and provisioners in order
|
||||
// to properly resolve implicit dependencies.
|
||||
Components contextComponentFactory
|
||||
}
|
||||
|
||||
func (t *CBDEdgeTransformer) Transform(g *Graph) error {
|
||||
log.Printf("[TRACE] CBDEdgeTransformer: Beginning CBD transformation...")
|
||||
|
||||
// Go through and reverse any destroy edges
|
||||
destroyMap := make(map[string][]dag.Vertex)
|
||||
for _, v := range g.Vertices() {
|
||||
|
@ -64,6 +67,7 @@ func (t *CBDEdgeTransformer) Transform(g *Graph) error {
|
|||
// and we need to auto-upgrade this node to CBD. We do this because
|
||||
// a CBD node depending on non-CBD will result in cycles. To avoid this,
|
||||
// we always attempt to upgrade it.
|
||||
log.Printf("[TRACE] CBDEdgeTransformer: forcing create_before_destroy on for %q (%T)", dag.VertexName(v), v)
|
||||
if err := dn.ModifyCreateBeforeDestroy(true); err != nil {
|
||||
return fmt.Errorf(
|
||||
"%s: must have create before destroy enabled because "+
|
||||
|
@ -174,6 +178,7 @@ func (t *CBDEdgeTransformer) depMap(destroyMap map[string][]dag.Vertex) (map[str
|
|||
&FlatConfigTransformer{Config: t.Config},
|
||||
&AttachResourceConfigTransformer{Config: t.Config},
|
||||
&AttachStateTransformer{State: t.State},
|
||||
&AttachSchemaTransformer{Components: t.Components},
|
||||
&ReferenceTransformer{},
|
||||
},
|
||||
Name: "CBDEdgeTransformer",
|
||||
|
|
|
@ -9,15 +9,16 @@ import (
|
|||
|
||||
func TestCBDEdgeTransformer(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A", CBD: true})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A", CBD: true})
|
||||
|
||||
module := testModule(t, "transform-destroy-edge-basic")
|
||||
|
||||
{
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -25,7 +26,10 @@ func TestCBDEdgeTransformer(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
tf := &CBDEdgeTransformer{Config: module}
|
||||
tf := &CBDEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
@ -34,22 +38,23 @@ func TestCBDEdgeTransformer(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformCBDEdgeBasicStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCBDEdgeTransformer_depNonCBD(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.B", CBD: true})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.B", CBD: true})
|
||||
|
||||
module := testModule(t, "transform-destroy-edge-basic")
|
||||
|
||||
{
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -57,7 +62,10 @@ func TestCBDEdgeTransformer_depNonCBD(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
tf := &CBDEdgeTransformer{Config: module}
|
||||
tf := &CBDEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
@ -66,22 +74,23 @@ func TestCBDEdgeTransformer_depNonCBD(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformCBDEdgeDepNonCBDStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCBDEdgeTransformer_depNonCBDCount(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.B[0]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.B[1]"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A", CBD: true})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.B[0]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.B[1]"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A", CBD: true})
|
||||
|
||||
module := testModule(t, "transform-destroy-edge-splat")
|
||||
|
||||
{
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -89,7 +98,10 @@ func TestCBDEdgeTransformer_depNonCBDCount(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
tf := &CBDEdgeTransformer{Config: module}
|
||||
tf := &CBDEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
@ -97,33 +109,34 @@ func TestCBDEdgeTransformer_depNonCBDCount(t *testing.T) {
|
|||
|
||||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(`
|
||||
test.A
|
||||
test.A (destroy)
|
||||
test.A
|
||||
test.B[0]
|
||||
test.B[1]
|
||||
test.B[0]
|
||||
test.B[1]
|
||||
test_object.A
|
||||
test_object.A (destroy)
|
||||
test_object.A
|
||||
test_object.B[0]
|
||||
test_object.B[1]
|
||||
test_object.B[0]
|
||||
test_object.B[1]
|
||||
`)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCBDEdgeTransformer_depNonCBDCountBoth(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.A[0]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.A[1]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.B[0]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.B[1]"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A[0]", CBD: true})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A[1]", CBD: true})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.A[0]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.A[1]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.B[0]"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.B[1]"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A[0]", CBD: true})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A[1]", CBD: true})
|
||||
|
||||
module := testModule(t, "transform-destroy-edge-splat")
|
||||
|
||||
{
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -131,7 +144,10 @@ func TestCBDEdgeTransformer_depNonCBDCountBoth(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
tf := &CBDEdgeTransformer{Config: module}
|
||||
tf := &CBDEdgeTransformer{
|
||||
Config: module,
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
@ -139,39 +155,39 @@ func TestCBDEdgeTransformer_depNonCBDCountBoth(t *testing.T) {
|
|||
|
||||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(`
|
||||
test.A[0]
|
||||
test.A[0] (destroy)
|
||||
test.A[0]
|
||||
test.B[0]
|
||||
test.B[1]
|
||||
test.A[1]
|
||||
test.A[1] (destroy)
|
||||
test.A[1]
|
||||
test.B[0]
|
||||
test.B[1]
|
||||
test.B[0]
|
||||
test.B[1]
|
||||
test_object.A[0]
|
||||
test_object.A[0] (destroy)
|
||||
test_object.A[0]
|
||||
test_object.B[0]
|
||||
test_object.B[1]
|
||||
test_object.A[1]
|
||||
test_object.A[1] (destroy)
|
||||
test_object.A[1]
|
||||
test_object.B[0]
|
||||
test_object.B[1]
|
||||
test_object.B[0]
|
||||
test_object.B[1]
|
||||
`)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
const testTransformCBDEdgeBasicStr = `
|
||||
test.A
|
||||
test.A (destroy)
|
||||
test.A
|
||||
test.B
|
||||
test.B
|
||||
test_object.A
|
||||
test_object.A (destroy)
|
||||
test_object.A
|
||||
test_object.B
|
||||
test_object.B
|
||||
`
|
||||
|
||||
const testTransformCBDEdgeDepNonCBDStr = `
|
||||
test.A
|
||||
test.A (destroy) (modified)
|
||||
test.A
|
||||
test.B
|
||||
test.B (destroy)
|
||||
test.B
|
||||
test.B (destroy)
|
||||
test.B
|
||||
test_object.A
|
||||
test_object.A (destroy) (modified)
|
||||
test_object.A
|
||||
test_object.B
|
||||
test_object.B (destroy)
|
||||
test_object.B
|
||||
test_object.B (destroy)
|
||||
test_object.B
|
||||
`
|
||||
|
|
|
@ -44,11 +44,14 @@ type DestroyEdgeTransformer struct {
|
|||
// to determine what a destroy node depends on. Any of these can be nil.
|
||||
Config *configs.Config
|
||||
State *State
|
||||
|
||||
// If configuration is present then Components is required in order to
|
||||
// obtain schema information from providers and provisioners in order
|
||||
// to properly resolve implicit dependencies.
|
||||
Components contextComponentFactory
|
||||
}
|
||||
|
||||
func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: Beginning destroy edge transformation...")
|
||||
|
||||
// Build a map of what is being destroyed (by address string) to
|
||||
// the list of destroyers. In general there will only be one destroyer
|
||||
// but to make it more robust we support multiple.
|
||||
|
@ -67,7 +70,7 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
|||
addr := *addrP
|
||||
|
||||
key := addr.String()
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: %s will destroy %s", dag.VertexName(dn), key)
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: %q (%T) destroys %s", dag.VertexName(dn), v, key)
|
||||
destroyers[key] = append(destroyers[key], dn)
|
||||
destroyerAddrs[key] = addr
|
||||
}
|
||||
|
@ -103,7 +106,7 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
|||
a := v
|
||||
|
||||
log.Printf(
|
||||
"[TRACE] DestroyEdgeTransformer: connecting creator/destroyer: %s, %s",
|
||||
"[TRACE] DestroyEdgeTransformer: connecting creator %q with destroyer %q",
|
||||
dag.VertexName(a), dag.VertexName(a_d))
|
||||
|
||||
g.Connect(&DestroyEdge{S: a, T: a_d})
|
||||
|
@ -138,6 +141,10 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
|||
&RootVariableTransformer{Config: t.Config},
|
||||
&ModuleVariableTransformer{Config: t.Config},
|
||||
|
||||
// Must be before ReferenceTransformer, since schema is required to
|
||||
// extract references from config.
|
||||
&AttachSchemaTransformer{Components: t.Components},
|
||||
|
||||
&ReferenceTransformer{},
|
||||
}
|
||||
|
||||
|
@ -157,12 +164,7 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
|||
// This part is a little bit weird but is the best way to
|
||||
// find the dependencies we need to: build a graph and use the
|
||||
// attach config and state transformers then ask for references.
|
||||
abstract := &NodeAbstractResourceInstance{
|
||||
NodeAbstractResource: NodeAbstractResource{
|
||||
Addr: addr.ContainingResource(),
|
||||
},
|
||||
InstanceKey: addr.Resource.Key,
|
||||
}
|
||||
abstract := NewNodeAbstractResourceInstance(addr)
|
||||
tempG.Add(abstract)
|
||||
tempDestroyed = append(tempDestroyed, abstract)
|
||||
|
||||
|
@ -175,13 +177,15 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
|||
|
||||
// Run the graph transforms so we have the information we need to
|
||||
// build references.
|
||||
log.Println("[TRACE] DestroyEdgeTransformer: constructing temporary graph for analysis of references")
|
||||
for _, s := range steps {
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: running %T on temporary graph", s)
|
||||
if err := s.Transform(&tempG); err != nil {
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: %T failed: %s", s, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: reference graph: %s", tempG.String())
|
||||
log.Printf("[TRACE] DestroyEdgeTransformer: temporary reference graph: %s", tempG.String())
|
||||
|
||||
// Go through all the nodes in the graph and determine what they
|
||||
// depend on.
|
||||
|
|
|
@ -9,10 +9,11 @@ import (
|
|||
|
||||
func TestDestroyEdgeTransformer_basic(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.B"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: testModule(t, "transform-destroy-edge-basic"),
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -21,17 +22,18 @@ func TestDestroyEdgeTransformer_basic(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformDestroyEdgeBasicStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestroyEdgeTransformer_create(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.B"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.B"})
|
||||
g.Add(&graphNodeCreatorTest{AddrString: "test_object.A"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: testModule(t, "transform-destroy-edge-basic"),
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -40,17 +42,18 @@ func TestDestroyEdgeTransformer_create(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformDestroyEdgeCreatorStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestroyEdgeTransformer_multi(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.C"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.B"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.C"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: testModule(t, "transform-destroy-edge-multi"),
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -59,15 +62,16 @@ func TestDestroyEdgeTransformer_multi(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformDestroyEdgeMultiStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestroyEdgeTransformer_selfRef(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test.A"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.A"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: testModule(t, "transform-destroy-edge-self-ref"),
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -76,16 +80,17 @@ func TestDestroyEdgeTransformer_selfRef(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformDestroyEdgeSelfRefStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestroyEdgeTransformer_module(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.aws_instance.b"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "aws_instance.a"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.test_object.b"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "test_object.a"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: testModule(t, "transform-destroy-edge-module"),
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -94,17 +99,18 @@ func TestDestroyEdgeTransformer_module(t *testing.T) {
|
|||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(testTransformDestroyEdgeModuleStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDestroyEdgeTransformer_moduleOnly(t *testing.T) {
|
||||
g := Graph{Path: addrs.RootModuleInstance}
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.aws_instance.a"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.aws_instance.b"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.aws_instance.c"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.test_object.a"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.test_object.b"})
|
||||
g.Add(&graphNodeDestroyerTest{AddrString: "module.child.test_object.c"})
|
||||
tf := &DestroyEdgeTransformer{
|
||||
Config: testModule(t, "transform-destroy-edge-module-only"),
|
||||
Components: simpleMockComponentFactory(),
|
||||
}
|
||||
if err := tf.Transform(&g); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -112,15 +118,15 @@ func TestDestroyEdgeTransformer_moduleOnly(t *testing.T) {
|
|||
|
||||
actual := strings.TrimSpace(g.String())
|
||||
expected := strings.TrimSpace(`
|
||||
module.child.aws_instance.a (destroy)
|
||||
module.child.aws_instance.b (destroy)
|
||||
module.child.aws_instance.c (destroy)
|
||||
module.child.aws_instance.b (destroy)
|
||||
module.child.aws_instance.c (destroy)
|
||||
module.child.aws_instance.c (destroy)
|
||||
module.child.test_object.a (destroy)
|
||||
module.child.test_object.b (destroy)
|
||||
module.child.test_object.c (destroy)
|
||||
module.child.test_object.b (destroy)
|
||||
module.child.test_object.c (destroy)
|
||||
module.child.test_object.c (destroy)
|
||||
`)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad:\n\n%s", actual)
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,17 +135,43 @@ type graphNodeCreatorTest struct {
|
|||
Refs []string
|
||||
}
|
||||
|
||||
func (n *graphNodeCreatorTest) Name() string { return n.CreateAddr().String() }
|
||||
func (n *graphNodeCreatorTest) CreateAddr() *ResourceAddress {
|
||||
addr, err := ParseResourceAddress(n.AddrString)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var (
|
||||
_ GraphNodeCreator = (*graphNodeCreatorTest)(nil)
|
||||
_ GraphNodeReferencer = (*graphNodeCreatorTest)(nil)
|
||||
)
|
||||
|
||||
func (n *graphNodeCreatorTest) Name() string {
|
||||
return n.CreateAddr().String()
|
||||
}
|
||||
|
||||
func (n *graphNodeCreatorTest) mustAddr() addrs.AbsResourceInstance {
|
||||
addr, diags := addrs.ParseAbsResourceInstanceStr(n.AddrString)
|
||||
if diags.HasErrors() {
|
||||
panic(diags.Err())
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func (n *graphNodeCreatorTest) References() []string { return n.Refs }
|
||||
func (n *graphNodeCreatorTest) Path() addrs.ModuleInstance {
|
||||
return n.mustAddr().Module
|
||||
}
|
||||
|
||||
func (n *graphNodeCreatorTest) CreateAddr() *addrs.AbsResourceInstance {
|
||||
addr := n.mustAddr()
|
||||
return &addr
|
||||
}
|
||||
|
||||
func (n *graphNodeCreatorTest) References() []*addrs.Reference {
|
||||
ret := make([]*addrs.Reference, len(n.Refs))
|
||||
for i, str := range n.Refs {
|
||||
ref, diags := addrs.ParseRefStr(str)
|
||||
if diags.HasErrors() {
|
||||
panic(diags.Err())
|
||||
}
|
||||
ret[i] = ref
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type graphNodeDestroyerTest struct {
|
||||
AddrString string
|
||||
|
@ -147,6 +179,8 @@ type graphNodeDestroyerTest struct {
|
|||
Modified bool
|
||||
}
|
||||
|
||||
var _ GraphNodeDestroyer = (*graphNodeDestroyerTest)(nil)
|
||||
|
||||
func (n *graphNodeDestroyerTest) Name() string {
|
||||
result := n.DestroyAddr().String() + " (destroy)"
|
||||
if n.Modified {
|
||||
|
@ -156,51 +190,57 @@ func (n *graphNodeDestroyerTest) Name() string {
|
|||
return result
|
||||
}
|
||||
|
||||
func (n *graphNodeDestroyerTest) CreateBeforeDestroy() bool { return n.CBD }
|
||||
func (n *graphNodeDestroyerTest) mustAddr() addrs.AbsResourceInstance {
|
||||
addr, diags := addrs.ParseAbsResourceInstanceStr(n.AddrString)
|
||||
if diags.HasErrors() {
|
||||
panic(diags.Err())
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func (n *graphNodeDestroyerTest) CreateBeforeDestroy() bool {
|
||||
return n.CBD
|
||||
}
|
||||
|
||||
func (n *graphNodeDestroyerTest) ModifyCreateBeforeDestroy(v bool) error {
|
||||
n.Modified = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *graphNodeDestroyerTest) DestroyAddr() *ResourceAddress {
|
||||
addr, err := ParseResourceAddress(n.AddrString)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return addr
|
||||
func (n *graphNodeDestroyerTest) DestroyAddr() *addrs.AbsResourceInstance {
|
||||
addr := n.mustAddr()
|
||||
return &addr
|
||||
}
|
||||
|
||||
const testTransformDestroyEdgeBasicStr = `
|
||||
test.A (destroy)
|
||||
test.B (destroy)
|
||||
test.B (destroy)
|
||||
test_object.A (destroy)
|
||||
test_object.B (destroy)
|
||||
test_object.B (destroy)
|
||||
`
|
||||
|
||||
const testTransformDestroyEdgeCreatorStr = `
|
||||
test.A
|
||||
test.A (destroy)
|
||||
test.A (destroy)
|
||||
test.B (destroy)
|
||||
test.B (destroy)
|
||||
test_object.A
|
||||
test_object.A (destroy)
|
||||
test_object.A (destroy)
|
||||
test_object.B (destroy)
|
||||
test_object.B (destroy)
|
||||
`
|
||||
|
||||
const testTransformDestroyEdgeMultiStr = `
|
||||
test.A (destroy)
|
||||
test.B (destroy)
|
||||
test.C (destroy)
|
||||
test.B (destroy)
|
||||
test.C (destroy)
|
||||
test.C (destroy)
|
||||
test_object.A (destroy)
|
||||
test_object.B (destroy)
|
||||
test_object.C (destroy)
|
||||
test_object.B (destroy)
|
||||
test_object.C (destroy)
|
||||
test_object.C (destroy)
|
||||
`
|
||||
|
||||
const testTransformDestroyEdgeSelfRefStr = `
|
||||
test.A (destroy)
|
||||
test_object.A (destroy)
|
||||
`
|
||||
|
||||
const testTransformDestroyEdgeModuleStr = `
|
||||
aws_instance.a (destroy)
|
||||
module.child.aws_instance.b (destroy)
|
||||
aws_instance.a (destroy)
|
||||
module.child.test_object.b (destroy)
|
||||
test_object.a (destroy)
|
||||
test_object.a (destroy)
|
||||
`
|
||||
|
|
Loading…
Reference in New Issue