@@ -6,6 +6,7 @@ package stackruntime
66import (
77 "context"
88 "path"
9+ "path/filepath"
910 "strconv"
1011 "testing"
1112 "time"
@@ -21,6 +22,7 @@ import (
2122 "github.com/hashicorp/terraform/internal/providers"
2223 "github.com/hashicorp/terraform/internal/stacks/stackaddrs"
2324 "github.com/hashicorp/terraform/internal/stacks/stackplan"
25+ "github.com/hashicorp/terraform/internal/stacks/stackruntime/hooks"
2426 stacks_testing_provider "github.com/hashicorp/terraform/internal/stacks/stackruntime/testing"
2527 "github.com/hashicorp/terraform/internal/stacks/stackstate"
2628 "github.com/hashicorp/terraform/internal/states"
@@ -1595,6 +1597,139 @@ func TestApplyDestroy(t *testing.T) {
15951597 },
15961598 },
15971599 },
1600+ "destroy-with-follow-up" : {
1601+ path : filepath .Join ("with-single-input" , "valid" ),
1602+ cycles : []TestCycle {
1603+ {
1604+ planMode : plans .NormalMode , // create
1605+ planInputs : map [string ]cty.Value {
1606+ "id" : cty .StringVal ("self" ),
1607+ "input" : cty .StringVal ("self" ),
1608+ },
1609+ },
1610+ {
1611+ planMode : plans .DestroyMode , // destroy
1612+ planInputs : map [string ]cty.Value {
1613+ "id" : cty .StringVal ("self" ),
1614+ "input" : cty .StringVal ("self" ),
1615+ },
1616+ wantPlannedHooks : & ExpectedHooks {
1617+ ComponentExpanded : []* hooks.ComponentInstances {
1618+ {
1619+ ComponentAddr : mustAbsComponent ("component.self" ),
1620+ InstanceAddrs : []stackaddrs.AbsComponentInstance {mustAbsComponentInstance ("component.self" )},
1621+ },
1622+ },
1623+ PendingComponentInstancePlan : collections.NewSet [stackaddrs.AbsComponentInstance ](
1624+ mustAbsComponentInstance ("component.self" ),
1625+ ),
1626+ BeginComponentInstancePlan : collections.NewSet [stackaddrs.AbsComponentInstance ](
1627+ mustAbsComponentInstance ("component.self" ),
1628+ ),
1629+ EndComponentInstancePlan : collections.NewSet [stackaddrs.AbsComponentInstance ](
1630+ mustAbsComponentInstance ("component.self" ),
1631+ ),
1632+ ReportResourceInstanceStatus : []* hooks.ResourceInstanceStatusHookData {
1633+ {
1634+ Addr : mustAbsResourceInstanceObject ("component.self.testing_resource.data" ),
1635+ ProviderAddr : mustDefaultRootProvider ("testing" ).Provider ,
1636+ Status : hooks .ResourceInstancePlanning ,
1637+ },
1638+ {
1639+ Addr : mustAbsResourceInstanceObject ("component.self.testing_resource.data" ),
1640+ ProviderAddr : mustDefaultRootProvider ("testing" ).Provider ,
1641+ Status : hooks .ResourceInstancePlanned ,
1642+ },
1643+ },
1644+ ReportResourceInstancePlanned : []* hooks.ResourceInstanceChange {
1645+ {
1646+ Addr : mustAbsResourceInstanceObject ("component.self.testing_resource.data" ),
1647+ Change : & plans.ResourceInstanceChangeSrc {
1648+ Addr : mustAbsResourceInstance ("testing_resource.data" ),
1649+ PrevRunAddr : mustAbsResourceInstance ("testing_resource.data" ),
1650+ ProviderAddr : mustDefaultRootProvider ("testing" ),
1651+ ChangeSrc : plans.ChangeSrc {
1652+ Action : plans .Delete ,
1653+ Before : mustPlanDynamicValue (cty .ObjectVal (map [string ]cty.Value {
1654+ "id" : cty .StringVal ("self" ),
1655+ "value" : cty .StringVal ("self" ),
1656+ })),
1657+ After : mustPlanDynamicValue (cty .NullVal (cty .Object (map [string ]cty.Type {
1658+ "id" : cty .String ,
1659+ "value" : cty .String ,
1660+ }))),
1661+ },
1662+ },
1663+ },
1664+ },
1665+ ReportComponentInstancePlanned : []* hooks.ComponentInstanceChange {
1666+ {
1667+ Addr : mustAbsComponentInstance ("component.self" ),
1668+ Remove : 1 ,
1669+ },
1670+ },
1671+ },
1672+ wantAppliedHooks : & ExpectedHooks {
1673+ ComponentExpanded : []* hooks.ComponentInstances {
1674+ {
1675+ ComponentAddr : mustAbsComponent ("component.self" ),
1676+ InstanceAddrs : []stackaddrs.AbsComponentInstance {mustAbsComponentInstance ("component.self" )},
1677+ },
1678+ },
1679+ PendingComponentInstanceApply : collections.NewSet [stackaddrs.AbsComponentInstance ](
1680+ mustAbsComponentInstance ("component.self" ),
1681+ ),
1682+ BeginComponentInstanceApply : collections.NewSet [stackaddrs.AbsComponentInstance ](
1683+ mustAbsComponentInstance ("component.self" ),
1684+ ),
1685+ EndComponentInstanceApply : collections.NewSet [stackaddrs.AbsComponentInstance ](
1686+ mustAbsComponentInstance ("component.self" ),
1687+ ),
1688+ ReportResourceInstanceStatus : []* hooks.ResourceInstanceStatusHookData {
1689+ {
1690+ Addr : mustAbsResourceInstanceObject ("component.self.testing_resource.data" ),
1691+ ProviderAddr : mustDefaultRootProvider ("testing" ).Provider ,
1692+ Status : hooks .ResourceInstanceApplying ,
1693+ },
1694+ {
1695+ Addr : mustAbsResourceInstanceObject ("component.self.testing_resource.data" ),
1696+ ProviderAddr : mustDefaultRootProvider ("testing" ).Provider ,
1697+ Status : hooks .ResourceInstanceApplied ,
1698+ },
1699+ },
1700+ ReportComponentInstanceApplied : []* hooks.ComponentInstanceChange {
1701+ {
1702+ Addr : mustAbsComponentInstance ("component.self" ),
1703+ Remove : 1 ,
1704+ },
1705+ },
1706+ },
1707+ },
1708+ {
1709+ planMode : plans .DestroyMode , // should be empty destroy
1710+ planInputs : map [string ]cty.Value {
1711+ "id" : cty .StringVal ("self" ),
1712+ "input" : cty .StringVal ("self" ),
1713+ },
1714+ wantPlannedHooks : & ExpectedHooks {
1715+ ComponentExpanded : []* hooks.ComponentInstances {
1716+ {
1717+ ComponentAddr : mustAbsComponent ("component.self" ),
1718+ InstanceAddrs : []stackaddrs.AbsComponentInstance {mustAbsComponentInstance ("component.self" )},
1719+ },
1720+ },
1721+ },
1722+ wantAppliedHooks : & ExpectedHooks {
1723+ ComponentExpanded : []* hooks.ComponentInstances {
1724+ {
1725+ ComponentAddr : mustAbsComponent ("component.self" ),
1726+ InstanceAddrs : []stackaddrs.AbsComponentInstance {mustAbsComponentInstance ("component.self" )},
1727+ },
1728+ },
1729+ },
1730+ },
1731+ },
1732+ },
15981733 }
15991734 for name , tc := range tcs {
16001735 t .Run (name , func (t * testing.T ) {
0 commit comments