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 }