@@ -999,6 +999,193 @@ func TestApplyDestroy(t *testing.T) {
999
999
},
1000
1000
},
1001
1001
},
1002
+ "empty-destroy-with-data-source" : {
1003
+ path : path .Join ("with-data-source" , "dependent" ),
1004
+ cycles : []TestCycle {
1005
+ {
1006
+ planMode : plans .DestroyMode ,
1007
+ planInputs : map [string ]cty.Value {
1008
+ "id" : cty .StringVal ("foo" ),
1009
+ },
1010
+ // deliberately empty, as we expect no changes from an
1011
+ // empty state.
1012
+ wantAppliedChanges : []stackstate.AppliedChange {
1013
+ & stackstate.AppliedChangeComponentInstanceRemoved {
1014
+ ComponentAddr : mustAbsComponent ("component.data" ),
1015
+ ComponentInstanceAddr : mustAbsComponentInstance ("component.data" ),
1016
+ },
1017
+ & stackstate.AppliedChangeComponentInstanceRemoved {
1018
+ ComponentAddr : mustAbsComponent ("component.self" ),
1019
+ ComponentInstanceAddr : mustAbsComponentInstance ("component.self" ),
1020
+ },
1021
+ & stackstate.AppliedChangeInputVariable {
1022
+ Addr : mustStackInputVariable ("id" ),
1023
+ },
1024
+ },
1025
+ },
1026
+ },
1027
+ },
1028
+ "partial destroy recovery" : {
1029
+ path : "component-chain" ,
1030
+ description : "this test simulates a partial destroy recovery" ,
1031
+ state : stackstate .NewStateBuilder ().
1032
+ // we only have data for the first component, indicating that
1033
+ // the second and third components were destroyed but not the
1034
+ // first one for some reason
1035
+ AddComponentInstance (stackstate .NewComponentInstanceBuilder (mustAbsComponentInstance ("component.one" )).
1036
+ AddDependent (mustAbsComponent ("component.two" )).
1037
+ AddInputVariable ("id" , cty .StringVal ("one" )).
1038
+ AddInputVariable ("value" , cty .StringVal ("foo" )).
1039
+ AddOutputValue ("value" , cty .StringVal ("foo" ))).
1040
+ AddResourceInstance (stackstate .NewResourceInstanceBuilder ().
1041
+ SetAddr (mustAbsResourceInstanceObject ("component.one.testing_resource.data" )).
1042
+ SetProviderAddr (mustDefaultRootProvider ("testing" )).
1043
+ SetResourceInstanceObjectSrc (states.ResourceInstanceObjectSrc {
1044
+ AttrsJSON : mustMarshalJSONAttrs (map [string ]interface {}{
1045
+ "id" : "one" ,
1046
+ "value" : "foo" ,
1047
+ }),
1048
+ Status : states .ObjectReady ,
1049
+ })).
1050
+ AddInput ("value" , cty .StringVal ("foo" )).
1051
+ AddOutput ("value" , cty .StringVal ("foo" )).
1052
+ Build (),
1053
+ store : stacks_testing_provider .NewResourceStoreBuilder ().
1054
+ AddResource ("one" , cty .ObjectVal (map [string ]cty.Value {
1055
+ "id" : cty .StringVal ("one" ),
1056
+ "value" : cty .StringVal ("foo" ),
1057
+ })).
1058
+ Build (),
1059
+ cycles : []TestCycle {
1060
+ {
1061
+ planMode : plans .DestroyMode ,
1062
+ planInputs : map [string ]cty.Value {
1063
+ "value" : cty .StringVal ("foo" ),
1064
+ },
1065
+ wantPlannedChanges : []stackplan.PlannedChange {
1066
+ & stackplan.PlannedChangeApplyable {
1067
+ Applyable : true ,
1068
+ },
1069
+ & stackplan.PlannedChangeComponentInstance {
1070
+ Addr : mustAbsComponentInstance ("component.one" ),
1071
+ Action : plans .Delete ,
1072
+ Mode : plans .DestroyMode ,
1073
+ PlanComplete : true ,
1074
+ PlanApplyable : true ,
1075
+ PlannedInputValues : map [string ]plans.DynamicValue {
1076
+ "id" : mustPlanDynamicValueDynamicType (cty .StringVal ("one" )),
1077
+ "value" : mustPlanDynamicValueDynamicType (cty .StringVal ("foo" )),
1078
+ },
1079
+ PlannedInputValueMarks : map [string ][]cty.PathValueMarks {
1080
+ "id" : nil ,
1081
+ "value" : nil ,
1082
+ },
1083
+ PlannedOutputValues : map [string ]cty.Value {
1084
+ "value" : cty .StringVal ("foo" ),
1085
+ },
1086
+ PlannedCheckResults : & states.CheckResults {},
1087
+ PlanTimestamp : fakePlanTimestamp ,
1088
+ },
1089
+ & stackplan.PlannedChangeResourceInstancePlanned {
1090
+ ResourceInstanceObjectAddr : mustAbsResourceInstanceObject ("component.one.testing_resource.data" ),
1091
+ ChangeSrc : & plans.ResourceInstanceChangeSrc {
1092
+ Addr : mustAbsResourceInstance ("testing_resource.data" ),
1093
+ PrevRunAddr : mustAbsResourceInstance ("testing_resource.data" ),
1094
+ ProviderAddr : mustDefaultRootProvider ("testing" ),
1095
+ ChangeSrc : plans.ChangeSrc {
1096
+ Action : plans .Delete ,
1097
+ Before : mustPlanDynamicValue (cty .ObjectVal (map [string ]cty.Value {
1098
+ "id" : cty .StringVal ("one" ),
1099
+ "value" : cty .StringVal ("foo" ),
1100
+ })),
1101
+ After : mustPlanDynamicValue (cty .NullVal (cty .Object (map [string ]cty.Type {
1102
+ "id" : cty .String ,
1103
+ "value" : cty .String ,
1104
+ }))),
1105
+ },
1106
+ },
1107
+ PriorStateSrc : & states.ResourceInstanceObjectSrc {
1108
+ AttrsJSON : mustMarshalJSONAttrs (map [string ]interface {}{
1109
+ "id" : "one" ,
1110
+ "value" : "foo" ,
1111
+ }),
1112
+ Status : states .ObjectReady ,
1113
+ Dependencies : make ([]addrs.ConfigResource , 0 ),
1114
+ },
1115
+ ProviderConfigAddr : mustDefaultRootProvider ("testing" ),
1116
+ Schema : stacks_testing_provider .TestingResourceSchema ,
1117
+ },
1118
+ & stackplan.PlannedChangeComponentInstance {
1119
+ Addr : mustAbsComponentInstance ("component.three" ),
1120
+ Action : plans .Delete ,
1121
+ Mode : plans .DestroyMode ,
1122
+ PlanComplete : true ,
1123
+ PlanApplyable : true ,
1124
+ RequiredComponents : collections .NewSet (mustAbsComponent ("component.two" )),
1125
+ PlannedOutputValues : map [string ]cty.Value {
1126
+ "value" : cty .DynamicVal ,
1127
+ },
1128
+ PlanTimestamp : fakePlanTimestamp ,
1129
+ },
1130
+ & stackplan.PlannedChangeComponentInstance {
1131
+ Addr : mustAbsComponentInstance ("component.two" ),
1132
+ Action : plans .Delete ,
1133
+ Mode : plans .DestroyMode ,
1134
+ PlanComplete : true ,
1135
+ PlanApplyable : true ,
1136
+ RequiredComponents : collections .NewSet (mustAbsComponent ("component.one" )),
1137
+ PlannedOutputValues : map [string ]cty.Value {
1138
+ "value" : cty .DynamicVal ,
1139
+ },
1140
+ PlanTimestamp : fakePlanTimestamp ,
1141
+ },
1142
+ & stackplan.PlannedChangeHeader {
1143
+ TerraformVersion : version .SemVer ,
1144
+ },
1145
+ & stackplan.PlannedChangeOutputValue {
1146
+ Addr : mustStackOutputValue ("value" ),
1147
+ Action : plans .Delete ,
1148
+ Before : cty .StringVal ("foo" ),
1149
+ After : cty .NullVal (cty .String ),
1150
+ },
1151
+ & stackplan.PlannedChangePlannedTimestamp {
1152
+ PlannedTimestamp : fakePlanTimestamp ,
1153
+ },
1154
+ & stackplan.PlannedChangeRootInputValue {
1155
+ Addr : mustStackInputVariable ("value" ),
1156
+ Action : plans .NoOp ,
1157
+ Before : cty .StringVal ("foo" ),
1158
+ After : cty .StringVal ("foo" ),
1159
+ DeleteOnApply : true ,
1160
+ },
1161
+ },
1162
+ wantAppliedChanges : []stackstate.AppliedChange {
1163
+ & stackstate.AppliedChangeComponentInstanceRemoved {
1164
+ ComponentAddr : mustAbsComponent ("component.one" ),
1165
+ ComponentInstanceAddr : mustAbsComponentInstance ("component.one" ),
1166
+ },
1167
+ & stackstate.AppliedChangeResourceInstanceObject {
1168
+ ResourceInstanceObjectAddr : mustAbsResourceInstanceObject ("component.one.testing_resource.data" ),
1169
+ ProviderConfigAddr : mustDefaultRootProvider ("testing" ),
1170
+ },
1171
+ & stackstate.AppliedChangeComponentInstanceRemoved {
1172
+ ComponentAddr : mustAbsComponent ("component.three" ),
1173
+ ComponentInstanceAddr : mustAbsComponentInstance ("component.three" ),
1174
+ },
1175
+ & stackstate.AppliedChangeComponentInstanceRemoved {
1176
+ ComponentAddr : mustAbsComponent ("component.two" ),
1177
+ ComponentInstanceAddr : mustAbsComponentInstance ("component.two" ),
1178
+ },
1179
+ & stackstate.AppliedChangeOutputValue {
1180
+ Addr : mustStackOutputValue ("value" ),
1181
+ },
1182
+ & stackstate.AppliedChangeInputVariable {
1183
+ Addr : mustStackInputVariable ("value" ),
1184
+ },
1185
+ },
1186
+ },
1187
+ },
1188
+ },
1002
1189
}
1003
1190
for name , tc := range tcs {
1004
1191
t .Run (name , func (t * testing.T ) {
0 commit comments