github.com/jaredpalmer/terraform@v1.1.0-alpha20210908.0.20210911170307-88705c943a03/internal/terraform/graph_builder_apply_test.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/terraform/internal/addrs" 9 "github.com/hashicorp/terraform/internal/plans" 10 "github.com/hashicorp/terraform/internal/states" 11 "github.com/zclconf/go-cty/cty" 12 ) 13 14 func TestApplyGraphBuilder_impl(t *testing.T) { 15 var _ GraphBuilder = new(ApplyGraphBuilder) 16 } 17 18 func TestApplyGraphBuilder(t *testing.T) { 19 changes := &plans.Changes{ 20 Resources: []*plans.ResourceInstanceChangeSrc{ 21 { 22 Addr: mustResourceInstanceAddr("test_object.create"), 23 ChangeSrc: plans.ChangeSrc{ 24 Action: plans.Create, 25 }, 26 }, 27 { 28 Addr: mustResourceInstanceAddr("test_object.other"), 29 ChangeSrc: plans.ChangeSrc{ 30 Action: plans.Update, 31 }, 32 }, 33 { 34 Addr: mustResourceInstanceAddr("module.child.test_object.create"), 35 ChangeSrc: plans.ChangeSrc{ 36 Action: plans.Create, 37 }, 38 }, 39 { 40 Addr: mustResourceInstanceAddr("module.child.test_object.other"), 41 ChangeSrc: plans.ChangeSrc{ 42 Action: plans.Create, 43 }, 44 }, 45 }, 46 } 47 48 b := &ApplyGraphBuilder{ 49 Config: testModule(t, "graph-builder-apply-basic"), 50 Changes: changes, 51 Plugins: simpleMockPluginLibrary(), 52 } 53 54 g, err := b.Build(addrs.RootModuleInstance) 55 if err != nil { 56 t.Fatalf("err: %s", err) 57 } 58 59 if g.Path.String() != addrs.RootModuleInstance.String() { 60 t.Fatalf("wrong path %q", g.Path.String()) 61 } 62 63 actual := strings.TrimSpace(g.String()) 64 65 expected := strings.TrimSpace(testApplyGraphBuilderStr) 66 if actual != expected { 67 t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) 68 } 69 } 70 71 // This tests the ordering of two resources where a non-CBD depends 72 // on a CBD. GH-11349. 73 func TestApplyGraphBuilder_depCbd(t *testing.T) { 74 changes := &plans.Changes{ 75 Resources: []*plans.ResourceInstanceChangeSrc{ 76 { 77 Addr: mustResourceInstanceAddr("test_object.A"), 78 ChangeSrc: plans.ChangeSrc{ 79 Action: plans.CreateThenDelete, 80 }, 81 }, 82 { 83 Addr: mustResourceInstanceAddr("test_object.B"), 84 ChangeSrc: plans.ChangeSrc{ 85 Action: plans.Update, 86 }, 87 }, 88 }, 89 } 90 91 state := states.NewState() 92 root := state.EnsureModule(addrs.RootModuleInstance) 93 root.SetResourceInstanceCurrent( 94 mustResourceInstanceAddr("test_object.A").Resource, 95 &states.ResourceInstanceObjectSrc{ 96 Status: states.ObjectReady, 97 AttrsJSON: []byte(`{"id":"A"}`), 98 }, 99 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 100 ) 101 root.SetResourceInstanceCurrent( 102 mustResourceInstanceAddr("test_object.B").Resource, 103 &states.ResourceInstanceObjectSrc{ 104 Status: states.ObjectReady, 105 AttrsJSON: []byte(`{"id":"B","test_list":["x"]}`), 106 Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("test_object.A")}, 107 }, 108 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 109 ) 110 111 b := &ApplyGraphBuilder{ 112 Config: testModule(t, "graph-builder-apply-dep-cbd"), 113 Changes: changes, 114 Plugins: simpleMockPluginLibrary(), 115 State: state, 116 } 117 118 g, err := b.Build(addrs.RootModuleInstance) 119 if err != nil { 120 t.Fatalf("err: %s", err) 121 } 122 123 if g.Path.String() != addrs.RootModuleInstance.String() { 124 t.Fatalf("wrong path %q", g.Path.String()) 125 } 126 127 // We're going to go hunting for our deposed instance node here, so we 128 // can find out its key to use in the assertions below. 129 var dk states.DeposedKey 130 for _, v := range g.Vertices() { 131 tv, ok := v.(*NodeDestroyDeposedResourceInstanceObject) 132 if !ok { 133 continue 134 } 135 if dk != states.NotDeposed { 136 t.Fatalf("more than one deposed instance node in the graph; want only one") 137 } 138 dk = tv.DeposedKey 139 } 140 if dk == states.NotDeposed { 141 t.Fatalf("no deposed instance node in the graph; want one") 142 } 143 144 destroyName := fmt.Sprintf("test_object.A (destroy deposed %s)", dk) 145 146 // Create A, Modify B, Destroy A 147 testGraphHappensBefore( 148 t, g, 149 "test_object.A", 150 destroyName, 151 ) 152 testGraphHappensBefore( 153 t, g, 154 "test_object.A", 155 "test_object.B", 156 ) 157 testGraphHappensBefore( 158 t, g, 159 "test_object.B", 160 destroyName, 161 ) 162 } 163 164 // This tests the ordering of two resources that are both CBD that 165 // require destroy/create. 166 func TestApplyGraphBuilder_doubleCBD(t *testing.T) { 167 changes := &plans.Changes{ 168 Resources: []*plans.ResourceInstanceChangeSrc{ 169 { 170 Addr: mustResourceInstanceAddr("test_object.A"), 171 ChangeSrc: plans.ChangeSrc{ 172 Action: plans.CreateThenDelete, 173 }, 174 }, 175 { 176 Addr: mustResourceInstanceAddr("test_object.B"), 177 ChangeSrc: plans.ChangeSrc{ 178 Action: plans.CreateThenDelete, 179 }, 180 }, 181 }, 182 } 183 184 b := &ApplyGraphBuilder{ 185 Config: testModule(t, "graph-builder-apply-double-cbd"), 186 Changes: changes, 187 Plugins: simpleMockPluginLibrary(), 188 } 189 190 g, err := b.Build(addrs.RootModuleInstance) 191 if err != nil { 192 t.Fatalf("err: %s", err) 193 } 194 195 if g.Path.String() != addrs.RootModuleInstance.String() { 196 t.Fatalf("wrong path %q", g.Path.String()) 197 } 198 199 // We're going to go hunting for our deposed instance node here, so we 200 // can find out its key to use in the assertions below. 201 var destroyA, destroyB string 202 for _, v := range g.Vertices() { 203 tv, ok := v.(*NodeDestroyDeposedResourceInstanceObject) 204 if !ok { 205 continue 206 } 207 208 switch tv.Addr.Resource.Resource.Name { 209 case "A": 210 destroyA = fmt.Sprintf("test_object.A (destroy deposed %s)", tv.DeposedKey) 211 case "B": 212 destroyB = fmt.Sprintf("test_object.B (destroy deposed %s)", tv.DeposedKey) 213 default: 214 t.Fatalf("unknown instance: %s", tv.Addr) 215 } 216 } 217 218 // Create A, Modify B, Destroy A 219 testGraphHappensBefore( 220 t, g, 221 "test_object.A", 222 destroyA, 223 ) 224 testGraphHappensBefore( 225 t, g, 226 "test_object.A", 227 "test_object.B", 228 ) 229 testGraphHappensBefore( 230 t, g, 231 "test_object.B", 232 destroyB, 233 ) 234 } 235 236 // This tests the ordering of two resources being destroyed that depend 237 // on each other from only state. GH-11749 238 func TestApplyGraphBuilder_destroyStateOnly(t *testing.T) { 239 changes := &plans.Changes{ 240 Resources: []*plans.ResourceInstanceChangeSrc{ 241 { 242 Addr: mustResourceInstanceAddr("module.child.test_object.A"), 243 ChangeSrc: plans.ChangeSrc{ 244 Action: plans.Delete, 245 }, 246 }, 247 { 248 Addr: mustResourceInstanceAddr("module.child.test_object.B"), 249 ChangeSrc: plans.ChangeSrc{ 250 Action: plans.Delete, 251 }, 252 }, 253 }, 254 } 255 256 state := states.NewState() 257 root := state.EnsureModule(addrs.RootModuleInstance) 258 child := state.EnsureModule(addrs.RootModuleInstance.Child("child", addrs.NoKey)) 259 root.SetResourceInstanceCurrent( 260 mustResourceInstanceAddr("test_object.A").Resource, 261 &states.ResourceInstanceObjectSrc{ 262 Status: states.ObjectReady, 263 AttrsJSON: []byte(`{"id":"foo"}`), 264 }, 265 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 266 ) 267 child.SetResourceInstanceCurrent( 268 mustResourceInstanceAddr("test_object.B").Resource, 269 &states.ResourceInstanceObjectSrc{ 270 Status: states.ObjectReady, 271 AttrsJSON: []byte(`{"id":"bar"}`), 272 Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("module.child.test_object.A")}, 273 }, 274 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 275 ) 276 277 b := &ApplyGraphBuilder{ 278 Config: testModule(t, "empty"), 279 Changes: changes, 280 State: state, 281 Plugins: simpleMockPluginLibrary(), 282 } 283 284 g, diags := b.Build(addrs.RootModuleInstance) 285 if diags.HasErrors() { 286 t.Fatalf("err: %s", diags.Err()) 287 } 288 289 if g.Path.String() != addrs.RootModuleInstance.String() { 290 t.Fatalf("wrong path %q", g.Path.String()) 291 } 292 293 testGraphHappensBefore( 294 t, g, 295 "module.child.test_object.B (destroy)", 296 "module.child.test_object.A (destroy)") 297 } 298 299 // This tests the ordering of destroying a single count of a resource. 300 func TestApplyGraphBuilder_destroyCount(t *testing.T) { 301 changes := &plans.Changes{ 302 Resources: []*plans.ResourceInstanceChangeSrc{ 303 { 304 Addr: mustResourceInstanceAddr("test_object.A[1]"), 305 ChangeSrc: plans.ChangeSrc{ 306 Action: plans.Delete, 307 }, 308 }, 309 { 310 Addr: mustResourceInstanceAddr("test_object.B"), 311 ChangeSrc: plans.ChangeSrc{ 312 Action: plans.Update, 313 }, 314 }, 315 }, 316 } 317 318 state := states.NewState() 319 root := state.RootModule() 320 addrA := mustResourceInstanceAddr("test_object.A[1]") 321 root.SetResourceInstanceCurrent( 322 addrA.Resource, 323 &states.ResourceInstanceObjectSrc{ 324 Status: states.ObjectReady, 325 AttrsJSON: []byte(`{"id":"B"}`), 326 }, 327 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 328 ) 329 root.SetResourceInstanceCurrent( 330 mustResourceInstanceAddr("test_object.B").Resource, 331 &states.ResourceInstanceObjectSrc{ 332 Status: states.ObjectReady, 333 AttrsJSON: []byte(`{"id":"B"}`), 334 Dependencies: []addrs.ConfigResource{addrA.ContainingResource().Config()}, 335 }, 336 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 337 ) 338 339 b := &ApplyGraphBuilder{ 340 Config: testModule(t, "graph-builder-apply-count"), 341 Changes: changes, 342 Plugins: simpleMockPluginLibrary(), 343 State: state, 344 } 345 346 g, err := b.Build(addrs.RootModuleInstance) 347 if err != nil { 348 t.Fatalf("err: %s", err) 349 } 350 351 if g.Path.String() != addrs.RootModuleInstance.String() { 352 t.Fatalf("wrong module path %q", g.Path) 353 } 354 355 actual := strings.TrimSpace(g.String()) 356 expected := strings.TrimSpace(testApplyGraphBuilderDestroyCountStr) 357 if actual != expected { 358 t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) 359 } 360 } 361 362 func TestApplyGraphBuilder_moduleDestroy(t *testing.T) { 363 changes := &plans.Changes{ 364 Resources: []*plans.ResourceInstanceChangeSrc{ 365 { 366 Addr: mustResourceInstanceAddr("module.A.test_object.foo"), 367 ChangeSrc: plans.ChangeSrc{ 368 Action: plans.Delete, 369 }, 370 }, 371 { 372 Addr: mustResourceInstanceAddr("module.B.test_object.foo"), 373 ChangeSrc: plans.ChangeSrc{ 374 Action: plans.Delete, 375 }, 376 }, 377 }, 378 } 379 380 state := states.NewState() 381 modA := state.EnsureModule(addrs.RootModuleInstance.Child("A", addrs.NoKey)) 382 modA.SetResourceInstanceCurrent( 383 mustResourceInstanceAddr("test_object.foo").Resource, 384 &states.ResourceInstanceObjectSrc{ 385 Status: states.ObjectReady, 386 AttrsJSON: []byte(`{"id":"foo"}`), 387 }, 388 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 389 ) 390 modB := state.EnsureModule(addrs.RootModuleInstance.Child("B", addrs.NoKey)) 391 modB.SetResourceInstanceCurrent( 392 mustResourceInstanceAddr("test_object.foo").Resource, 393 &states.ResourceInstanceObjectSrc{ 394 Status: states.ObjectReady, 395 AttrsJSON: []byte(`{"id":"foo","value":"foo"}`), 396 Dependencies: []addrs.ConfigResource{mustConfigResourceAddr("module.A.test_object.foo")}, 397 }, 398 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 399 ) 400 401 b := &ApplyGraphBuilder{ 402 Config: testModule(t, "graph-builder-apply-module-destroy"), 403 Changes: changes, 404 Plugins: simpleMockPluginLibrary(), 405 State: state, 406 } 407 408 g, err := b.Build(addrs.RootModuleInstance) 409 if err != nil { 410 t.Fatalf("err: %s", err) 411 } 412 413 testGraphHappensBefore( 414 t, g, 415 "module.B.test_object.foo (destroy)", 416 "module.A.test_object.foo (destroy)", 417 ) 418 } 419 420 func TestApplyGraphBuilder_targetModule(t *testing.T) { 421 changes := &plans.Changes{ 422 Resources: []*plans.ResourceInstanceChangeSrc{ 423 { 424 Addr: mustResourceInstanceAddr("test_object.foo"), 425 ChangeSrc: plans.ChangeSrc{ 426 Action: plans.Update, 427 }, 428 }, 429 { 430 Addr: mustResourceInstanceAddr("module.child2.test_object.foo"), 431 ChangeSrc: plans.ChangeSrc{ 432 Action: plans.Update, 433 }, 434 }, 435 }, 436 } 437 438 b := &ApplyGraphBuilder{ 439 Config: testModule(t, "graph-builder-apply-target-module"), 440 Changes: changes, 441 Plugins: simpleMockPluginLibrary(), 442 Targets: []addrs.Targetable{ 443 addrs.RootModuleInstance.Child("child2", addrs.NoKey), 444 }, 445 } 446 447 g, err := b.Build(addrs.RootModuleInstance) 448 if err != nil { 449 t.Fatalf("err: %s", err) 450 } 451 452 testGraphNotContains(t, g, "module.child1.output.instance_id") 453 } 454 455 // Ensure that an update resulting from the removal of a resource happens after 456 // that resource is destroyed. 457 func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) { 458 schemas := simpleTestSchemas() 459 instanceSchema := schemas.Providers[addrs.NewDefaultProvider("test")].ResourceTypes["test_object"] 460 461 bBefore, _ := plans.NewDynamicValue( 462 cty.ObjectVal(map[string]cty.Value{ 463 "id": cty.StringVal("b_id"), 464 "test_string": cty.StringVal("a_id"), 465 }), instanceSchema.ImpliedType()) 466 bAfter, _ := plans.NewDynamicValue( 467 cty.ObjectVal(map[string]cty.Value{ 468 "id": cty.StringVal("b_id"), 469 "test_string": cty.StringVal("changed"), 470 }), instanceSchema.ImpliedType()) 471 472 changes := &plans.Changes{ 473 Resources: []*plans.ResourceInstanceChangeSrc{ 474 { 475 Addr: mustResourceInstanceAddr("test_object.a"), 476 ChangeSrc: plans.ChangeSrc{ 477 Action: plans.Delete, 478 }, 479 }, 480 { 481 Addr: mustResourceInstanceAddr("test_object.b"), 482 ChangeSrc: plans.ChangeSrc{ 483 Action: plans.Update, 484 Before: bBefore, 485 After: bAfter, 486 }, 487 }, 488 }, 489 } 490 491 state := states.NewState() 492 root := state.EnsureModule(addrs.RootModuleInstance) 493 root.SetResourceInstanceCurrent( 494 addrs.Resource{ 495 Mode: addrs.ManagedResourceMode, 496 Type: "test_object", 497 Name: "a", 498 }.Instance(addrs.NoKey), 499 &states.ResourceInstanceObjectSrc{ 500 Status: states.ObjectReady, 501 AttrsJSON: []byte(`{"id":"a_id"}`), 502 }, 503 addrs.AbsProviderConfig{ 504 Provider: addrs.NewDefaultProvider("test"), 505 Module: addrs.RootModule, 506 }, 507 ) 508 root.SetResourceInstanceCurrent( 509 addrs.Resource{ 510 Mode: addrs.ManagedResourceMode, 511 Type: "test_object", 512 Name: "b", 513 }.Instance(addrs.NoKey), 514 &states.ResourceInstanceObjectSrc{ 515 Status: states.ObjectReady, 516 AttrsJSON: []byte(`{"id":"b_id","test_string":"a_id"}`), 517 Dependencies: []addrs.ConfigResource{ 518 { 519 Resource: addrs.Resource{ 520 Mode: addrs.ManagedResourceMode, 521 Type: "test_object", 522 Name: "a", 523 }, 524 Module: root.Addr.Module(), 525 }, 526 }, 527 }, 528 addrs.AbsProviderConfig{ 529 Provider: addrs.NewDefaultProvider("test"), 530 Module: addrs.RootModule, 531 }, 532 ) 533 534 b := &ApplyGraphBuilder{ 535 Config: testModule(t, "graph-builder-apply-orphan-update"), 536 Changes: changes, 537 Plugins: simpleMockPluginLibrary(), 538 State: state, 539 } 540 541 g, err := b.Build(addrs.RootModuleInstance) 542 if err != nil { 543 t.Fatalf("err: %s", err) 544 } 545 546 expected := strings.TrimSpace(` 547 test_object.a (destroy) 548 test_object.b 549 test_object.a (destroy) 550 `) 551 552 instanceGraph := filterInstances(g) 553 got := strings.TrimSpace(instanceGraph.String()) 554 555 if got != expected { 556 t.Fatalf("expected:\n%s\ngot:\n%s", expected, got) 557 } 558 } 559 560 // Ensure that an update resulting from the removal of a resource happens before 561 // a CBD resource is destroyed. 562 func TestApplyGraphBuilder_updateFromCBDOrphan(t *testing.T) { 563 schemas := simpleTestSchemas() 564 instanceSchema := schemas.Providers[addrs.NewDefaultProvider("test")].ResourceTypes["test_object"] 565 566 bBefore, _ := plans.NewDynamicValue( 567 cty.ObjectVal(map[string]cty.Value{ 568 "id": cty.StringVal("b_id"), 569 "test_string": cty.StringVal("a_id"), 570 }), instanceSchema.ImpliedType()) 571 bAfter, _ := plans.NewDynamicValue( 572 cty.ObjectVal(map[string]cty.Value{ 573 "id": cty.StringVal("b_id"), 574 "test_string": cty.StringVal("changed"), 575 }), instanceSchema.ImpliedType()) 576 577 changes := &plans.Changes{ 578 Resources: []*plans.ResourceInstanceChangeSrc{ 579 { 580 Addr: mustResourceInstanceAddr("test_object.a"), 581 ChangeSrc: plans.ChangeSrc{ 582 Action: plans.Delete, 583 }, 584 }, 585 { 586 Addr: mustResourceInstanceAddr("test_object.b"), 587 ChangeSrc: plans.ChangeSrc{ 588 Action: plans.Update, 589 Before: bBefore, 590 After: bAfter, 591 }, 592 }, 593 }, 594 } 595 596 state := states.NewState() 597 root := state.EnsureModule(addrs.RootModuleInstance) 598 root.SetResourceInstanceCurrent( 599 addrs.Resource{ 600 Mode: addrs.ManagedResourceMode, 601 Type: "test_object", 602 Name: "a", 603 }.Instance(addrs.NoKey), 604 &states.ResourceInstanceObjectSrc{ 605 Status: states.ObjectReady, 606 AttrsJSON: []byte(`{"id":"a_id"}`), 607 CreateBeforeDestroy: true, 608 }, 609 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 610 ) 611 root.SetResourceInstanceCurrent( 612 addrs.Resource{ 613 Mode: addrs.ManagedResourceMode, 614 Type: "test_object", 615 Name: "b", 616 }.Instance(addrs.NoKey), 617 &states.ResourceInstanceObjectSrc{ 618 Status: states.ObjectReady, 619 AttrsJSON: []byte(`{"id":"b_id","test_string":"a_id"}`), 620 Dependencies: []addrs.ConfigResource{ 621 { 622 Resource: addrs.Resource{ 623 Mode: addrs.ManagedResourceMode, 624 Type: "test_object", 625 Name: "a", 626 }, 627 Module: root.Addr.Module(), 628 }, 629 }, 630 }, 631 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`), 632 ) 633 634 b := &ApplyGraphBuilder{ 635 Config: testModule(t, "graph-builder-apply-orphan-update"), 636 Changes: changes, 637 Plugins: simpleMockPluginLibrary(), 638 State: state, 639 } 640 641 g, err := b.Build(addrs.RootModuleInstance) 642 if err != nil { 643 t.Fatalf("err: %s", err) 644 } 645 646 expected := strings.TrimSpace(` 647 test_object.a (destroy) 648 test_object.b 649 test_object.b 650 `) 651 652 instanceGraph := filterInstances(g) 653 got := strings.TrimSpace(instanceGraph.String()) 654 655 if got != expected { 656 t.Fatalf("expected:\n%s\ngot:\n%s", expected, got) 657 } 658 } 659 660 // The orphan clean up node should not be connected to a provider 661 func TestApplyGraphBuilder_orphanedWithProvider(t *testing.T) { 662 changes := &plans.Changes{ 663 Resources: []*plans.ResourceInstanceChangeSrc{ 664 { 665 Addr: mustResourceInstanceAddr("test_object.A"), 666 ChangeSrc: plans.ChangeSrc{ 667 Action: plans.Delete, 668 }, 669 }, 670 }, 671 } 672 673 state := states.NewState() 674 root := state.EnsureModule(addrs.RootModuleInstance) 675 root.SetResourceInstanceCurrent( 676 mustResourceInstanceAddr("test_object.A").Resource, 677 &states.ResourceInstanceObjectSrc{ 678 Status: states.ObjectReady, 679 AttrsJSON: []byte(`{"id":"A"}`), 680 }, 681 mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"].foo`), 682 ) 683 684 b := &ApplyGraphBuilder{ 685 Config: testModule(t, "graph-builder-orphan-alias"), 686 Changes: changes, 687 Plugins: simpleMockPluginLibrary(), 688 State: state, 689 } 690 691 g, err := b.Build(addrs.RootModuleInstance) 692 if err != nil { 693 t.Fatal(err) 694 } 695 696 // The cleanup node has no state or config of its own, so would create a 697 // default provider which we don't want. 698 testGraphNotContains(t, g, "provider.test") 699 } 700 701 const testApplyGraphBuilderStr = ` 702 meta.count-boundary (EachMode fixup) 703 module.child (close) 704 test_object.other 705 module.child (close) 706 module.child.test_object.other 707 module.child (expand) 708 module.child.test_object.create 709 module.child.test_object.create (expand) 710 module.child.test_object.create (expand) 711 module.child (expand) 712 provider["registry.terraform.io/hashicorp/test"] 713 module.child.test_object.other 714 module.child.test_object.create 715 module.child.test_object.other (expand) 716 module.child.test_object.other (expand) 717 module.child (expand) 718 provider["registry.terraform.io/hashicorp/test"] 719 provider["registry.terraform.io/hashicorp/test"] 720 provider["registry.terraform.io/hashicorp/test"] (close) 721 module.child.test_object.other 722 test_object.other 723 root 724 meta.count-boundary (EachMode fixup) 725 provider["registry.terraform.io/hashicorp/test"] (close) 726 test_object.create 727 test_object.create (expand) 728 test_object.create (expand) 729 provider["registry.terraform.io/hashicorp/test"] 730 test_object.other 731 test_object.create 732 test_object.other (expand) 733 test_object.other (expand) 734 provider["registry.terraform.io/hashicorp/test"] 735 ` 736 737 const testApplyGraphBuilderDestroyCountStr = ` 738 meta.count-boundary (EachMode fixup) 739 test_object.B 740 provider["registry.terraform.io/hashicorp/test"] 741 provider["registry.terraform.io/hashicorp/test"] (close) 742 test_object.B 743 root 744 meta.count-boundary (EachMode fixup) 745 provider["registry.terraform.io/hashicorp/test"] (close) 746 test_object.A (expand) 747 provider["registry.terraform.io/hashicorp/test"] 748 test_object.A[1] (destroy) 749 provider["registry.terraform.io/hashicorp/test"] 750 test_object.B 751 test_object.A (expand) 752 test_object.A[1] (destroy) 753 test_object.B (expand) 754 test_object.B (expand) 755 provider["registry.terraform.io/hashicorp/test"] 756 `