github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/transform_destroy_cbd_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"regexp"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/muratcelep/terraform/not-internal/addrs"
     9  	"github.com/muratcelep/terraform/not-internal/plans"
    10  	"github.com/muratcelep/terraform/not-internal/states"
    11  )
    12  
    13  func cbdTestGraph(t *testing.T, mod string, changes *plans.Changes, state *states.State) *Graph {
    14  	module := testModule(t, mod)
    15  
    16  	applyBuilder := &ApplyGraphBuilder{
    17  		Config:  module,
    18  		Changes: changes,
    19  		Plugins: simpleMockPluginLibrary(),
    20  		State:   state,
    21  	}
    22  	g, err := (&BasicGraphBuilder{
    23  		Steps: cbdTestSteps(applyBuilder.Steps()),
    24  		Name:  "ApplyGraphBuilder",
    25  	}).Build(addrs.RootModuleInstance)
    26  	if err != nil {
    27  		t.Fatalf("err: %s", err)
    28  	}
    29  
    30  	return filterInstances(g)
    31  }
    32  
    33  // override the apply graph builder to halt the process after CBD
    34  func cbdTestSteps(steps []GraphTransformer) []GraphTransformer {
    35  	found := false
    36  	var i int
    37  	var t GraphTransformer
    38  	for i, t = range steps {
    39  		if _, ok := t.(*CBDEdgeTransformer); ok {
    40  			found = true
    41  			break
    42  		}
    43  	}
    44  
    45  	if !found {
    46  		panic("CBDEdgeTransformer not found")
    47  	}
    48  
    49  	return steps[:i+1]
    50  }
    51  
    52  // remove extra nodes for easier test comparisons
    53  func filterInstances(g *Graph) *Graph {
    54  	for _, v := range g.Vertices() {
    55  		if _, ok := v.(GraphNodeResourceInstance); !ok {
    56  			g.Remove(v)
    57  		}
    58  
    59  	}
    60  	return g
    61  }
    62  
    63  func TestCBDEdgeTransformer(t *testing.T) {
    64  	changes := &plans.Changes{
    65  		Resources: []*plans.ResourceInstanceChangeSrc{
    66  			{
    67  				Addr: mustResourceInstanceAddr("test_object.A"),
    68  				ChangeSrc: plans.ChangeSrc{
    69  					Action: plans.CreateThenDelete,
    70  				},
    71  			},
    72  			{
    73  				Addr: mustResourceInstanceAddr("test_object.B"),
    74  				ChangeSrc: plans.ChangeSrc{
    75  					Action: plans.Update,
    76  				},
    77  			},
    78  		},
    79  	}
    80  
    81  	state := states.NewState()
    82  	root := state.EnsureModule(addrs.RootModuleInstance)
    83  	root.SetResourceInstanceCurrent(
    84  		mustResourceInstanceAddr("test_object.A").Resource,
    85  		&states.ResourceInstanceObjectSrc{
    86  			Status:    states.ObjectReady,
    87  			AttrsJSON: []byte(`{"id":"A"}`),
    88  		},
    89  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
    90  	)
    91  	root.SetResourceInstanceCurrent(
    92  		mustResourceInstanceAddr("test_object.B").Resource,
    93  		&states.ResourceInstanceObjectSrc{
    94  			Status:       states.ObjectReady,
    95  			AttrsJSON:    []byte(`{"id":"B","test_list":["x"]}`),
    96  			Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")},
    97  		},
    98  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
    99  	)
   100  
   101  	g := cbdTestGraph(t, "transform-destroy-cbd-edge-basic", changes, state)
   102  	g = filterInstances(g)
   103  
   104  	actual := strings.TrimSpace(g.String())
   105  	expected := regexp.MustCompile(strings.TrimSpace(`
   106  (?m)test_object.A
   107  test_object.A \(destroy deposed \w+\)
   108    test_object.A
   109    test_object.B
   110  test_object.B
   111    test_object.A
   112  `))
   113  
   114  	if !expected.MatchString(actual) {
   115  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
   116  	}
   117  }
   118  
   119  func TestCBDEdgeTransformerMulti(t *testing.T) {
   120  	changes := &plans.Changes{
   121  		Resources: []*plans.ResourceInstanceChangeSrc{
   122  			{
   123  				Addr: mustResourceInstanceAddr("test_object.A"),
   124  				ChangeSrc: plans.ChangeSrc{
   125  					Action: plans.CreateThenDelete,
   126  				},
   127  			},
   128  			{
   129  				Addr: mustResourceInstanceAddr("test_object.B"),
   130  				ChangeSrc: plans.ChangeSrc{
   131  					Action: plans.CreateThenDelete,
   132  				},
   133  			},
   134  			{
   135  				Addr: mustResourceInstanceAddr("test_object.C"),
   136  				ChangeSrc: plans.ChangeSrc{
   137  					Action: plans.Update,
   138  				},
   139  			},
   140  		},
   141  	}
   142  
   143  	state := states.NewState()
   144  	root := state.EnsureModule(addrs.RootModuleInstance)
   145  	root.SetResourceInstanceCurrent(
   146  		mustResourceInstanceAddr("test_object.A").Resource,
   147  		&states.ResourceInstanceObjectSrc{
   148  			Status:    states.ObjectReady,
   149  			AttrsJSON: []byte(`{"id":"A"}`),
   150  		},
   151  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   152  	)
   153  	root.SetResourceInstanceCurrent(
   154  		mustResourceInstanceAddr("test_object.B").Resource,
   155  		&states.ResourceInstanceObjectSrc{
   156  			Status:    states.ObjectReady,
   157  			AttrsJSON: []byte(`{"id":"B"}`),
   158  		},
   159  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   160  	)
   161  	root.SetResourceInstanceCurrent(
   162  		mustResourceInstanceAddr("test_object.C").Resource,
   163  		&states.ResourceInstanceObjectSrc{
   164  			Status:    states.ObjectReady,
   165  			AttrsJSON: []byte(`{"id":"C","test_list":["x"]}`),
   166  			Dependencies: []addrs.ConfigResource{
   167  				mustConfigResourceAddr("test_object.A"),
   168  				mustConfigResourceAddr("test_object.B"),
   169  			},
   170  		},
   171  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   172  	)
   173  
   174  	g := cbdTestGraph(t, "transform-destroy-cbd-edge-multi", changes, state)
   175  	g = filterInstances(g)
   176  
   177  	actual := strings.TrimSpace(g.String())
   178  	expected := regexp.MustCompile(strings.TrimSpace(`
   179  (?m)test_object.A
   180  test_object.A \(destroy deposed \w+\)
   181    test_object.A
   182    test_object.C
   183  test_object.B
   184  test_object.B \(destroy deposed \w+\)
   185    test_object.B
   186    test_object.C
   187  test_object.C
   188    test_object.A
   189    test_object.B
   190  `))
   191  
   192  	if !expected.MatchString(actual) {
   193  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
   194  	}
   195  }
   196  
   197  func TestCBDEdgeTransformer_depNonCBDCount(t *testing.T) {
   198  	changes := &plans.Changes{
   199  		Resources: []*plans.ResourceInstanceChangeSrc{
   200  			{
   201  				Addr: mustResourceInstanceAddr("test_object.A"),
   202  				ChangeSrc: plans.ChangeSrc{
   203  					Action: plans.CreateThenDelete,
   204  				},
   205  			},
   206  			{
   207  				Addr: mustResourceInstanceAddr("test_object.B[0]"),
   208  				ChangeSrc: plans.ChangeSrc{
   209  					Action: plans.Update,
   210  				},
   211  			},
   212  			{
   213  				Addr: mustResourceInstanceAddr("test_object.B[1]"),
   214  				ChangeSrc: plans.ChangeSrc{
   215  					Action: plans.Update,
   216  				},
   217  			},
   218  		},
   219  	}
   220  
   221  	state := states.NewState()
   222  	root := state.EnsureModule(addrs.RootModuleInstance)
   223  	root.SetResourceInstanceCurrent(
   224  		mustResourceInstanceAddr("test_object.A").Resource,
   225  		&states.ResourceInstanceObjectSrc{
   226  			Status:    states.ObjectReady,
   227  			AttrsJSON: []byte(`{"id":"A"}`),
   228  		},
   229  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   230  	)
   231  	root.SetResourceInstanceCurrent(
   232  		mustResourceInstanceAddr("test_object.B[0]").Resource,
   233  		&states.ResourceInstanceObjectSrc{
   234  			Status:       states.ObjectReady,
   235  			AttrsJSON:    []byte(`{"id":"B","test_list":["x"]}`),
   236  			Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")},
   237  		},
   238  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   239  	)
   240  	root.SetResourceInstanceCurrent(
   241  		mustResourceInstanceAddr("test_object.B[1]").Resource,
   242  		&states.ResourceInstanceObjectSrc{
   243  			Status:       states.ObjectReady,
   244  			AttrsJSON:    []byte(`{"id":"B","test_list":["x"]}`),
   245  			Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")},
   246  		},
   247  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   248  	)
   249  
   250  	g := cbdTestGraph(t, "transform-cbd-destroy-edge-count", changes, state)
   251  
   252  	actual := strings.TrimSpace(g.String())
   253  	expected := regexp.MustCompile(strings.TrimSpace(`
   254  (?m)test_object.A
   255  test_object.A \(destroy deposed \w+\)
   256    test_object.A
   257    test_object.B\[0\]
   258    test_object.B\[1\]
   259  test_object.B\[0\]
   260    test_object.A
   261  test_object.B\[1\]
   262    test_object.A`))
   263  
   264  	if !expected.MatchString(actual) {
   265  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
   266  	}
   267  }
   268  
   269  func TestCBDEdgeTransformer_depNonCBDCountBoth(t *testing.T) {
   270  	changes := &plans.Changes{
   271  		Resources: []*plans.ResourceInstanceChangeSrc{
   272  			{
   273  				Addr: mustResourceInstanceAddr("test_object.A[0]"),
   274  				ChangeSrc: plans.ChangeSrc{
   275  					Action: plans.CreateThenDelete,
   276  				},
   277  			},
   278  			{
   279  				Addr: mustResourceInstanceAddr("test_object.A[1]"),
   280  				ChangeSrc: plans.ChangeSrc{
   281  					Action: plans.CreateThenDelete,
   282  				},
   283  			},
   284  			{
   285  				Addr: mustResourceInstanceAddr("test_object.B[0]"),
   286  				ChangeSrc: plans.ChangeSrc{
   287  					Action: plans.Update,
   288  				},
   289  			},
   290  			{
   291  				Addr: mustResourceInstanceAddr("test_object.B[1]"),
   292  				ChangeSrc: plans.ChangeSrc{
   293  					Action: plans.Update,
   294  				},
   295  			},
   296  		},
   297  	}
   298  
   299  	state := states.NewState()
   300  	root := state.EnsureModule(addrs.RootModuleInstance)
   301  	root.SetResourceInstanceCurrent(
   302  		mustResourceInstanceAddr("test_object.A[0]").Resource,
   303  		&states.ResourceInstanceObjectSrc{
   304  			Status:    states.ObjectReady,
   305  			AttrsJSON: []byte(`{"id":"A"}`),
   306  		},
   307  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   308  	)
   309  	root.SetResourceInstanceCurrent(
   310  		mustResourceInstanceAddr("test_object.A[1]").Resource,
   311  		&states.ResourceInstanceObjectSrc{
   312  			Status:    states.ObjectReady,
   313  			AttrsJSON: []byte(`{"id":"A"}`),
   314  		},
   315  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   316  	)
   317  	root.SetResourceInstanceCurrent(
   318  		mustResourceInstanceAddr("test_object.B[0]").Resource,
   319  		&states.ResourceInstanceObjectSrc{
   320  			Status:       states.ObjectReady,
   321  			AttrsJSON:    []byte(`{"id":"B","test_list":["x"]}`),
   322  			Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")},
   323  		},
   324  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   325  	)
   326  	root.SetResourceInstanceCurrent(
   327  		mustResourceInstanceAddr("test_object.B[1]").Resource,
   328  		&states.ResourceInstanceObjectSrc{
   329  			Status:       states.ObjectReady,
   330  			AttrsJSON:    []byte(`{"id":"B","test_list":["x"]}`),
   331  			Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")},
   332  		},
   333  		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
   334  	)
   335  
   336  	g := cbdTestGraph(t, "transform-cbd-destroy-edge-both-count", changes, state)
   337  
   338  	actual := strings.TrimSpace(g.String())
   339  	expected := regexp.MustCompile(strings.TrimSpace(`
   340  test_object.A\[0\]
   341  test_object.A\[0\] \(destroy deposed \w+\)
   342    test_object.A\[0\]
   343    test_object.B\[0\]
   344    test_object.B\[1\]
   345  test_object.A\[1\]
   346  test_object.A\[1\] \(destroy deposed \w+\)
   347    test_object.A\[1\]
   348    test_object.B\[0\]
   349    test_object.B\[1\]
   350  test_object.B\[0\]
   351    test_object.A\[0\]
   352    test_object.A\[1\]
   353  test_object.B\[1\]
   354    test_object.A\[0\]
   355    test_object.A\[1\]
   356  `))
   357  
   358  	if !expected.MatchString(actual) {
   359  		t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
   360  	}
   361  }